漏洞分析
CC3.1-InvokerTransformer.class
- 由此可知InvokerTransormer类中提供了一个transform方法存在一组反射调用,若input、ImethodName、iParamTypes、iArgs参数可控即可以进行命令执行(那就找找参数从何而来
- 可见四个参数都是通过传入函数的,说明可控。 ```java import org.apache.commons.collections.functors.InvokerTransformer;
public class InvokerTransformerTest { public static void main(String[] args){ InvokerTransformer invokerTransformer = new InvokerTransformer(“exec”, new Class[]{String.class}, new Object[]{new String(“calc”)}); invokerTransformer.transform(Runtime.getRuntime());
}
}
通过InvokerTransformer来执行命令,接下来就要寻找能够自动调用InvokerTransformer类的transform方法,明显调用transform()方法有以下两个类:
- TransformedMap
- LazyMap
<a name="6tKJ3"></a>
####
<a name="Og6Gh"></a>
### TransformedMap
```java
Apache Commons Collections 中实现了类TransformedMap,用来对Map进行某种变换。只要调用decorate()函数,传入key和value的变换函数Transformer,即可从任意Map对象生成相应的TransformedMap,decorate()函数如下
public static Map decorate(Map map, Transformer keyTransformer, Transformer valueTransformer) {
return new TransformedMap(map, keyTransformer, valueTransformer);
}
- 其中,Transformer参数 是定义的如何变换的函数。
- Map中的任意项的Key或者Value被修改,相应的Transformer(keyTransformer或者valueTransformer)的
transform
方法就会被调用。 - 将传入decorate方法的参数作为实例化TransformedMap类的参数传入
TransformedMap
实现了Map接口,并且其中有个setValue
方法,每当调用map的setValue
方法时,该方法将会被调用。
TransformedMap
父类AbstractInputCheckedMapDecorator
类中有对setValue的重写:
跟进TransformedMap.checkSetValue
,此处会调用transform
方法:
实际触发流程:
(被decorate修饰过的map)setValue -> checkSetValue -> valueTransformer.transform(value)
LazyMap
LazyMap
实现了Map
接口,其中的get(Object)
方法调用了transform()
方法,跟进函数进去
这里可以看到,在调用transform()
方法之前会先判断当前Map中是否已经有该key,如果没有最终会由这里的factory.transform()
进行处理,跟踪facory
变量找到decorate()
方法。
这里的decorate()
方法会对factory
进行初始化,同时实例化一个LazyMap
,为了能成功调用transform()
方法,找到了LazyMap
,发现在get()
方法中调用了transform()
方法,那么现在漏洞利用的核心条件就是去寻找一个类,在对象进行反序列化时会调用我们精心构造对象的get(Object)
方法。