【bsauce读论文】PSPRAY-基于时序侧信道的Linux内核堆利用技术

news2024/11/16 21:26:21

会议:USENIX Security’23

作者:来自 Seoul National University 的 Yoochan Lee、Byoungyoung Lee 等人。

主要内容:由于Linux内核的堆分配器SLUB开启的freelist随机化保护,所以堆相关的内核漏洞利用成功率较低(平均为56.1%)。本文提出PSPRAY,采用基于时序侧信道的利用技术来提高OOB/UAF/DF漏洞的利用成功率,成功率从56.1%提高到了97.92%。作者还提出了防护机制来缓解PSPRAY攻击,将成功率降低到和不使用PSPRAY的成功率一样,且带来的性能开销只有0.25%,内存开销只有0.52%,几乎可以忽略不计。

1. Introduction

现有的防护机制:KASLR [11], KCFI [8, 12], and KDFI [21, 34]

动机:如果利用失败会导致崩溃并被发现,为了隐藏攻击行为,需提高利用成功率。堆漏洞利用成功率无法保证的原因有以下两点

  • (1)攻击者无法在用户层感知内存分配的状态;
  • (2)内核内存分配具有随机性,难以预测。

例如,对于堆漏洞OOB/UAF/DF都要求漏洞对象和目标对象相邻或重叠,以往堆喷都是靠运气触发。

本文思路:通过时序侧信道来区分SLUB内部的分配路径,间接探知slab的分配状态(判断是否是从empty freelist分配到的内存),最后根据此信息来增大堆漏洞利用的稳定性(避免利用OOB时漏洞对象和目标对象分配不相邻,利用UAF时漏洞对象和目标对象分配不重叠)。

实验结果:采用10个CVE来测试,成功率从56.1%提高到了97.92%。 其中 83bec2 从13.70%提升到98.16%。

2. Background

2-1 SLUB分配器

请添加图片描述

SLUB分配器架构

  • 内核中需要申请的对象相对比较固定,大部分情况下是一些编译期确定的常见的结构体。SLUB分配器根据对象的不同含有多个kmem_cache,如特定类型的task_struct、特定大小的kmalloc-系列(如kmalloc-96kmalloc-128kmalloc-sizeof(task_struct)kmalloc-sizeof(mm_struct)等);
  • 每个kmem_cache都使用per-CPU和per-node机制来管理slab,具体来说,每个CPU核都有单独的 freelist / page / partial;freelist是一个单链表,负责存储page上的空闲对象,分配对象时就从这个freelist上分配。
    • 每个 CPU 对应一个 cpu-freelistpage-freelistpartial-freelist。每个 page-freelist 有一个 slab,每个partial-freelist有一个或多个 slab。
    • 每个 node 对应一个 partial-freelist,包含一个或多个 slab。
  • 即使每个slab都有一个freelist,SLUB分配器还管理了一个单独的CPU-freelist来提高分配效率,所以访问某个slab中CPU的page-freelistpartial-freelist要比直接访问CPU-freelist要慢(在CPU-freelist为空时才访问page-freelist和partial-freelist);
  • 注意,CPU的page-freelist包含1个slab,而partial-freelist包含1个或多个slab。
  • 每个node也有1个partial,包含1个或多个slab(在CPU-freelist为空时才访问该node的partial-freelist)。

请添加图片描述

SLUB分配顺序:遵循一个原则,所有的对象都从CPU-freelist分配,如果CPU-freelist为空则从别的slab挪过来。所以有5条路径

  • Fast-path:首先在 CPU-freelist 里寻找内存,如果还有空闲内存则直接返回;
  • Medium-path #1:fast-path 未成功,说明 CPU-freelist 中已经没有空闲内存了,那么直接将该 CPU 的 page-freelist 挪到CPU-freelist,再从 CPU-freelist 中分配内存;
  • Medium-path #2:Medium-path #1 未成功,说明该 CPU 的 page-freelist 是空的,那么将该 CPU 的 partial-freelist 中一个 list 挪到 page-freelist,再挪到 CPU-freelist 后分配内存;
  • Medium-path #3:Medium-path #2 未成功,说明该 CPU 的 partial-freelist 是空的,那么从 node 的 partial-freelist 中拿一个作为 CPU 的 page-freelist,再挪到 CPU-freelist 后分配内存;
  • Slow-path:此前所有的尝试都没有成功,这时候就需要从 Buddy Allocator 中拿新的 page 出来,填充 SLUB分配器,再进行分配。这条路径显著慢于之前的路径。

