漏洞原理
TransformedMap这个类的decorate函数可以将一个普通的Map转换为一个TransformedMap,其第2、3参数分别对应当key改变和value改变时需要做的操作。所以此时如果修改其中的任意key或value,就会触发我们预先定义好的某些操作来对Map进行处理,具体的变换逻辑由Transformer类定义。
由于commons-collections内置了很多常见的transformer,我们可以利用InvokerTransformer通过反射的方式去调用任意的函数。通过getClass()、getMethod、invoke()进行反射,最终实现类似于:
((Runtime) Runtime.class.getMethod("getRuntime").invoke()).exec("calc")
而多个Transformer可以串起来,形成ChainedTransformer。当触发时,ChainedTransformer可以按顺序调用一系列的变换,只需要传入一个Transformer数组即可。
CC的利用链版本,maven依赖
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.0</version>
</dependency>
因为在3.1-3.2.1版本中TransformingComparator类没有实现Serializable接口,不能够被序列化,于是就不能在使用链上构造了。
CommonsCollections1
环境:JDK1.7、commons-collections-3.1-3.2.1
漏洞点
commons-collections-3.1-src.jar:
/org/apache/commons/collections/functors/InvokerTransformer.java
在 InvokerTransformer 类的transform方法中使用了反射,且反射参数均可控,所以我们可以利用这处代码调用任意类的任意方法
Transformer
Transformer是Commons Collections中提供的一个接口
ConstantTransformer
ConstantTransformer是Transformer的实现类
InvokerTransformer
InvokerTransformer也是Transformer的实现类,
在构造方法中有三个参数,第⼀个参数是待执⾏的⽅法名,第⼆个参数
是这个函数的参数列表的参数类型,第三个参数是传给这个函数的参数列表 。里面还提供了一个Transform的方法,该方法可以通过Java反射机制来进行执行任意代码。
ChainedTransformer
ChainedTransformer也是实现了Transformer接⼝的⼀个类,看到transform方法是通过传入Trasnformer[]数组来对传入的数值进行遍历并且调用数组对象的transform方法。
Map
Transform来执行命令需要绑定到Map上,抽象类AbstractMapDecorator是Apache Commons Collections提供的一个类,
实现类有很多,比如LazyMap、TransformedMap等,这些类都有一个decorate()方法,用于将上述的Transformer实现类绑定到Map上,当对Map进行一些操作时,会自动触发Transformer实现类的tranform()方法,不同的Map类型有不同的触发规则。
TransformedMap
Transformer实现类分别绑定到map的key和value上,当map的key或value被修改时,会调用对应Transformer实现类的transform()方法。我们可以把chainedtransformer绑定到一个TransformedMap上,当此map的key或value发生改变时,就会自动触发chainedtransformer。
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);