Google CTF 2023 - v8box
字数 1419 2025-08-29 22:41:10
Google CTF 2023 - v8box 漏洞分析与利用教学文档
环境搭建
- 根据提供的
build.dockerfile在本地编译环境 - 修改
args.gn文件内容,使用以下编译选项:- 关闭了 JIT、Maglev、TurboFan 和 WebAssembly
- 开启了
v8_expose_memory_corruption_api选项
关键API分析
内存操作API
位于 src/sandbox/testing.cc 的 API 提供了对沙箱内空间的直接操作能力,相当于提供了 OOB(越界)原语。
在新版本 V8 (12.x 以上)中:
- 编译选项变为
V8_ENABLE_MEMORY_CORRUPTION_API - 新增了一些方法
- 开启了
v8_code_pointer_sandboxing保护机制
代码指针沙箱化保护
- 目的:防止通过修改函数指针控制 RIP
- 实现方式:
- 可执行函数指针有固定入口(code pointer table)
- 通过偏移索引对应代码
漏洞分析
Patch 分析
-
v8.patch:- 关闭了一些 d8 选项以使编译更轻量化
-
0001-Protect-chunk-headers-on-the-heap.patch:- 新增了三个方法:
ProtectSpace:修改指定地址段的权限(使用mprotect)SetWritable:将地址空间设为 RW 权限- 对 young generation 且未被 GC 处理的内存:设置 from space 和 to space 为 RW
- 对 old generation:直接调用
ProtectSpace
SetReadOnly:结构与SetWritable相同,设为只读
- 新增了三个方法:
条件竞争问题:
- 使用
nesting level变量约束 - 多线程情况下会出现问题(非预期解法)
Ignition 解释器漏洞
- Ignition 是 V8 的字节码解释器
- 即使关闭 Maglev/JIT,仍可工作
- 漏洞点:
Ldar和Star操作码缺乏边界检查- 允许修改字节码数组内容实现任意指令执行
Ldar 指令分析
- 功能:从栈上读取值
- 汇编实现:
r12:字节码数组基址r9:索引- 返回值
rax由rbx赋值 rbx通过rdx+rbx索引得到rdx由rbp赋值
效果:可以泄漏栈上低 32 位值(由于指针压缩)
- 注意:SMI 类型会右移 1 位(需要乘以 2 恢复)
Star 指令分析
- 功能:将值写入栈上
- 汇编实现:
- 将
rax(上一次执行的返回值)写入栈上 - 通过
rbp+0x0处的值被修改为rax寄存器值
- 将
利用思路
现有能力
- 泄漏栈上低 4 字节数据
- 栈上 8 字节数据写
控制流劫持
-
通过多次执行
leave指令实现栈迁移- 修改字节数组控制执行流程
- 劫持控制流
-
获取 gadget:
- 从栈上可以找到位于 d8 的代码片段
- 地址随机化特点:
- 低 4 字节变化很小/基本不变
- 泄漏 d8 基地址:
- 从堆块开头读取高位字节(仍有读权限)
- 拼接低 4 字节
- 减去尾部偏移得到 d8 基地址
-
ROP 链构造:
- 使用获取的 gadget 构造 ROP 链
- 实现提权