漏洞分析

CC3.1-InvokerTransformer.class

image.png

  • 由此可知InvokerTransormer类中提供了一个transform方法存在一组反射调用,若input、ImethodName、iParamTypes、iArgs参数可控即可以进行命令执行(那就找找参数从何而来

image.png

  • 可见四个参数都是通过传入函数的,说明可控。 ```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());

  1. }

}

  1. 通过InvokerTransformer来执行命令,接下来就要寻找能够自动调用InvokerTransformer类的transform方法,明显调用transform()方法有以下两个类:
  2. - TransformedMap
  3. - LazyMap
  4. <a name="6tKJ3"></a>
  5. ####
  6. <a name="Og6Gh"></a>
  7. ### TransformedMap
  8. ```java
  9. Apache Commons Collections 中实现了类TransformedMap,用来对Map进行某种变换。只要调用decorate()函数,传入key和value的变换函数Transformer,即可从任意Map对象生成相应的TransformedMap,decorate()函数如下
  10. public static Map decorate(Map map, Transformer keyTransformer, Transformer valueTransformer) {
  11. return new TransformedMap(map, keyTransformer, valueTransformer);
  12. }
  • 其中,Transformer参数 是定义的如何变换的函数
  • Map中的任意项的Key或者Value被修改,相应的Transformer(keyTransformer或者valueTransformer)的transform方法就会被调用。
  • 将传入decorate方法的参数作为实例化TransformedMap类的参数传入

image.png
TransformedMap实现了Map接口,并且其中有个setValue方法,每当调用map的setValue方法时,该方法将会被调用。

TransformedMap父类AbstractInputCheckedMapDecorator类中有对setValue的重写:
image.png
跟进TransformedMap.checkSetValue,此处会调用transform方法:
image.png
实际触发流程:
(被decorate修饰过的map)setValue -> checkSetValue -> valueTransformer.transform(value)

LazyMap

LazyMap实现了Map接口,其中的get(Object)方法调用了transform()方法,跟进函数进去
image.png这里可以看到,在调用transform()方法之前会先判断当前Map中是否已经有该key,如果没有最终会由这里的factory.transform()进行处理,跟踪facory变量找到decorate()方法。
image.png
这里的decorate()方法会对factory进行初始化,同时实例化一个LazyMap,为了能成功调用transform()方法,找到了LazyMap,发现在get()方法中调用了transform()方法,那么现在漏洞利用的核心条件就是去寻找一个类,在对象进行反序列化时会调用我们精心构造对象的get(Object)方法。