ysoserial利用链分析(一)
字数 2063 2025-08-10 08:28:32

ysoserial利用链分析(一) - CommonsCollections1与CommonsCollections2详解

1. CommonsCollections1利用链分析

1.1 利用链执行流程

  1. 起始点: AnnotationInvocationHandler.readObject
  2. 动态代理触发: 执行entrySet方法时触发AnnotationInvocationHandler.invoke
  3. LazyMap调用: 最终调用到LazyMap.get方法
  4. 命令执行核心: 进入org.apache.commons.collections.functors.ChainedTransformer#transform

1.2 关键组件分析

  • LazyMap: 通过其get方法触发后续利用链
  • ChainedTransformer: 核心转换器,遍历iTransformers数组执行转换操作
  • Transformer数组构造:
    • 第一次循环返回Runtime.class对象
    • 通过ConstantTransformer的构造函数对iConstant赋值
    • 后续循环最终调用到exec方法
  • InvokerTransformer:
    • iMethodName等值来自构造函数初始化
    • 最终通过反射执行命令

1.3 利用限制

  • 适用于JDK 1.8 8u71版本之前

2. Commons-Collections2利用链分析

2.1 适用环境

  • 适用于common-collection4-4.0
  • 解决JDK 1.8 8u71版本后cc1无法使用的问题

2.2 利用链执行流程

  1. 起始点: PriorityQueue.readObject
  2. 堆调整: 进入heapify函数
  3. 队列设置: 需要将size设置为2才能继续利用
    queue.add(1);
    queue.add(1);
    
  4. 转换执行: 进入org.apache.commons.collections4.comparators.TransformingComparator#compare
  5. 模板触发: 反射执行com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer
  6. 实例化执行:
    • 进入getTransletInstance
    • 实例化StubTransletPayload类触发反序列化

2.3 关键组件分析

  • PriorityQueue: 利用其反序列化行为触发利用链
  • TransformingComparator: 通过compare方法触发transform
  • TemplatesImpl:
    • _bytecodes赋值给_class(来自ysoserial构造)
    • 通过defineTransletClasses加载恶意类
    • 最终执行构造函数中包含的命令

3. 对比分析

特性 CommonsCollections1 CommonsCollections2
适用版本 JDK 1.8 8u71之前 common-collection4-4.0
起始类 AnnotationInvocationHandler PriorityQueue
核心转换器 ChainedTransformer TransformingComparator
最终执行点 Runtime.exec() TemplatesImpl.newTransformer()
依赖的集合组件 LazyMap PriorityQueue

4. 防御建议

  1. 升级JDK到最新版本
  2. 更新commons-collections库
  3. 限制反序列化操作
  4. 使用安全框架如SerialKiller过滤恶意序列化数据

5. 扩展思考

  1. 利用链构造原理: 通过精心构造的对象图,利用Java反序列化机制自动调用一系列方法
  2. 绕过限制技巧: 通过寻找替代类和方法绕过高版本JDK的限制
  3. 检测方法: 可以通过监控特定类的加载和特定方法的调用来检测此类攻击
ysoserial利用链分析(一) - CommonsCollections1与CommonsCollections2详解 1. CommonsCollections1利用链分析 1.1 利用链执行流程 起始点 : AnnotationInvocationHandler.readObject 动态代理触发 : 执行 entrySet 方法时触发 AnnotationInvocationHandler.invoke LazyMap调用 : 最终调用到 LazyMap.get 方法 命令执行核心 : 进入 org.apache.commons.collections.functors.ChainedTransformer#transform 1.2 关键组件分析 LazyMap : 通过其 get 方法触发后续利用链 ChainedTransformer : 核心转换器,遍历 iTransformers 数组执行转换操作 Transformer数组构造 : 第一次循环返回 Runtime.class 对象 通过 ConstantTransformer 的构造函数对 iConstant 赋值 后续循环最终调用到 exec 方法 InvokerTransformer : iMethodName 等值来自构造函数初始化 最终通过反射执行命令 1.3 利用限制 适用于JDK 1.8 8u71版本之前 2. Commons-Collections2利用链分析 2.1 适用环境 适用于common-collection4-4.0 解决JDK 1.8 8u71版本后cc1无法使用的问题 2.2 利用链执行流程 起始点 : PriorityQueue.readObject 堆调整 : 进入 heapify 函数 队列设置 : 需要将 size 设置为2才能继续利用 转换执行 : 进入 org.apache.commons.collections4.comparators.TransformingComparator#compare 模板触发 : 反射执行 com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer 实例化执行 : 进入 getTransletInstance 实例化 StubTransletPayload 类触发反序列化 2.3 关键组件分析 PriorityQueue : 利用其反序列化行为触发利用链 TransformingComparator : 通过 compare 方法触发 transform TemplatesImpl : _bytecodes 赋值给 _class (来自ysoserial构造) 通过 defineTransletClasses 加载恶意类 最终执行构造函数中包含的命令 3. 对比分析 | 特性 | CommonsCollections1 | CommonsCollections2 | |---------------------|-----------------------------------|-----------------------------------| | 适用版本 | JDK 1.8 8u71之前 | common-collection4-4.0 | | 起始类 | AnnotationInvocationHandler | PriorityQueue | | 核心转换器 | ChainedTransformer | TransformingComparator | | 最终执行点 | Runtime.exec() | TemplatesImpl.newTransformer() | | 依赖的集合组件 | LazyMap | PriorityQueue | 4. 防御建议 升级JDK到最新版本 更新commons-collections库 限制反序列化操作 使用安全框架如SerialKiller过滤恶意序列化数据 5. 扩展思考 利用链构造原理 : 通过精心构造的对象图,利用Java反序列化机制自动调用一系列方法 绕过限制技巧 : 通过寻找替代类和方法绕过高版本JDK的限制 检测方法 : 可以通过监控特定类的加载和特定方法的调用来检测此类攻击