freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

Z3专栏 | CommonsCollections4、5、7分析
z3 2021-12-16 20:08:39 174494
所属地 辽宁省

介绍

已经学了5条链了,感觉后面越学越简单了,都是前面的一些触发点的新组合。前面几篇细致的分析了每一个点,总结出规律,像推导定理一样。从本篇开始,都是对之前总结出的规律、定理的应用,原理不去细致分析了,如果觉得本篇讲的太粗略,看不懂的,一定是没看前面几篇。

CC4分析

代码如下

第一句创建templates就不说了
第二句,创建constant对象,调用transform方法就返回String.class,倒数第四行又改为了TrAXFilter.class
第五句,创建instantiate对象,调用transform方法会使用"foo"当参数,实例化传入的对象
下两行获取了instantiate对象的,用来实例化对象的参数类型和参数值的对象,在倒数2、3行,把类型和值改为了tempates
下一行创建ChainedTransformer类型的chain对象,把constant和串联起来

至此,以上操作构建了一个Transformer链,
第一个Transformer返回TrAXFilter.class,第二个返回new TrAXFilter(templates)
CC3学过了,new TrAXFilter(templates)会触发命令执行

紧接着创建了优先队列,这个在CC2学过,优先队列反序列化时会触发Transformer

ok,至此CC4就分析完了,没有新知识点,也不用调试,一看就懂,越学越简单了

CC5分析

代码如下

创建了transformerChain和transformers,第一个里面是1
再看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}, execArgs), 
    new ConstantTransformer(1)
};

是一个通过Runtime命令执行链
再看倒数第二行,把transformerChain的iTransformers(就是1)改为了transformers
所以transformerChain就是用于命令执行的Transformer链

再看下三句,还是老套路,创建lazyMap对象,使用了transformerChain链,然后用lazyMap创建TiedMapEntry类型对象entry
在CC6学过,这样一条链,当对entry对象计算hash时就会触发命令执行

下面创建了BadAttributeValueExpException对象val
然后下三句,通过反射,将val的成员变量val修改为了entry

ok,这条链就结束了
猜测BadAttributeValueExpException对象的readObject方法对成员变量val计算了hash

看一下代码,如图,valObj就是从序列化数据中读出的entry对象
没计算entry的hash,而是调用了entry的toString方法

而entry的toString方法和计算hash一样,都会调用getValue,然后调用LazyMap的get,导致命令执行

ok,至此CC5也结束了

CC7

代码如图

构造transformerChain链就不讲了,用的是Runtime命令执行
然后创建了两个LazyMap,lazyMap1和lazyMap2,分别放了一条数据
创建一个Hashtable,把两个HashMap放进去,
lazyMap2移除数据"yy"(刚才lazyMap只放了"zZ",应该没有"yy"键啊?)

Hashtable之前没遇到过,看一下put,没发现调用LazyMap的get


看起来和HashMap有点像
网上查了下,和HashMap的区别:HashTable 是线程安全 Collection,HashMap 不是线程安全的

下面就调试下,断点加在方法LazyMap的get上

调用栈如图
Hashtable的readObject -> readHashtable -> reconstitutionPut -> e.key.equals(key) -> AbstractMapDector的equal - > AbstractMap的equal -> get(key)
Hashtable反序列化时调用readHashtable读取数据
在readHashtable中读取到数据通过reconstitutionPut方法添加键值对到table
在添加新键值对时,会遍历table,检查key是否在table中存在,这时调用了equal方法
因为之前已经添加过一个lazyMap1了,所以添加lazyMap2时会调用lazyMap1.equals(lazyMap2)

lazyMap类没有equals,但它的父类AbstractMapDecorator有

这里的this.map是创建LazyMap时用的HashMap
所以equals方法在HashMap
HashMap也没equalse,但它继承了AbstractMap

终于在AbstractMap中找到了equals方法
如图,lazyMap1.equals(lazyMap2),则这里o就是lazyMap2,在第二个红框调用了get方法,导致了命令执行

总结一下

  1. Hashtable反序列化时会,先创建空table,然后添加键值对,添加新键时要用每个键的equals比较新添加的键

  2. 而LazyMap的equals方法会调用传入Map的get方法,
    所以综合以上两点,构造出CC7利用链

疑问

为什么要执行

lazyMap2.remove("yy");

经过如下代码测试,反序列化失败

调试时发现,执行下面这句话导致lazyMap2增加了新元素"yy":"yy"

hashtable.put(lazyMap2, 2);

为什么呢?
看下put方法,如图
调用了entry.key.equals(key),这里的entry是lazyMap1

上面分析过,lazyMap1.equals(lazyMap2)会导致lazyMap2.get(key),这里的key是lazyMap1的key
如图

而lazyMap2的Transformer是空的ChainedTransformer,所以会生成和key一样的value,所以在lazyMap2生成了键值对"yy":"yy"

那为什么要移除新增加的元素?不移除也会对这俩lazyMap做equals呀
调试发现,如图
AbstractMap的equals比较两个map时会先比较大小,不相等直接返回false,就不会执行第二个红框了

总结

CC5:
TiedMapEntry不仅hashCode方法,而且toString方法也可以触发LazyMap的get,导致命令执行
BadAttributeValueExpException对象在反序列化时会调用val的toString,所以可以把val改为TiedMapEntry类型对象

CC7:

1、LazyMap的equals方法会调用传入Map的get方法(两个map大小要相等),所以让lazyMap1.equals(lazyMap2)就会造成命令执行

2、Hashtable反序列化时,新建空table,然后把数据通过reconstitutionPut方法放进去,这个过程会使用table内每个元素的key和新元素的key作比较。
所以当两个key都是lazyMap时,就会发生1中的情况,导致命令执行

# java漏洞 # java # java反序列化 # Java代码审计 # JAVA安全
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 z3 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
java代码审计学习
z3 LV.4
  • 27 文章数
  • 89 关注者
Java 反序列化回显链研究:漏洞检测工程化
2022-04-01
Z3专栏 | CommonsCollections3分析
2022-03-19
MeterSphere未授权导致的rce漏洞分析、复现、exp编写
2022-02-11
文章目录