注意:
有关于反序列化漏洞的相关介绍在文章Java 中 DNS 反序列化漏洞的分析与复现已经有所描述,本文不在对此方面进行赘述。
一、Apache Commons Collection
CC链涉及到一个框架 。Apache Commons Collections 。
Apache Commons Collections是一个扩展了Java标准库里的Collection结构的第三方基础库,它提供了很多强大的数据结构类型和实现了各种集合工具 类。作为Apache开放项目的重要组件,Commons Collections被广泛的各种Java应用的开发。可以在Apache官网下载CC的jar文件和源代码,用于代码审计。Collections – Home ,本教程以3.2.1版本为例,JDK版本必须在1.8.0_71以下,检测java版本:
因为之后的版本无法利用 sun.reflect.annotation.AnnotationInvocationHandler 类进行反序列化处理。可以在此下载JDK源码:https://hg.openjdk.org/jdk8u/jdk8u60/jdk/file/935758609767/src/share/classes (此版本针对1.8.0_60,如果是其他版本,则浏览 OpenJDK Mercurial Repositories 即可)。
Java集合框架:称为Collection,是Java中存在的一系列操作List、Set和Map的类的集合。Commons Collections扩展了集合框架,增强了很多功能。
二、cc的简单运用
引入cc代码,放入位置,如图一:
图一
代码:
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
对比应用。如图二:
图二
具体代码:
public static void main(String[] args) {
Map<String,String> maps = new HashMap<>();
maps.put("one","anhui");
maps.put("two","beijing");
maps.put("three","shanghai");
maps.put("four","guangdong");
maps.put("five","shenzhen");
//entrySet();方法是Map接口中的方法,返回的是一个Set集合,Set集合中的元素是一个Map.Entry<String, String>对象,也就是 键值对 对象(键和值)
Set<Map.Entry<String,String>> entries = maps.entrySet();
for(Map.Entry<String,String> entry:entries){
System.out.println(entry.getKey()+"="+entry.getValue());
}
System.out.println("==============================");
//cc的简单使用,创建有序的Map集合:OrderedMap
OrderedMap orderedMap = new LinkedMap();
orderedMap.put("one","anhui");
orderedMap.put("two","beijing");
orderedMap.put("three","shanghai");
orderedMap.put("four","guangdong");
orderedMap.put("five","shenzhen");
Set sets= orderedMap.keySet();
for(Object key:sets){
System.out.println(key+"="+orderedMap.get(key));
}
}
感兴趣的,更多有关于cc的使用方法:https://cloud.tencent.com/developer/article/1497565
三、cc6
1、确认cc6执行链的终点:InvokerTransformer.class,位置:
//终点所在位置
package org.apache.commons.collections.functors;
如图三:
图三
通过对InvokerTransformer.class代码观察到,该类并虽然可序列化,但是从直观上来看并没有重写readObject,先具体确定到漏洞产生的终点的方法:public Object transform,代码如下:
public class InvokerTransformer implements Transformer, Serializable {
public Object transform(Object input) {
if (input == null) {
return null;
} else {
try {
Class cls = input.getClass();
Method method = cls.getMethod(this.iMethodName, this.iParamTypes);
return method.invoke(input, this.iArgs);
} catch (NoSuchMethodException var4) {
throw new FunctorException("InvokerTransformer: The method '" + this.iMethodName + "' on '" + input.getClass() + "' does not exist");
} catch (IllegalAccessException var5) {
throw new FunctorException("InvokerTransformer: The method '" + this.iMethodName + "' on '" + input.getClass() + "' cannot be accessed");
} catch (InvocationTargetException var6) {
throw new FunctorException("InvokerTransformer: The method '" + this.iMethodName + "