2-2 SLUB freelist保护机制

Linux v4.8开始引入该机制,Ubuntu v16.04 / Debian v9设置为默认开启,在 fast-path 中增加随机性,将freelist中的空闲块顺序打乱,这样在利用OOB漏洞时就很难使漏洞对象和目标对象相邻。

3. 利用成功与失败分析

3-1 OOB漏洞

请添加图片描述

成功利用:如图Figure 4,先调用1000次open()分配目标对象,再调用1次sendmsg()分配漏洞对象,弱漏洞对象和目标对象相邻,即可通过溢出篡改目标对象。

请添加图片描述

失败分析:由于有freelist随机化机制,攻击者不知道某slab中堆喷了多少个目标对象。Figure 5中列出了4种情况,若喷了0个目标对象,肯定失败;若喷了1个或2个目标对象,取决于freelist中堆块顺序;若喷射了3个目标对象,但漏洞对象在最后1个,则失败。

3-2 UAF/DF漏洞

请添加图片描述

成功利用-UAF:参见Figure 6,先调用epoll_ctl()分配1个漏洞对象和1个额外对象,再调用ioctl()释放漏洞对象,再调用msgsnd()分配目标对象占据漏洞对象,最后调用close()访问漏洞对象。

请添加图片描述

成功利用-DF:参见Figure 7,在kmalloc-2048中,先分配1个漏洞对象和3个额外的对象,调用connect()释放漏洞对象,再调用msgsnd()分配 msg_msg 对象(victim对象),再调用 shutdown() 第2次释放漏洞对象,实际上释放了victim对象并留下了指向victim对象的悬垂指针,再调用msgsnd()分配 msg_msg 对象(目标对象),这样就能通过悬垂指针访问和篡改目标对象。

请添加图片描述

失败分析分配目标对象时CPU正好启用的新的freelist。触发漏洞的syscall分配漏洞对象时可能会分配多个额外对象,例如,CVE-2018-6555 分配漏洞对象时也分配了12个额外对象(都位于kmalloc-96),假设分配漏洞对象前CPU的page是半满的,分配完漏洞对象后,CPU的page 填满了,相应的slab被移动到full-list,CPU的page空了,再分配额外对象时,内核执行 medium-path #2 / #3 或 slow-path 来填充CPU的page。这样CPU的page变为另一个slab,额外对象从此处分配。接着释放漏洞对象后,分配目标对象是,可能不会复用漏洞对象,因为会从新的page上分配目标对象。

