前言
分析CC2链的实现原理,CC2链是因为CC3中的TransformingComparator类在4.0版本不能进行序列化
环境
JDK:1.8.0_65
Apache Commons Collections:4.0
正文
TransformingComparator类
该类是类转换比较器,构造器中存放Transfomer,compare方法中调用了transform
PriorityQueue类
该类主要作用是用来排序,在readObject方法中进行触发
这里主要是heapify方法,前面主要是对字节流进行读取和存放
heapify方法中就是一个for循环,对size进行右移运算,这里想要进入siftDown方法,保证size的大小超过2,然后看siftDown方法
如果调用siftDown方法的类对象中是否存在comparator,会进入两个不同的方法中,现在看一下这两个方法的具体实现
这两个方法都会调用compare方法,只是第一个方法是 key对象进行调用,第二个方法是comparator对象调用
进入org.apache.commons.collections4.comparators.TransformingComparator类
这样就可以写调用代码了,这里实例化PriorityQueue对象需要对队列初始化,所以传入两个参数,初始化时候设置为2
执行后发现在序列化的时候直接调用了计算器
调试一下
这里会进入siftUp方法
进入 siftUpUsingComparator方法
在这里调用了compare方法
调用了两次计算器
所以可以采用CC1方法,在对象实例化的时候不添加comparator对象,添加玩元素后再通过反射传入comparator对象,这样没有comparator对象后,siftUp方法执行后会进入siftUpComparable方法,这里不会调用compare方法,可以避免触发调用计算器
所以可以这样改poc
上面是利用ChainedTransformer类的链条,也可以通过字节码的方式进行触发
这里可以用TemplatesImpl.newTransformer()触发恶意类
通过InvokerTransformer对newTransformer方法进行调用
这里可以先创建一个未加载恶意字节的TransformingComparator类对象,然后通过通过反射,将
invokerTransformer对象赋值到priorityQueue对象中
,