【bsauce读论文】2024-NDSS-K-LEAK:Linux内核infoleak利用自动生成
基本信息
- 原文标题:K-LEAK: Towards Automating the Generation of Multi-Step Infoleak Exploits against the Linux Kernel
- 原文作者:Zhengchuan Liang, Xiaochen Zou, Chengyu Song, Zhiyun Qian
- 作者单位:加州大学河滨分校(UC Riverside)
- 关键词:信息泄露, Linux内核, 自动化, 安全漏洞
- 原文链接:DOI link
- 开源代码:GitHub link
1. 论文要点
论文简介:K-LEAK工具是一种基于图的数据流分析框架,针对Linux内核中的内存漏洞(UAF/OOB),辅助生成infoleak的利用,绕过内核KASLR防护。本文将infoleak利用生成问题看作是数据流搜索问题,通过对内存错误引入的非预期数据流,以及现有内存错误如何转化为新的内存错误进行建模,K-LEAK能够系统性的搜索出多步infoleak数据流路径。
特点:
- (1)统一处理预期和非预期数据流片段,将内核敏感信息连接到泄露点(eg, copy_to_user());
- (2)支持跨syscall边界的推理;
- (3)允许在发现最终的信息泄露之前推理中间原语(也即新的内存错误)。
测试:测试了250个由syzbot fuzz出来的Linux内核内存漏洞,找到40个漏洞的infoleak路径,为20个漏洞生成EXP。
2. Introduction
主要介绍数据流分析和points-to分析。
DFG问题:当前的DFG图没有考虑内存错误,作者引入了M-DFG(Memory-error-augmented data-flow graph),能捕获内核中预期和非预期的数据流,其中node表示程序点,edge表示预期和非预期的数据流。可以通过M-DFG来搜索infoleak路径和能获得新内存错误的可控寄存器。
Points-to分析很难用于Linux内核的原因:Linux有一个特性,multi-interaction[13],也即多个程序入口,用户程序可以调用多个syscall和内核交互,多个syscall可通过共享内存来传播数据流。这会给infoleak路径搜索带来一个问题,敏感信息的数据流可能会跨多个syscall,例如在syscall A中将敏感信息存入全局内存,在syscall B中读取敏感信息并传播到泄露点,导致搜索空间变大。
本文思路:本文的points-to分析采用了SUTURE,数据流分析采用的是M-DFG。SUTURE[51]解决了multi-interaction问题,它对每个syscall入口单独进行points-to分析和数据流分析,对每个syscall生成points-to总结和数据流总结。两种分析都是inter-procedural flow-, context-, field-sensitive。在points-to分析中,它对每个入口创建抽象内存对象,使用访问路径来确定内存对象的别名(例如,A入口中的内存对象o1和B入口的内存对象o2是别名);在数据流分析中(主要采用污点分析),在获得所有入口的data-flow总结后,就会连接不同入口的数据流,构成跨syscall的数据流。
3. 研究内容
挑战:
- (1)对内存错误带来的非预期数据流进行建模。内存错误的本质是错误指针的引用(指针越界或指向空闲/未初始化内存),会导致load读和store写操作之间新的数据流。也就是说,错误指针会导致load和store指针的非预期的别名。需设计针对错误指针的别名分析。
- (2)对跨syscall数据流进行建模。非预期的跨syscall数据流是指,某syscall利用内存错误,非预期的读或写另一个syscall使用的内存。
- (3)对额外内存错误进行建模。内存错误有时需要转化后才能实现infoleak,例如elastic对象。本文实现迭代搜索算法,不仅搜索infoleak路径,还搜索攻击者可控的指针,并检查通过可控指针是否能获得新的内存错误。
工作过程:方框表示分析组件,椭圆表示输入/输出数据。内核源码编译为LLVM中间码,经过points-to分析构建M-DFG图,引入初始内存错误后扩展为M-DFG,通过迭代搜索来搜索infoleak路径和攻击者可控的指针,如果发现新的内存错误,就根据该信息扩展出新的M-DFG进行迭代。
案例分析:参加Listing 2 代码图。
- UAF读:12行处存在UAF读,
ax25_dev *ax25_dev
指向已被释放的对象,读取的值被存入ax25_cb *ax25
对象中; - 堆喷占用:为了泄露信息,需先堆喷
struct usb_bus
对象占据空闲的ax25_cb
对象,往漏洞对象写敏感数据(ubus
指针,17行); - 泄露:28行会将
ubus
指针赋给另一变量,29行泄露出来。
M-DFG示例:水平线表示infoleak路径,包含3段,对应3个syscall入口。虚线是pointer edge
(地址的存储与载入),实线是data edge
(数据的存储与载入)。
mon_bus_init()
——17行,store
点将敏感指针存入struct mon_bus
对象;ax25_setsockopt()
——12行,从地址&ax25_dev->values[N2]
读取,由于&mbus->u_bus
和&ax25_dev->values[N2]
别名(重分配导致内存重叠),所以引入红色箭头(由UAF内存错误导致的非预期边),连接上一次的store和本次load,也称为写后读依赖(read-after-write data edge
);ax25_getsockopt()
——28行,临时寄存器值保存到栈地址valptr=&val
,copy_to_user
将valptr
地址的内容拷贝到用户空间。
所以说,M-DFG引入了内存错误带来的数据流边(read-after-write data edge
),这样ax25_cb
和struct mon_bus
就因为UAF而形成别名。总目标就是,找到一条从敏感信息到泄露点的infoleak路径。
3-1. M-DFG
生成原理:基于两个信息生成,(1)LLVM的SSA静态单赋值,(2)SUTURE[51]的指向分析结果。
M-DFG包含三类node:variable node
/ load node
/ store load
M-DFG包含两类edge:针对不同的指令(BinOp / ConOp / Phi / Call / Load / Store)分别进行分析,确定添加哪种边。copy_to_user()
当作一类特殊的load/store指令。如果store的指针和load的指针是别名,则添加一条data edge
。不处理栈上的,栈指针和栈帧指针。
data edge
—— 直接数据流传递,实心边;pointer edge
—— 特殊的数据流边,只针对store
/load
指令,虚线边。
3-2. M-DFG搜索
M-DFG优势:
- (1)对比SUTURE[51]:SUTURE使用污点分析来解决数据依赖问题,创建污点总结(污点source到污点sink),这种数据结构不高效、占用内存大;
- (2)对比SVF:SVF使用变量节点来表示顶层变量和内存节点,M-DFG去掉内存节点并引入load/store节点和
pointer edge
,M-DFG可以用stored_value->store_node->load_node->loaded_value
来表示read-after-write
,类似于stored_value->memory_node->loaded_value
,但M-DFG的优势是能够解释如何构造新的内存错误,因为M-DFG比普通DFG多了一个pointer edge
(新的内存错误,表示攻击者是否可通过一个pointer edge
来控制一个load/store节点)。
搜索infoleak路径:找到从敏感信息(内核指针,也即函数指针、数据指针,keys,network&IPC消息)到泄露点(见Table III)的路径。并使用SyzScope[54]中的符号执行引擎来验证路径可达性。
搜索新内存错误:等效于搜索一条路径,从用户可控的数据节点(copy_from_user()
)到指针变量节点,该指针稍后会被load/store使用。如果存在该数据流路径,且指针变量可指向非预期内存位置,则表示可构造新内存错误。
迭代搜索:每次迭代,先用新内存错误来扩展M-DFG,然后搜索infoleak路径和新内存错误,新找到的内存错误添加到下一轮迭代。
可利用性验证:为了简化验证,本文假设堆喷成功,利用gdb将敏感信息写入待读的地址。例如,本来需堆喷mbus
占据ax25_dev
对象,现在使用GDB将mbus->ubus
指针写入load指令(也即tmp = mbus->u_bus
)。如果能通过测试用例泄露敏感信息,则可利用。
4. 实现
总体采用静态分析和符号执行实现,组件包含 M-DFG builder
和 Graph Searcher
。 采用Syzscope[54]来获得初始的内存错误;M-DFG builder
是基于SUTURE实现;Graph Searcher
中,采用BFS来搜索infoleak路径和新的内存错误,采用Angr符号执行来验证路径可达性。
5. 实验
对syzbot上的250个UAF/OOB漏洞进行测试,能够找到40个infoleak路径,生成21个EXP。
文档信息
- 本文作者:bsauce
- 本文链接:https://bsauce.github.io/2024/05/18/K-LEAK/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)