CommonsCollections6


触发POC

利用IDEA创建一个maven项目,导入依赖

利用ysoserial生成payload:

得到

这里用的jdk1.8.0_121

触发Poc

 

分析利用链

Step 0

入口点是java.util.HashSetreadObject()中的map.put(e, PRESENT);

326行到328行,这里可以控制mapnew HashMap()

且333行的e可控 (这里的readObject()就是再从序列化数据中取出一个Object,类似于readInt(),readFloat()),进入map.put()

 

Step 1

跟入HashMap()put()

继续跟入hash()

这里key可控,需要找一个hashCode()可利用的点

 

Step 2

还是CC5中提到的org.apache.commons.collections.keyvalue.TiedMapEntry

其中有hashCode()方法,且其中执行了getValue(),进入getValue()后又回到了之前利用get()方法的链

 

构造EXP

Step 0

照抄CC1前半段

值得注意的是,这里要先构造一个占位的fakeTransformers

作用是避免在生成exp的过程中就直接执行命令(而且如果不加这个fakeTranformers,我在本地执行POC.java时会有问题,不能成功序列化正确的内容)

EXP part 1:

 

Step 1

要执行hashCode()也就是要在HashMap中执行public V put(K key, V value)且传入的key需要为TiedMapEntry

EXP part 2:

 

Step 2

最后就是要在HashSet中执行map.put(e, PRESENT);

map需要为HashMape需要为tiedMapEntry,才能执行到TiedMapEntry.hashcode()

根据HashSet.add()

tiedMapEntry绑定到HashSet,这样在反序列化的时候map.put(e, PRESENT)中的e就是tiedMapEntry,构造

运行后无报错

但是将hashSet序列化之后再用Poc.java反序列化发现无法命令执行

是哪里出了问题?下断点看看

一路跟到了LazyMap.get()

再往下执行发现直接跳到了else分支,因为super.map.containsKey(key)事先已经存在了,所以并未进入if中的transform(),导致命令未能成功执行

那为什么会存在这个c014呢?

主要是我们Poc.java中的hashSet.add(tiedMapEntry)操作

这一步相当于将fakeTransformers的内容在链中执行了一遍,导致c014也被put了进去

 

因此我们在序列化的时候lazyMap事先必须不存在c014键值,这样才进入这个if分支

所以直接使用hashSet.add(tiedMapEntry)是不行的,还需要在序列化之前删除lazyMap中的c014属性

remove()掉即可

EXP part 3

 

整合EXP