成功概率:三种情况下成功的概率分别为:
P O O B = N − 1 2 N , P U A F , D F = { N − A + 1 N , A < N , 1 N , A ≤ N , P_{OOB}=\frac{N-1}{2N},\\ P_{UAF,DF}= \left\{ \begin{aligned} \frac{N-A+1}{N}, A < N,\\ \frac{1}{N}, A \le N, \end{aligned} \right. POOB=2NN1,PUAF,DF= NNA+1,A<N,N1,AN,

其中 N N N是一个 freelist 中对象的数量, A A A 是一次 UAF/DF 攻击中伴随漏洞对象额外分配的对象数量(上面介绍中未直接提及,请参考原文)。

4. PSPRAY方法

5条路径分配时间:经过测试,5条分配路径的耗时分别是459 / 676 / 1191 / 1848 / 6048时钟周期,slow-path耗时最长,因为要用到buddy分配器,将新的slab取到CPU的 page-freelist,再取到 CPU-freelist

推断分配状态:目标是推断目标slab中分配了多少对象,方法是只要检测到执行了 slow-path 路径,则说明从新slab分配了1个对象。这个时候所有freelist都为空,分配状态清晰,容易进行堆喷利用。

确定堆喷syscall:通过该syscall喷射对象,来判断当前slab分配状态。需满足三个条件——(1)用户权限可用;(2)只分配1个对象;(3)除了分配对象外,其他操作的性能开销小。找到23个syscall,参见 Table A.1。

请添加图片描述

测试区分度:采用 msgsnd() 分配1000次,3种cache(kmalloc-1024 / kmalloc-2048 / kmalloc-4096),结果参见 Figure 9。

  • fast-path 和 medium path 很难区分,因为 msgsnd() 不仅调用 kmalloc() 分配对象,还调用 copy_from_user() 拷贝数据;
  • fast-path 和 slow-path 辨识度很高(参见300-400次的分配区间,此区间的分配趋于稳定)。

请添加图片描述

OOB利用(PSPRAY):参见Figure 10,成功概率为 P O O B = N − 1 N P_{OOB}=\frac{N-1}{N} POOB=NN1

  • (1)一旦观测到 slow-path,说明创建了一个新的 slab B,并且其中正好有一个对象;
  • (2)再分配N-1个对象把这个 slab B 填满;
  • (3)分配N-1个target对象和1个漏洞对象,都会从新的slab C中分配。

请添加图片描述

UAF/DF利用(PSPRAY):参见Figure 10,理论成功率则是 100 % 100\% 100%。。

  • (1)一旦观测到 slow-path,说明创建了一个新的 slab B,并且其中正好有一个对象;
  • (2)分配漏洞对象,会分配额外对象;
  • (3)释放漏洞对象;
  • (4)分配target对象,占据漏洞对象。

请添加图片描述

5. 利用评估

内核版本:Linux v4.15。

5-1 合成漏洞

目的:测试PSPRAY是否对不同的 kmem_cache 有效(从kmalloc-64 到 kmalloc-4096)。

漏洞程序编写:主要实现 OOB read 和 UAF read,代码参见 Figure A.2 和 Figure A.3。其中UAF漏洞,通过调研,发现伴随漏洞对象会平均分配4个额外对象。

测试结果:分别测试不用和用PSPRAY时的理论成功率和实际成功率,参见 Table 1。对于OOB,理论成功概率为48%,实际最小为17.94%,因为系统本身有背景线程的噪声,使用PSPRAY能提高到94.61%;UAF从平均83.46%提高到100%;DF从平均83.67%提高到100%。

请添加图片描述

5-2 真实漏洞

目的:测试PSPRAY是否对真实漏洞有效。

漏洞选取:7个CVE和3个从syzbot。

测试环境:为模拟真实系统,将系统分为两种运行状态:idle——背景线程少;busy——背景线程多(运行stress-ng)。

测试结果:参见Table 2。使用PSPRAY都能显著提高利用成功率。

  • 有些漏洞在系统 busy 时,只有不到 10 % 10\% 10% 的成功率,这些漏洞以往可能会被评估为相对没有那么危险的漏洞,但是在 PSPRAY 的辅助下,都达到了接近 100 % 100\% 100% 的成功率;
  • 对UAF/DF的提升更大,因为其时间窗口(分配漏洞对象和target对象之间)要小于OOB,这样受噪声影响更小。

请添加图片描述

6. 防护机制

思路:一是统一分配时间,但影响系统性能;二是给 slow-path 增加随机性,确保执行 slow-path 不表示 freelist为空。

实现:算法参见 Algorithm 1(只修改13行代码),原理参见 Figure 12。复用 freelist 下标随机化的机制,如果分配到下标为0(也可以指定其他下标)的空闲块,且CPU的 partial-freelist 为空,则走 slow-path,将新slab挪到 partial-freelist。不需要等 freelist 用光了再走 slow-path。防护效果参见 Table A.4。

请添加图片描述

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

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

相关文章

BEV(一)---lift splat shoot

1. 算法原理 1.1 2D坐标与3D坐标的关系 如图&#xff0c;已知世界坐标系上的某点P&#xff08;Xc&#xff0c; Yc&#xff0c; Zc&#xff09;经过相机的内参矩阵可以获得唯一的图像坐标p&#xff08;x&#xff0c; y&#xff09;&#xff0c;但是反过来已知图像上某点p&…

软考初级程序员--学习

1、十进制 转 二进制 1.1、整数十进制87 转换为 二进制为 1010111 1.2 、小数十进制0.125 转为 二进制 为 0.001 使用乘2取整法&#xff0c;一直乘到没有小数 2、二进制 转 十进制 2.1、二进制1010111 转换为 十进制 2.2、 二进制小数0.001 转 十进制 3、循环队列 计算长度通用…

周赛341(模拟、双指针、树上DP)

文章目录周赛341[6376. 一最多的行](https://leetcode.cn/problems/row-with-maximum-ones/)暴力模拟[6350. 找出可整除性得分最大的整数](https://leetcode.cn/problems/find-the-maximum-divisibility-score/)暴力模拟[6375. 构造有效字符串的最少插入数](https://leetcode.c…

JVM系统优化实践(15):GC可视化工具实践

您好&#xff0c;我是湘王&#xff0c;这是我的CSDN博客&#xff0c;欢迎您来&#xff0c;欢迎您再来&#xff5e; 线上系统的JVM监测要么使用jstat、jmap、jhat等工具查看JVM状态&#xff0c;或者使用监控系统&#xff0c;如Zabbix、Prometheus、Open-FaIcon、Ganglia等。作为…

pyg的NeighborLoader和LinkNeighborLoader

NeighborLoader 1 数据格式要求 需要传入加载的属性值&#xff1a; class NeighborLoader(data: Union[Data, HeteroData, Tuple[FeatureStore, GraphStore]], num_neighbors: Union[List[int], Dict[Tuple[str, str, str], List[int]]], input_nodes: Union[Tensor, None…

进程调度的基本过程

进程调度的基本过程&#x1f50e; 进程是什么&#x1f50e; 进程管理&#x1f50e; 进程中结构体的属性进程标识符(PID)内存指针文件描述符表结构体中与进程调度相关的属性进程的状态进程的优先级进程的上下文进程的记账信息&#x1f50e; 总结&#x1f50e; 结尾&#x1f50e;…

(第十四届蓝桥真题) 整数删除(线段树+二分)

样例输入&#xff1a; 5 3 1 4 2 8 7 样例输出&#xff1a; 17 分析&#xff1a;这道题我想的比较复杂&#xff0c;不过复杂度还是够用的&#xff0c;我是用线段树二分来做的。 我们用线段树维护所有位置的最小值&#xff0c;那么我们每次删除一个数之前先求一遍最小值&a…

停车场管理系统文件录入(C++版)

❤️作者主页&#xff1a;微凉秋意 ✅作者简介&#xff1a;后端领域优质创作者&#x1f3c6;&#xff0c;CSDN内容合伙人&#x1f3c6;&#xff0c;阿里云专家博主&#x1f3c6; 文章目录一、案例需求描述1.1、汽车信息模块1.2、普通用户模块1.3、管理员用户模块二、案例分析三…

mysql:使用终端操作数据库

登录进入终端&#xff1a; mysql -u root -p 展示数据库 SHOW DATABASES; 创建数据库&#xff1a; CREATE DATABASE IF NOT EXISTS RUNOOB_TEST DEFAULT CHARSET utf8 COLLATE utf8_general_ci; 1. 如果数据库不存在则创建&#xff0c;存在则不创建。 2. 创建RUNOOB_TEST数据库…

ElasticSearch安装、启动、操作及概念简介

ElasticSearch快速入门 文件链接&#xff1a;https://pan.baidu.com/s/15kJtcHY-RAY3wzpJZIn4-w?pwd0k5a 提取码&#xff1a;0k5a 有些软件对于安装路径有一定的要求&#xff0c;例如&#xff1a;路径中不能有空格&#xff0c;不能有中文&#xff0c;不能有特殊符号&#xf…

JUC并发编程之ReentrantLock

1. 非公平锁实现原理 加锁解锁流程 构造器默认实现的是非公平锁 public ReentrantLock() {sync new NonfairSync();}NonfairSync 继承 Sync&#xff0c; Sync 继承 AbstractQueuedSynchronizer 没有竞争时 第一个竞争出现时 Thread-1 执行了 CAS 尝试将state 由 0 改为 1&…

Stable Diffusion免费(三个月)通过阿里云轻松部署服务

温馨提示&#xff1a;划重点&#xff0c;活动入口在这里喔&#xff0c;不要迷路了。 其实我就在AIGC_有没有一种可能&#xff0c;其实你早就在AIGC了&#xff1f;阿里云邀请你&#xff0c;体验一把AIGC级的毕加索、达芬奇、梵高等大师作画的快感。阿里云将提供免费云产品资源&…

如何使用evosuite为指定被测方法生成测试用例

目录 省流版本 准备工作 环境 evosuite获取 检验环境 参数解释 怎样表示被测方法 怎样指向被测类 其他参数 参考 省流版本 java -jar .\target\depd\evosuite-1.1.0.jar -generateTests -Dtarget_method"isLenient()Z" -class com.google.gson.stream.…

Midjourney教程(二)——Prompt基本结构

Midjourney教程——Prompt基本结构 Basic Prompt 基础版本的prompt仅仅包含图片的描述&#xff0c;能够满足普通的需求&#xff0c;如下图所示 Advanced Prompt 高级版本的prompt主要包含三个部分&#xff0c;如下图所示 Image Prompts(可选) prompt第一部分是Image&#x…

TCP/IP协议详解

一.引言TCP/IP 是 TCP 和 IP 两种协议群的统称&#xff0c;具体来说&#xff0c;IP 或 ICMP、TCP 或 UDP、TELNET 或 FTP、以及 HTTP 等都属于 TCP/IP 协议二.计算机网络体系结构分层计算机网络体系结构分层计算机网络体系结构分层不难看出&#xff0c;TCP/IP 与 OSI 在分层模块…

【C语言】迷宫问题

【C语言】迷宫问题一. 题目描述二. 思想2.1 算法---回溯算法2.2 思路分析图解三. 代码实现3.1 二维数组的实现3.2 上下左右四个方向的判断3.4 用栈记录坐标的实现3.5 完整代码四. 总结一. 题目描述 牛客网链接&#xff1a;https://www.nowcoder.com/questionTerminal/cf2490605…

STM32看门狗

目录 独立看门狗 IWDG 什么是看门狗&#xff1f; 独立看门狗本质 独立看门狗框图 独立看门狗时钟 分频系数算法&#xff1a; ​编辑 重装载寄存器 键寄存器 溢出时间计算公式 独立看门狗实验 需求&#xff1a; 硬件接线&#xff1a; 溢出时间计算&#xff1…

macOS设置环境变量和别名

因为我的mac所用shell是bash&#xff0c;所以本文中涉及的环境变量和别名配置均在~/.zshrc文件中,且在每次配置完成后&#xff0c;需要执行source ~/.zshrc命令使配置文件生效 环境变量 通过配置环境变量&#xff0c;我们可以将某个路径暴露到全局&#xff0c;这样可以在全局…

周总结(第一周)

3月份3个星期 *** 三个星代表不会 ** 再做 * 加强 题目1-完全二叉树(记忆) 考察数据结构 完全二叉树的深度deplog2(N1)1 完全二叉树节点的深度depiceil(log2(i1))向上舍入 完全二叉树的层次遍历&#xff0c;遍历每层的二叉树计算基础每层的总和&#xff0c;然后找出最大的和…

Talk预告 | 新加坡国立大学郑奘巍 AAAI‘23 杰出论文:大批量学习算法加速推荐系统训练

本期为TechBeat人工智能社区第486期线上Talk&#xff01; 北京时间3月30日(周四)20:00&#xff0c;新加坡国立大学二年级博士生——郑奘巍的Talk将准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “大批量学习算法加速推荐系统训练”&#xff0c;届时将分…