CC 链的变体繁多,但万变不离其宗,无非是 Source、Gadget 和 Sink 的排列组合。
0x01 CC链各链的流程分析
1 2 3 4 5 6 7
| ConstantTransformer类发transformer方法传入任意东西,都会返回iConstant,类似一个常量,是Object类型,是所有类的父类。
private final Object iConstant; public ConstantTransformer(Object constantToReturn) { super(); iConstant = constantToReturn; }
|

1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 1、iTransformers是一个Transformer数组,遍历遍历到每个Transformer按顺序调用每个 Transformer的 transform方法,这样外部触发一次transform方法,就可以同时调用多个Transformer,那么就不用写多个InvokerTransformer.transform方法了
private final Transformer[] iTransformers; public ChainedTransformer(Transformer[] transformers) { super(); iTransformers = transformers; }
public Object transform(Object object) { for (int i = 0; i < iTransformers.length; i++) { object = iTransformers[i].transform(object); } return object; }
|

1.3CC1-CC7链调用逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| C1(TransformedMap链): runtime.exec() InvokerTransformer#transform TransformedMap#checkSetValue valueTransformer.transform AbstractInputCheckedMapDecorator.MapEntry#setValue parent.checkSetValue AnnotationInvocationHandler#readObject emberValue.setValue CC1(LazyMap链): runtime.exec() InvokeTransformer#transform LazyMap#get factory.transform() ChainedTransformer.transform() ConstantTransformer.transform() AnnotationInvocationHandler#invoke memberValues.get() AnnotationInvocationHandler#readObject memberValues.entrySet()
CC2: runtime.exec() InvokerTransformer.transform() TransformingComparator.compare() this.transformer.transform() PriorityQueue.siftDownUsingComparator() comparator.compare() PriorityQueue.siftDown() → siftDownUsingComparator() PriorityQueue.heapify() siftDown() PriorityQueue.readObject() heapify() CC3: TemplatesImpl.newTransformer() TrAXFilter构造调用templates.newTransformer() InstantiateTransformer.transform(TrAXFilter.class) con.newInstance() LazyMap.get() factory.transform() TiedMapEntry.getValue() map.get() TiedMapEntry.hashCode() HashMap.readObject() putVal(hash())
CC4: TemplatesImpl.newTransformer() TrAXFilter构造调用templates.newTransformer() InstantiateTransformer.transform()实例化TrAXFilter ChainedTransformer.transform() TransformingComparator.compare()内部调用transformer.transform() comparator.compare() TransformingComparator.compare() PriorityQueue.siftDownUsingComparator() comparator.compare() PriorityQueue.siftDown() → siftDownUsingComparator() PriorityQueue.heapify() siftDown() PriorityQueue.readObject() heapify() CC5: runtime.exec() InvokeTransformer#transform LazyMap.get() ChainedTransformer.transform() ConstantTransformer.transform() TiedMapEntry.getValue() TiedMapEntry.toString() getValue() BadAttributeValueExpException.readObject() val.toString() CC6: runtime.exec() InvokerTransformer#transform LazyMap#get ChainedTransformer.transform() ConstantTransformer.transform() TiedMapEntry#getValue TiedMapEntry#hashCode HashMap#hash HashMap#readObject CC7: runtime.exec() InvokeTransformer#transform LazyMap.get() → factory.transform() AbstractMap.equals() m.get() Hashtable.reconstitutionPut() key.equals() Hashtable.readObject reconstitutionPut()
|

0x02 链对比分析表
| 链 |
核心类 |
环境要求 |
特点 |
| CC1 |
InvokerTransformer, AnnotationInvocationHandler, LazyMap |
Commons Collections <= 3.2.1, JDK <= 8u65 |
定义了反序列化漏洞,通过找到尾部,寻找链子,在找到入口点,最总执行而已代码。 |
| CC2 |
TemplatesImpl,InvokerTransformer,TransformingComparator,PriorityQueue |
Commons Collections <= 3.2.1, <8u252 |
使用字节码加载的runtime类 |
| CC3 |
HashMap,TrAXFilter,InvokerTransformer,TemplatesImpl |
Commons Collections <= 3.2.1,Java版本不收限制 |
绕过了InvokerTransformer类的限制。 |
| CC4 |
TemplatesImpl,InvokerTransformer,TransformingComparator,PriorityQueue |
Commons-Collections 4.0,Java版本不收限制 |
结合了CC2和CC3。 |
| CC5 |
InvokeTransformer,LazyMap,TiedMapEntry,BadAttributeValueExpException |
Commons Collections <= 3.2.1, JDK <= 8u65 |
入口类使用了BadAttributeValueExpException,没使用AnnotationInvocationHandler |
| CC6 |
HashMap,TiedMapEntry,LazyMap,InvokerTransformer |
Commons Collections <= 3.2.1,Java版本不收限制 |
入口类HashMap,兼容性最强,无版本限制 |
| CC7 |
Hashtable,AbstractMap,LazyMap,InvokeTransformer |
Commons Collections <= 3.2.1,Java版本不收限制 |
入口类使用Hashtable |
后续衍生出来的其他链其他都是从CC1-CC7互相拼接而来,比如CC11,是CC2 + CC6 的结合体,入口使用了CC6,尾部使用了类加载的方式加载Runtime类
1 2 3 4 5 6 7 8
| -> HashMap.readObject() -> HashMap.putVal(hash(key), key, value, ...) -> tiedMapEntry.hashCode() -> tiedMapEntry.getValue() -> lazyMap.get(templates) -> factory.transform(templates) // factory现在是invokerTransformer -> InvokerTransformer.transform(templates) -> templates.newTransformer()
|
0x03 防御与修复视角
针对CC链的直接修复措施:
1.升级CC链版本,
升级到 3.2.2 或更高版本(3.x系列)。
升级到 4.1 或更高版本(4.x系列)。
这些安全版本在 InvokerTransformer、InstantiateTransformer等关键类的 readObject方法中增加了安全校验,比如3X系列除非开发者手动设置系统属性,否则反序列化到危险类就直接抛出异常,4.1版直接移除了functor包下不安全类(如 InvokerTransformer、InstantiateTransformer)对 Serializable接口的实现,反序列化都不行了。
2.升级JDK:
虽然CC链中部分利用(如CC6、CC7)对JDK版本不敏感,但高版本JDK(特别是Java 9+)引入的模块化系统可以限制对内部API(如 com.sun.org.apache.xalan.internal...TemplatesImpl)的访问,增加了利用难度。