Apache Commons Collections 是一个扩展了 Java 标准库里的 Collection 结构的第三方基础库,它提供了很多强有力的数据结构类型并实现了各种集合工具类。作为 Apache 开源项目的重要组件,被广泛运用于各种 Java 应用的开发。
目录
JAVA环境
依赖版本
检查依赖配置
资源下载
前置知识
AbstractMapDecorator
TransformedMap
decorate
transformKey/transformValue
put
使用实例
LazyMap
decorate
get
使用实例
Transformer
InvokerTransformer - sink
transform
利用实例
ChainedTransformer - chain
transform
ConstantTransformer
攻击构造
sink & chain
kick-off
AnnotationInvocationHandler
构造方法
readObject
构造恶意Payload
基于TransformedMap
反序列化流程分析
基于LazyMap
总结
利用说明
Gadget 总结
调用链展示
基于TransformedMap
基于LazyMap
拓展知识点:动态代理
1. 动态代理的核心组件
2. 动态代理的工作流程
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b18)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b18, mixed mode)
Apache Commons Collections 依赖版本:Commons Collection 3.2.1
确认项目中是否正确引入了 Apache Commons Collections 的依赖。如果使用的是 Maven,可以在 pom.xml
文件中添加以下依赖:
commons-collections
commons-collections
3.2.1
首先 CC 库中提供了一个抽象类org.apache.commons.collections.map.AbstractMapDecorator
,这个类是 Map 的扩展,并且从名字中可以知道,这是一个基础的装饰器,用来给 map 提供附加功能
被装饰的 map 存在于该类的属性中,并且将所有的操作都转发给这个 map
这个类有很多实现类,各个类触发的方式不同,重点关注:
TransformedMap
LazyMap
org.apache.commons.collections.map.TransformedMap
类可以在一个元素被加入到集合内时
Transformer
来定义Transformer
在 TransformedMap
实例化时作为参数传入接下来看一下几个重点方法
TransformedMap 通过 decorate
函数将自定义的转换逻辑Transformer
装饰到传入的map
中,Transformer
分为keyTransformer
与valueTransformer
,分别对应key和value的转换逻辑
public static Map decorate(Map map, Transformer keyTransformer, Transformer valueTransformer) {
return new TransformedMap(map, keyTransformer, valueTransformer);
}
protected TransformedMap(Map map, Transformer keyTransformer, Transformer valueTransformer) {
super(map);
this.keyTransformer = keyTransformer;
this.valueTransformer = valueTransformer;
}
在transformKey
/transformValue
方法中,会调用keyTransformer
/valueTransformer
的transform
方法,实际进行转换
protected Object transformKey(Object object) {
if (keyTransformer == null) {
return object;
}
return keyTransformer.transform(object);
}
protected Object transformValue(Object object) {
if (valueTransformer == null) {
return object;
}
return valueTransformer.transform(object);
}
调用 TransformedMap
的 put
方法时,会触发transformKey
/transformValue
方法,从而触发transform
方法,实际进行转换
public Object put(Object key, Object value) {
key = transformKey(key);
value = transformValue(value);
return getMap().put(key, value);
}
当 TransformedMap 内的 key 或者 value 发生变化时,就会触发相应参数的 Transformer
的 transform
方法,这里以put
方法举例
public static void main(String[] args) throws Exception {
// 创建基础HashMap对象
HashMap
org.apache.commons.collections.map.LazyMap
与 TransformedMap
类似,差异在于
get()
方法时如果传入的 key 不存在,则会触发相应参数的Transformer
的transform()
方法。org.apache.commons.collections.map.DefaultedMap
与 LazyMap
具有相同功能,同样是 get()
方法会触发 transform()
方法
LazyMap 通过 decorate
函数将自定义的转换逻辑Transformer
装饰到传入的map
中,Transformer
只有factory
,不分keyTransformer
与valueTransformer
public static Map decorate(Map map, Transformer factory) {
return new LazyMap(map, factory);
}
protected LazyMap(Map map, Transformer factory) {
super(map);
if (factory == null) {
throw new IllegalArgumentException("Factory must not be null");
}
this.factory = factory;
}
调用 LazyMap 的 get
方法时,如果装饰的 map 中不存在传入的key,会触发factory
的transform
方法,实际进行转换
public Object get(Object key) {
// create value for key if key is not currently in the map
if (map.containsKey(key) == false) {
Object value = factory.transform(key);
map.put(key, value);
return value;
}
return map.get(key);
}
public void test() {
// 创建基础HashMap对象
HashMap