利用链
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
的创建