JAVA反序列化深入学习(三):CommonsCollections1

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环境

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

依赖版本

  • commons-collections : 3.1 - 3.2.1
  • TransformedMap - jdk < 8u71

检查依赖配置

确认项目中是否正确引入了 Apache Commons Collections 的依赖。如果使用的是 Maven,可以在 pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.2.1</version>
</dependency>

资源下载

前置知识

AbstractMapDecorator

首先 CC 库中提供了一个抽象类org.apache.commons.collections.map.AbstractMapDecorator,这个类是 Map 的扩展,并且从名字中可以知道,这是一个基础的装饰器,用来给 map 提供附加功能

被装饰的 map 存在于该类的属性中,并且将所有的操作都转发给这个 map

这个类有很多实现类,各个类触发的方式不同,重点关注:

  • TransformedMap
  • LazyMap
TransformedMap

org.apache.commons.collections.map.TransformedMap 类可以在一个元素被加入到集合内时

  1. 自动对该元素进行特定的修饰变换
  2. 具体的变换逻辑由 Transformer 来定义
  3. TransformerTransformedMap 实例化时作为参数传入

接下来看一下几个重点方法

decorate

TransformedMap 通过 decorate 函数将自定义的转换逻辑Transformer装饰到传入的map 中,Transformer分为keyTransformervalueTransformer,分别对应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

transformKey/transformValue方法中,会调用keyTransformer/valueTransformertransform方法,实际进行转换

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);
}
put

调用 TransformedMapput 方法时,会触发transformKey/transformValue方法,从而触发transform方法,实际进行转换

public Object put(Object key, Object value) {
    key = transformKey(key);
    value = transformValue(value);
    return getMap().put(key, value);
}

当 TransformedMap 内的 key 或者 value 发生变化时,就会触发相应参数的 Transformertransform 方法,这里以put方法举例

使用实例
public static void main(String[] args) throws Exception {

    // 创建基础HashMap对象
    HashMap<Object, Object> map = new HashMap<>();
    map.put(1, "a");
    System.out.println("初始化map: " + map);

    // 创建一个Transformer对象,将输入的key转换为key + 1
    Transformer keyTransformer = input -> (Object) ((int) input + 1);
    // 创建一个Transformer对象,将输入的value转换为value + "1"
    Transformer valueTransformer = input -> input + "1";

    // 使用TransformedMap包装原始map对象
    Map transformedMap = TransformedMap.decorate(map, keyTransformer, valueTransformer);

    // 使用put触发transform()方法
    transformedMap.put(2, "b");
    System.out.println("transformedMap1: " + transformedMap);
    transformedMap.put(1, "c");
    System.out.println("transformedMap2: " + transformedMap);
    transformedMap.remove(1);
    System.out.println("transformedMap3: " + transformedMap);
}

LazyMap

org.apache.commons.collections.map.LazyMapTransformedMap 类似,差异在于

  • 调用get()方法时如果传入的 key 不存在,则会触发相应参数的Transformertransform()方法。

org.apache.commons.collections.map.DefaultedMapLazyMap 具有相同功能,同样是 get() 方法会触发 transform()方法

decorate

LazyMap 通过 decorate 函数将自定义的转换逻辑Transformer装饰到传入的map 中,Transformer只有factory,不分keyTransformervalueTransformer

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;
}
get

调用 LazyMap 的 get 方法时,如果装饰的 map 中不存在传入的key,会触发factorytransform方法,实际进行转换

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<Object, Object> map = new HashMap<>();
    map.put(1, "a");
    System.out.println("初始化map: " + map);
    
    // 创建一个Transformer对象,将输入的key转换为key + 1
    Transformer factory = input -> (Object) ((int) input + 1);

    // 使用TransformedMap包装原始map对象
    Map lazyMap = LazyMap.decorate(map, factory);

    System.out.println("LazyMap: " + lazyMap);
    System.out.println("LazyM
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Neolock

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值