前言
CommonCollections系列的gadgets之CommonsCollections4
实验环境:jdk1.8.0_211、org.apache.commons:commons-collections4:4.0
代码分析
对于CommonCollections4,官方的注释
1 | /* |
将CommonCollections2中的InvokerTransformer替换为了InstantiateTransformer,我们看看InstantiateTransformer的transform方法
1 | public T transform(Class<? extends T> input) { |
该方法能调用某个类的构造函数并实例化,通过之前几期的cc链分析,我们明白com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter的构造函数可以调用到(TransformerImpl) templates.newTransformer()。如果templates的_bytecode被设置为我们的恶意代码,就可以实现任意代码执行。
因此这条链的整体思路就是用ChainedTransformer把new ConstantTransformer(TrAXFilter.class)和InstantiateTransformer串联起来,把TrAXFilter.class作为InstantiateTransformer的输入。接下来为了使ChainedTransformer.transform得到触发,我们把ChainedTransformer作为参数构造TransformingComparator实体类。然后利用PriorityQueue最终调用到TransformingComparator实体类的compare方法。后面这一套操作和cc2是完全一样的。
为什么exp中很多关键点都是先赋值了一个简单的字符串,然后再反射赋值的?
这个问题其实cc2的文章中也说过,在第二个queue.add(1)时会触发进入siftUp(i, e),然后触发
TransformingComparator.compare,提前触发我们构造好的调用链,然后会抛出异常从而终止后面的行为。因此我们先在原本调用恶意类的恶意方法处修改为一个不会有异常抛出的正常类的正常方法。当我们准备生成反序列化payload时再把正常类的正常方法通过反射修改即可。
后记
cc4在cc2上改动不大,理解了cc2就会比较好理解,因此笔墨不多。。。