利用链
yso给出的利用链:

完整的:
1 | ObjectInputStream.readObject() |
可以看到,CC2使用了PriorityQueue reaObject作为了反序列化的入口
这里调用了heapify函数

在这个函数里面又调用了siftDown

在这面又调用了siftDownUsingComparator


这里就调用了comparator.compare(),如果这里的comparator是TransformingComparator类型,则会调用transform函数,达到利用效果。

基于以上,想要满足程序能按照我们预想的顺序执行,我们需要满足几个条件:
- comparator不为空,这个条件可以通过
PriorityQueue的构造函数完成

size >= 2,这个条件可以通过两个add函数满足

而且,如果我们直接把恶意类放进PriorityQueue的话,那么在PriorityQueue的add中会调用offer

进而调用siftUp

然后提前触发恶意类的代码执行,所以,要现将无害的信息放进PriorityQueue,然后最后再将恶意的类替换进去:

这里使用了yso工具类进行字段替换:

替换后:

然后,transformer调用newTransformer,然后触发恶意类,完成利用。

TemplatesImpl
我们可以发现,在yso中,和CC1不一样的是,这里没有直接使用InvokerTransformer来完成利用(但是是可以用的),而是使用了TemplatesImpl:

这里的流程是:
在TemplatesImpl 存在一个 成员变量_bytecodes,当调用 TemplatesImpl#newTransformer 方法时,将会把
_bytecodes 实例化,所以我们可以将恶意代码写到类的无参构造函数或static代码块中转换为字节码赋值给_bytecodes ,然后找到一个位置调用newTransformer就能完成整个攻击。
但是要注意,这里的_bytecodes对象必须是AbstractTranslet的子类
yso通过以下方法完成了这个_bytecodes的创建



