CC链总结
字数 1992 2025-08-20 18:17:59

Apache Commons Collections 反序列化漏洞(CC链)深度分析

1. CC链概述

CC链是指利用Apache Commons Collections库中的某些特性构造的反序列化利用链,主要影响Commons Collections 3.1-3.2.1版本,在特定JDK版本(8u71之前)下可导致远程代码执行。

1.1 CC链基本结构

CC链可分为两大部分:

  1. 起点部分:依赖commons-collection的入口点
  2. commons-collection内部链
    • 中间点:LazyMap、TransformedMap等
    • 利用点(敏感点):Transformer接口实现类

依赖关系可以是直接的,也可以是间接的(通过父类型依赖)。

2. 利用条件与限制

2.1 主要限制条件

  1. JDK版本限制:需要在8u71之前
  2. Commons Collections版本限制:3.1-3.2.1

2.2 限制原因分析

导致这两个限制的主要原因是:

  • AnnotationInvocationHandler的变化(导致JDK版本限制)
  • InvokerTransformer的反序列化问题(导致Commons Collections版本限制)

3. 典型利用链分析

3.1 CC0利用链

利用条件

  • JDK版本在8u71之前
  • Commons Collections 3.1-3.2.1

调用链

ObjectInputStream.readObject()
→ AnnotationInvocationHandler.readObject()
→ TransformedMap.entrySet().iterator()
→ AbstractInputCheckedMapDecorator.MapEntry.setValue()
→ TransformedMap.checkSetValue()
→ ChainedTransformer.transform()

关键点分析

  1. AnnotationInvocationHandler.readObject()直接调用memberValues.entrySet().iterator()
  2. defaultReadObject()将反序列化数据直接赋值给当前对象字段
  3. memberValuesTransformedMap(继承自AbstractInputCheckedMapDecorator)
  4. var5AbstractInputCheckedMapDecorator.MapEntry,因此能触发后续调用

3.2 CC1利用链

利用条件

  • JDK版本在8u71之前
  • Commons Collections 3.1-3.2.1

调用链

ObjectInputStream.readObject()
→ AnnotationInvocationHandler.readObject()
→ Map(Proxy).entrySet()
→ AnnotationInvocationHandler.invoke()
→ LazyMap.get()
→ ChainedTransformer.transform()
→ ConstantTransformer.transform()

关键点分析

  1. 使用动态代理机制,memberValuesProxy(Map)
  2. 调用Map(Proxy).entrySet()时会触发innerAnnotationInvocationHandler.invoke(...)
  3. memberValues是被代理的LazyMap,最终调用LazyMap.get()
  4. CC3与CC1本质相同,只是最终利用的Transformer不同

4. JDK 8u71+的防御机制

4.1 对CC0的防御

在JDK 8u71+中(以jdk_1.8_422为例):

  1. 不再调用AbstractInputCheckedMapDecorator.MapEntry.setValue()
  2. 改为调用LazyMap.getKey()LazyMap.getValue()
  3. 将键值对存入LinkedHashMap,破坏原有调用链

4.2 对CC1的防御

  1. 反序列化是递归的
  2. 执行outerAnnotationInvocationHandlers.readFileds()时:
    • 底层调用innerAnnotationInvocationHandler.readObject()
    • fields.get("memberValues",null)返回LazyMap
    • UnsageAccessor.setMemberValues(this,mv)memberValues改为LinkedHashMap
  3. 最终调用LinkedHashMap.get()而非LazyMap.get(),阻断调用链

5. Commons Collections版本限制分析

InvokerTransformer在Commons Collections 3.2.2+版本中无法直接反序列化,这是导致版本限制的主要原因。

6. 总结

CC链反序列化漏洞的核心在于:

  1. 利用AnnotationInvocationHandler作为入口点
  2. 通过TransformedMapLazyMap作为中间桥梁
  3. 最终调用Transformer实现类执行任意代码
  4. JDK 8u71+通过修改AnnotationInvocationHandler的行为和数据结构阻断攻击链
  5. Commons Collections 3.2.2+通过限制InvokerTransformer的反序列化能力增强安全性

理解这些关键点对于分析Java反序列化漏洞和安全防护具有重要意义。

Apache Commons Collections 反序列化漏洞(CC链)深度分析 1. CC链概述 CC链是指利用Apache Commons Collections库中的某些特性构造的反序列化利用链,主要影响Commons Collections 3.1-3.2.1版本,在特定JDK版本(8u71之前)下可导致远程代码执行。 1.1 CC链基本结构 CC链可分为两大部分: 起点部分 :依赖commons-collection的入口点 commons-collection内部链 : 中间点:LazyMap、TransformedMap等 利用点(敏感点):Transformer接口实现类 依赖关系可以是直接的,也可以是间接的(通过父类型依赖)。 2. 利用条件与限制 2.1 主要限制条件 JDK版本限制 :需要在8u71之前 Commons Collections版本限制 :3.1-3.2.1 2.2 限制原因分析 导致这两个限制的主要原因是: AnnotationInvocationHandler 的变化(导致JDK版本限制) InvokerTransformer 的反序列化问题(导致Commons Collections版本限制) 3. 典型利用链分析 3.1 CC0利用链 利用条件 : JDK版本在8u71之前 Commons Collections 3.1-3.2.1 调用链 : 关键点分析 : AnnotationInvocationHandler.readObject() 直接调用 memberValues.entrySet().iterator() defaultReadObject() 将反序列化数据直接赋值给当前对象字段 memberValues 是 TransformedMap (继承自 AbstractInputCheckedMapDecorator ) var5 是 AbstractInputCheckedMapDecorator.MapEntry ,因此能触发后续调用 3.2 CC1利用链 利用条件 : JDK版本在8u71之前 Commons Collections 3.1-3.2.1 调用链 : 关键点分析 : 使用动态代理机制, memberValues 是 Proxy(Map) 调用 Map(Proxy).entrySet() 时会触发 innerAnnotationInvocationHandler.invoke(...) memberValues 是被代理的 LazyMap ,最终调用 LazyMap.get() CC3与CC1本质相同,只是最终利用的 Transformer 不同 4. JDK 8u71+的防御机制 4.1 对CC0的防御 在JDK 8u71+中(以jdk_ 1.8_ 422为例): 不再调用 AbstractInputCheckedMapDecorator.MapEntry.setValue() 改为调用 LazyMap.getKey() 和 LazyMap.getValue() 将键值对存入 LinkedHashMap ,破坏原有调用链 4.2 对CC1的防御 反序列化是递归的 执行 outerAnnotationInvocationHandler 的 s.readFileds() 时: 底层调用 innerAnnotationInvocationHandler.readObject() fields.get("memberValues",null) 返回 LazyMap UnsageAccessor.setMemberValues(this,mv) 将 memberValues 改为 LinkedHashMap 最终调用 LinkedHashMap.get() 而非 LazyMap.get() ,阻断调用链 5. Commons Collections版本限制分析 InvokerTransformer 在Commons Collections 3.2.2+版本中无法直接反序列化,这是导致版本限制的主要原因。 6. 总结 CC链反序列化漏洞的核心在于: 利用 AnnotationInvocationHandler 作为入口点 通过 TransformedMap 或 LazyMap 作为中间桥梁 最终调用 Transformer 实现类执行任意代码 JDK 8u71+通过修改 AnnotationInvocationHandler 的行为和数据结构阻断攻击链 Commons Collections 3.2.2+通过限制 InvokerTransformer 的反序列化能力增强安全性 理解这些关键点对于分析Java反序列化漏洞和安全防护具有重要意义。