CVE-2021-21220 漏洞利用
从错误的 JIT 行为到远程代码执行
概述
本演示文稿解释了 CVE-2021-21220 的利用过程,这是 Google Chrome 的 V8 JavaScript 引擎 中的一个漏洞,由 JIT 编译器在优化过程中的错误假设引起。
演示涵盖以下内容:
- V8 如何执行即时(JIT)编译
- 优化过程中如何出现有符号/无符号类型混淆错误
- 该错误如何导致越界(OOB)数组原语
- 攻击者如何利用 OOB 访问泄露地址并实现任意内存写入
- WebAssembly(Wasm)如何成为本机代码执行的目标
- 现有的缓解措施和现代浏览器防御
演示目标
本演示的目标是展示现代 JavaScript 引擎中一个细微的优化错误如何逐步升级为:
- 内存破坏
- 任意读取/写入原语
- 本机代码修改
- 潜在的远程代码执行(RCE)
该利用链突显了 JIT 引擎如何在性能与安全性之间进行平衡,以及错误的优化假设如何变得可被利用。
涵盖的主题
1. V8 架构
演示介绍了 V8 的主要组件:
Ignition 解释器
- 执行 JavaScript 字节码
- 收集运行时反馈
- 在反馈向量中存储类型信息
TurboFan 优化器
- 根据运行时反馈构建优化图
- 插入推测性假设和保护检查
- 执行激进的优化遍历
机器码后端
- 生成本机 CPU 指令
- 为“热”函数生成优化的机器码
演示中的架构图说明了 JavaScript 如何从:
2. 为什么 JavaScript 难以优化
JavaScript 难以实现高性能执行,原因是:
- 变量动态改变类型
- 数组改变结构和元素类型
- 像
+ 这样的运算符可能有多种含义
- 运行时检查代价高昂
V8 使用 JIT 编译通过推测运行时行为来优化常见的执行模式。
3. CVE-2021-21220 的根本原因
该漏洞源于 JIT 优化过程中的 有符号与无符号整数不匹配。
演示的关键概念包括:
Uint32Array
Word32Xor
- 错误的类型传播
ChangeInt32ToInt64
- 错误的汇编指令选择
该利用滥用了以下值:
该值设置了 32 位整数的符号位。
4. 优化不匹配
漏洞发生的原因是 TurboFan 优化了:
将其完全消除。
在此优化过程中:
- XOR 操作消失
- 类型信息丢失
- 有符号值被解释为无符号
- JIT 行为与解释器行为发生偏差
这导致生成错误的机器码以及攻击者可控制的值。
5. 构建 OOB 原语
该利用将错误的 JIT 结果转换为对数组行为的控制。
演示展示了:
- 错误的优化整数值
- 转换为控制变量
i
- 热身执行与触发执行之间的不匹配
Array.shift() 长度下溢
- 创建一个具备越界能力的数组
重要的利用概念包括:
6. 越界访问
一旦数组长度变为 -1,攻击者便可获得:
然后演示展示了:
- 指针泄露
- 对象地址发现
- 数组重叠
- 原始 V8 指针提取
7. WebAssembly 滥用
演示解释了攻击者如何针对:
- WebAssembly 编译的代码页
- V8 生成的本机可执行内存
攻击流程:
- 创建一个 Wasm 函数
- 定位可执行内存
- 覆盖已编译的机器码
- 重新执行 Wasm
- 实现任意本机执行
这展示了 JavaScript 引擎漏洞如何过渡到进程级代码执行。
防御措施与缓解策略
最后一部分涵盖现代浏览器防御:
压缩指针
减少直接指针暴露和堆的可预测性。
指针间接引用
防止直接访问原始内存地址。
堆沙箱
隔离内存区域并降低利用影响。
W^X(写入异或执行)
防止页面同时可写和可执行。
演示还包含了 V8 补丁差异,展示了针对符号扩展问题的修复。
关键要点
本演示展示了如何:
- 微小的优化错误可能变成关键漏洞
- JIT 编译器显著增加了攻击面的复杂性
- 运行时推测可能引入危险的不一致性
- WebAssembly 改变了利用的格局
- 现代浏览器需要多层防御
讨论的技术
- JavaScript
- Google V8 引擎
- TurboFan
- Ignition
- WebAssembly(Wasm)
- JIT 编译
- 内存破坏
- 越界访问
- 浏览器漏洞利用
教育目的
本材料严格用于:
请勿将此信息用于针对您不拥有或未经许可进行测试的系统。
参考