内容提要
本文分析Java Commons-Collections组件中的反序列化漏洞,重点讲解CC3和CC4两条利用链。CC3通过BadAttributeValueExpException触发LazyMap链,CC4利用PriorityQueue和TemplatesImpl执行命令。文章详细演示了漏洞触发流程、成因及利用代码,强调反射机制在漏洞中的关键作用,并总结构造Gadget链的要点。
延伸解读
反射机制是漏洞利用的核心
文章反复强调,Commons-Collections反序列化漏洞的利用离不开Java反射机制。无论是CC3链中通过InvokerTransformer动态调用Runtime.exec,还是CC4链中利用反射修改TemplatesImpl的私有字段,反射都提供了在运行时动态操作类和对象的能力。理解反射的调用原理,是分析这类Gadget链的关键。
入口类选择与触发条件
构造利用链需要找到一个满足反序列化条件的入口类,且该类在readObject过程中能间接调用到危险方法。CC3选用JDK自带的BadAttributeValueExpException,通过反射修改其私有字段val来触发;CC4则利用PriorityQueue的readObject在堆化时调用比较器。入口类的选择决定了利用链的稳定性和适用场景。
版本差异与利用链变化
文章指出Commons-Collections 3和4的利用方式不同,Gadget链也不同。CC3利用LazyMap和TiedMapEntry,而CC4则结合PriorityQueue和TemplatesImpl。这种差异源于组件内部实现的变化,也提醒我们在实际漏洞分析中,必须针对具体版本进行调试,不能盲目套用已知链。
Q&A
Commons-Collections反序列化漏洞是什么?
Commons-Collections是Java中常用的集合处理库,其反序列化漏洞是指攻击者通过构造恶意序列化数据,在目标系统反序列化时触发任意代码执行。该漏洞是Java生态中第一个被广泛利用的反序列化漏洞,主要影响版本3和4。
CC3利用链的完整触发流程是怎样的?
CC3利用链的触发流程为:ObjectInputStream.readObject() -> BadAttributeValueExpException.readObject() -> TiedMapEntry.toString() -> LazyMap.get() -> ChainedTransformer.transform() -> ConstantTransformer.transform() -> InvokerTransformer.transform() -> Method.invoke() -> Class.getMethod() -> InvokerTransformer.transform() -> Method.invoke() -> Runtime.getRuntime() -> InvokerTransformer.transform() -> Method.invoke() -> Runtime.exec()。
CC3漏洞中如何利用BadAttributeValueExpException触发反序列化?
BadAttributeValueExpException是JDK自带的类,实现了Serializable接口,其readObject方法会调用val属性的toString方法。攻击者通过反射将val属性设置为TiedMapEntry对象,该对象的toString方法会调用LazyMap.get(),从而触发恶意Transformer链执行命令。
CC4利用链的完整触发流程是怎样的?
CC4利用链的触发流程为:ObjectInputStream.readObject() -> PriorityQueue.readObject() -> heapify() -> siftDown() -> siftDownUsingComparator() -> TransformingComparator.compare() -> InvokerTransformer.transform() -> Method.invoke() -> TemplatesImpl.newTransformer() -> getTransletInstance() -> defineTransletClasses() -> Runtime.exec()。
CC4中如何通过TemplatesImpl执行命令?
CC4利用链中,通过修改字节码生成恶意类,该类继承AbstractTranslet,并在静态初始化中插入执行命令的代码。然后通过反射将恶意字节码设置到TemplatesImpl的_bytecodes字段,当调用newTransformer()时,会加载并实例化该类,触发静态初始化中的命令执行。
CC3和CC4利用链的主要区别是什么?
CC3和CC4的主要区别在于入口点和触发方式:CC3使用BadAttributeValueExpException作为入口,通过LazyMap和TiedMapEntry触发;CC4使用PriorityQueue作为入口,通过TransformingComparator和TemplatesImpl触发。此外,CC4涉及字节码修改,而CC3主要依赖反射调用Runtime。
构造Gadget链的关键要点有哪些?
构造Gadget链的关键要点包括:需要一个JDK自带的实现Serializable接口的类作为入口,其readObject方法中要有可被利用的调用点;必须依赖Java反射机制来动态调用方法;需要精心设计Transformer链或利用TemplatesImpl等类来执行最终命令。