CVE-2015-7501: Apache Commons Collections 反序列化漏洞深度分析
0x00 漏洞背景与详情
- CVE ID: CVE-2015-7501
- 受影响组件: Apache Commons Collections 3.x (<= 3.2.1)
- 漏洞类型: 反序列化漏洞 (CWE-502)
- 危险等级: 极高危 (Critical)
- 影响范围: 大量使用 ACC 库的 Java 应用,包括 WebLogic, JBoss, Jenkins, WebSphere 等。
CVE-2015-7501 是 Java 安全领域极具里程碑意义的漏洞,它揭示了 Java 原生反序列化机制与通用第三方组件库结合所产生的巨大杀伤力。该漏洞的核心在于 ACC 库中的 InvokerTransformer 类允许在反序列化期间执行任意的反射调用,从而导致远程代码执行 (RCE)。
0x01 漏洞原理分析
漏洞的核心在于 Apache Commons Collections (ACC) 库提供的 Transformer 接口及其实现类 InvokerTransformer。
- 危险的
InvokerTransformer: 该类的transform(Object input)方法会根据初始化时传入的methodName、parameterTypes和arguments,在传入的input对象上执行 Java 反射调用。 - 链条构建 (Gadget Chain):
攻击者利用
ChainedTransformer将多个InvokerTransformer串联起来,形成一个可以执行任意代码的链条。通常最终目标是反射调用java.lang.Runtime.getRuntime().exec()。 - 自动触发机制:
为了在反序列化时自动触发
transform调用,攻击者通常使用TransformedMap或LazyMap装饰一个 Map,再配合 JDK 自带的AnnotationInvocationHandler。当反序列化AnnotationInvocationHandler时,它的readObject方法会遍历 Map,从而自动触发transform逻辑。
0x02 POC (以 CommonsCollections1 为例)
以下是基于 AnnotationInvocationHandler + LazyMap 构造反序列化链的经典伪代码逻辑:
0x03 典型利用案例
由于 Apache Commons Collections 被极其广泛地引用,该漏洞横扫了当时的 Java 中间件:
- JBoss RCE: JBoss 的
invoker/JMXInvokerServlet接口直接接收序列化对象,攻击者通过发送精心构造的 ACC 链字节流即可获取服务器权限。 - WebLogic RCE: WebLogic 的 T3 协议默认传输序列化对象,在未打补丁前,通过 T3 发送 ACC payload 是最经典的内网渗透手段。
- Jenkins RCE: Jenkins 的 CLI 接口曾通过反序列化进行通信,导致其也受此漏洞影响。
0x04 高级利用姿势
在实战中,仅仅执行 touch 或反弹 Shell 往往不够,红队通常会使用以下高级利用姿势:
1. 内存马注入 (Memory WebShell)
通过反序列化链执行 Java 代码,动态向当前的 Web 容器(如 Tomcat)注入无文件落地的 Filter、Servlet 或 Listener 内存马。
- 利用原理:利用
InvokerTransformer链或更复杂的TemplatesImpl链,获取当前上下文的StandardContext对象,调用其addFilterDef和addFilterMap方法,将恶意字节码直接注入内存。 - 优势:无文件残留,重启即消失,能有效规避文件完整性监控 (FIM) 和传统的杀毒软件。
2. 命令执行回显 (Echo Technique)
默认情况下,Runtime.exec() 执行命令没有回显。高级利用会通过以下方式获取结果:
- 异常回显:将命令执行结果包装成异常消息抛出,通过 HTTP 500 页面获取回显。
- Response 对象回显:通过反射遍历当前线程或上下文,获取当前 HTTP 请求的
HttpServletResponse对象,将命令执行结果直接写入输出流。 - OOB (带外数据):对于不通外网的内网环境,通过
curl或ping将数据拼接到 DNS 请求中带外传出 (DNSLog)。
3. 反序列化混淆与 WAF 绕过
- 多链切换:如果
CommonsCollections1链被 WAF 拦截,可以尝试CommonsCollections3(利用TemplatesImpl加载字节码) 或CommonsCollections6(利用TiedMapEntry触发)。 - 二次反序列化:利用
java.security.SignedObject等类对 Payload 进行二次封装,绕过 WAF 对原生类名特征的浅层黑名单检测。
0x05 应急排查与日志痕迹分析
1. 流量特征分析
- 魔数识别:Java 序列化数据以十六进制
AC ED 00 05开头,Base64 编码后通常表现为rO0AB。 - 关键字检索:在 HTTP 流量(POST Body 或特定的 Cookie/Header)中搜索敏感类名,如
InvokerTransformer,ChainedTransformer,LazyMap,AnnotationInvocationHandler。
2. 日志审计
- Web 日志:检查是否存在大量产生 500 状态码的请求,特别是请求体体积庞大且包含乱码二进制数据的情况。
- JVM 堆栈日志:如果应用崩溃或报错,检查
catalina.out等日志。若堆栈中出现readObject并在调用栈上方看到InvokerTransformer.transform,则是绝对的攻击铁证。