CommonsCollections2
摘要:CC2
0x01 链子
这条链子对应的是commons-collections:4.0
这条链子的原理是通过PQ中的heapify方法里会调用自己的Transformer进行比较导致的字节码执行。
一些疑问
为什么要有CC2:CC2主要是用于处理CC1在高版本jdk中无法使用的问题,以及4.0包中链子的问题;
为什么只有在commons-collections:4.0可用:在P神的Java安全漫谈16中有提到,这条链子无法在4.0+和3.x版本中使用,原因是利用链中的org.apache.commons.collections4.comparators.TransformingComparator 并未实现Serializable接口;而从4.1起,官方直接禁用了InvokerTransformer等类的使用。用P神的话讲,更绝。
调试
1、直接跳过ObjectInputStream#readObject(),来到PriorityQueue#readObject();
2、进入到heapify();
3、跳过一些包装直接进入到siftDownUsingComparator(),关注到第722行comparator.compare();
4、进入到一开始PoC中设置的comparator:TransformingComparator的compare方法,到此链子调试完毕,此处触发TemplateImp字节码任意执行命令的链子。
0x02 ysoserial源码分析
同之前一样,CC2这条链子也使用了自己定义的方法来生成荷载。这次使用的是createTemplatesImpl,传入了三个参数:
第一个参数为TemplatesImpl类,用于生成TemplatesImpl实例
第二个参数为AbstractTranslet
第三个参数为TransformerFactoryImpl类,为TemplatesImpl实例中_tfactory属性需要的值
而构造TemplatesImpl利用链的要点在于:
_bytecodes为字节码,字节码中对应的类必须为AbstractTranslet的子类
_name为任何字符串但不可为空
_tfactory得是TranformerFactoryImpl对象。而ysoserial也是按照这个套路来行事的。
来看一些初看会非常迷惑的点:
1、静态代码块的设置
1 | String cmd = "java.lang.Runtime.getRuntime().exec(\"" + |
这里是往StubTransletPayload类中加入静态代码块,包含执行代码cmd。这个静态代码块可以参考P神的Java安全漫谈系列反射那一节的文章。
2、为什么是AbstractTranslet
源码往下一点有这样一句代码:
1 | CtClass superC = pool.get(abstTranslet.getName()); |
这里将clazz(也就是恶意类)的父类设置为AbstractTranslet,之所以如此,看TemplatesImpl的调用链:
1 | TemplatesImpl.getOutputProperties() |
来到TemplatesImpl第415行,这里处于defineTransletClasses()方法内部:
这里会将字节码中的类的父类整出来,而后在getTransletInstance()中的455行:
实例化这个类,而后触发static代码块。
- 本文标题:CommonsCollections2
- 本文作者:Hn13
- 本文链接:https://www.hn13.top/2021/04/04/CommonsCollections2/>
- 发布时间:2021-04-04
- 版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!