议题解读:How I use a novel approach to exploit a limited OOB on Ubuntu at Pwn2Own Vancouver 2024
字数 2318 2025-08-20 18:17:41
Linux内核栈缓冲区越界写漏洞利用技术深度解析
漏洞概述
本议题介绍了一种针对Linux内核栈缓冲区越界写漏洞的新型利用技术,该漏洞在Pwn2Own Vancouver 2024比赛中被成功利用。漏洞存在于Linux内核网络调度器中的nla_parse_nested函数,允许攻击者通过精心构造的用户态数据实现内核栈越界写,最终通过结合内核栈分配机制和eBPF技术实现任意地址写,修改modprobe_path完成提权。
漏洞详细分析
漏洞代码位置
漏洞位于内核处理TAPRIO队列调度器的代码中,具体在解析嵌套netlink属性时的类型处理不当:
struct nla_policy taprio_tc_policy[TCA_TAPRIO_TC_ENTRY_MAX + 1] = {
[TCA_TAPRIO_TC_ENTRY_INDEX] = { .type = NLA_U32 },
[TCA_TAPRIO_TC_ENTRY_MAX_SDU] = { .type = NLA_U32 },
[TCA_TAPRIO_TC_ENTRY_FP] = NLA_POLICY_RANGE(NLA_U32, TC_FP_EXPRESS, TC_FP_PREEMPTIBLE),
};
漏洞成因
-
类型转换问题:
nla_get_u32获取TCA_TAPRIO_TC_ENTRY_INDEX返回u32类型- 但接收变量
tc是int类型 - 通过提供很大的
TCA_TAPRIO_TC_ENTRY_INDEX值可使tc变为负数
-
越界访问:
- 绕过后续的
tc范围检查 - 写入
max_sdu和fp数组时使用负数索引导致向前越界写栈内存 max_sdu和fp是内核栈上的数组:u32 max_sdu[TC_QOPT_MAX_QUEUE]和u32 fp[TC_QOPT_MAX_QUEUE]
- 绕过后续的
漏洞补丁
补丁通过限制TCA_TAPRIO_TC_ENTRY_INDEX的最大值来修复:
[TCA_TAPRIO_TC_ENTRY_INDEX] = NLA_POLICY_MAX(NLA_U32, TC_QOPT_MAX_QUEUE),
漏洞利用原语分析
漏洞提供的原始利用能力有限:
-
写入大小限制:
- 最大只能写入
0xffff(u32类型) max_sdu写入的值需要小于dev->max_mtu
- 最大只能写入
-
写入值限制:
fp写入的值受taprio_tc_policy约束,只能为1或2
-
利用难度:
- 难以部分修改栈上的指针(修改后偏移太大难以控制)
- 常规的栈越界写利用策略难以奏效
内核内存布局机制
VMALLOC区域特性
-
内存分配:
- Linux内核进程栈在VMALLOC区域分配
- vmalloc接口也在此区域分配内存
- 不同进程的栈内存、vmalloc堆内存相邻
-
保护机制:
- 默认分配时会在内存后添加不可访问的guard page防止溢出
- 但OOB(越界)写入不受此保护影响
VMALLOC分配/释放机制
-
地址空间:
- 虚拟地址空间
[VMALLOC_START, VMALLOC_END] - 用于分配虚拟地址连续但物理地址不一定连续的内存
- 虚拟地址空间
-
管理结构:
- 已分配的虚拟地址空间用
vm_area结构体表示 - 通过链表和红黑树组织
- 已分配的虚拟地址空间用
-
分配过程:
- 从低地址向高地址遍历
vm_area搜索空闲区间 - 类似于ptmalloc中的unsorted bin分配机制
- 通过
alloc_page向伙伴系统逐页申请物理内存
- 从低地址向高地址遍历
-
释放过程:
- 物理地址释放回伙伴系统
- 虚拟地址空间标记为
unpurged vm_area - 当所有
unpurged vm_area页面数超过阈值(约40000页)时才回收 - 回收前对应的虚拟地址不可被申请
利用技术演进
传统利用方法及其限制
-
修改其他进程内核栈:
- 类似SVE-2020-18610的利用策略
- 修改
do_select栈内存实现栈溢出和ROP
-
防护机制:
CONFIG_RANDOMIZE_KSTACK_OFFSET引入栈布局随机性- 导致偏移无法确定,阻止此类利用
新型利用技术
-
VMALLOC区域目标选择:
- 除了内核栈外,VMALLOC还包含:
- Android Mali GPU驱动管理结构
- eBPF字节码等
- 除了内核栈外,VMALLOC还包含:
-
历史案例参考:
- CVE-2021-33909:通过vmalloc越界写修改eBPF字节码
-
eBPF利用现状:
- 低权限进程无法直接使用eBPF(因易被用于恶意软件)
- 但可通过
setsockopt创建eBPF字节码(参考CVE-2023-3609)
完整利用链构建
eBPF处理流程
-
校验阶段:
- 首先校验字节码的合法性
- 校验通过后将filter字节码转换为eBPF字节码
-
JIT编译:
- 将eBPF字节码进行即时编译
漏洞利用关键点
-
时机选择:
- 在校验通过后、JIT编译前篡改eBPF字节码
- 注入恶意eBPF指令实现任意地址写
-
指令注入:
- 篡改注入
BPF_STX_MEM指令 - 用于实现任意地址写
- 篡改注入
-
最终目标:
- 修改
modprobe_path实现提权
- 修改
利用过程中的挑战与解决方案
-
地址泄露问题:
- 利用CVE-2024-26816泄露内核镜像基地址
-
内存布局不稳定:
- 大量进程创建/销毁导致内存布局变化
- 解决方案:通过
SIGSTOP暂停部分进程减少系统行为
-
竞争条件:
- 需要在eBPF字节码生成到JIT之间触发漏洞
- 解决方案:增加bpf指令数目以延长时间窗口
相关漏洞案例
-
vmalloc区域漏洞利用:
- ioremap越界写修改内核栈:Pwn2Own 2023 Tesla, CVE-2022-21765
- ION Buffer OOB漏洞:SVE-2020-18610
-
利用策略通用性:
- 通过RACE在eBPF生成过程中篡改指令的技术
- 可应用于其他vmalloc相关漏洞利用场景
总结与启示
-
技术要点:
- 结合内核栈分配机制和eBPF实现有限OOB到任意地址写
- 利用VMALLOC区域特性绕过常规防护
- 精确控制漏洞触发时机实现稳定利用
-
防护建议:
- 加强类型转换检查
- 增强VMALLOC区域隔离
- 缩短eBPF校验到JIT的时间窗口
- 监控
modprobe_path等关键数据修改
-
研究价值:
- 为受限原语的利用提供新思路
- 展示内核子系统间交互的安全影响
- 推动更精细的内核内存防护机制发展