解析Chrome 渲染器中的 RCE 漏洞 CVE-2024-3833原理

397 阅读6分钟

CVE-2024-3833 是 Chrome V8 引擎中的一个对象属性重复漏洞。简单来说,这个漏洞允许在 JavaScript 对象中创建具有相同名称的两个属性。虽然听起来不起眼,但攻击者可以利用这个漏洞,实现在 Chrome 渲染进程的沙箱中执行任意代码,也就是 RCE (Remote Code Execution)。

(完整的教程详见:github.blog/security/vu…

实际场景

想象一下你正在浏览一个恶意网站。这个网站包含一些特殊的 JavaScript 代码,这些代码利用了 CVE-2024-3833 漏洞。当你的 Chrome 浏览器尝试渲染这个网页时,恶意代码会偷偷地在 V8 引擎中制造一个“陷阱”,最终导致你的电脑执行攻击者预设的指令。

技术细节

要理解这个漏洞,需要了解一些 V8 引擎的工作原理:

  1. Origin Trials (原始试验):Chrome 允许开发者在正式发布前,通过 "Origin Trials" 试用一些新功能。开发者需要注册他们的网站,获得一个 "token",并通过 <meta> 标签添加到网页中。

  2. 漏洞成因:漏洞的产生,源于 Chrome 在启用 "Origin Trials" 功能时,没有充分检查是否已经有 JavaScript 代码运行。恶意代码可以先于 "Origin Trials" 启用,并在 V8 引擎中创建一些预设的属性。当 "Origin Trials" 尝试创建同名属性时,就会产生冲突,导致 V8 引擎内部数据结构损坏。

  3. 重复属性:在 V8 引擎中,对象的属性通常存储在一个数组中。当尝试添加一个已存在的属性时,正常情况下会更新已存在属性的值。但是,利用此漏洞,可以在数组中创建两个具有相同名称的属性,指向不同的内存地址。

  4. 类型混淆:V8 引擎会根据对象的 "map" (可以理解为对象的类型信息) 来优化属性的访问。当对象中存在重复属性时,会导致 "map" 信息混乱,V8 引擎可能会错误地将一个对象按照另外一种类型来解释,从而允许读写不应该访问的内存区域。

  5. 攻击步骤

    • 创建重复属性:通过一些技巧,在 JavaScript 对象中创建重复的属性。
    • 触发类型混淆:利用 V8 引擎的优化机制,触发类型混淆。
    • 越界读写 (OOB):通过类型混淆,实现对内存的越界读取和写入。
    • 代码执行:通过修改内存中的 WebAssembly 函数的跳转目标,让 CPU 执行攻击者预先准备好的 Shellcode,从而实现 RCE。

代码演示

下面的代码演示了如何利用 "Origin Trials" 和 WebAssembly 创建重复属性(请勿在生产环境或者不安全的环境中运行此代码):

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Origin-Trial" content="YOUR_ORIGIN_TRIAL_TOKEN">
    <script>
        // Step 1: 创建一个 WebAssembly 对象
        WebAssembly.Exception = 1.1;

        // Step 2: 启用 Origin Trial (需要有效的 token)
        //  Origin Trial 功能会尝试再次创建 WebAssembly.Exception 属性

        // Step 3: 此时,WebAssembly.Exception 拥有重复的属性
        console.log(WebAssembly.Exception);
    </script>
</head>
<body>
    <h1>CVE-2024-3833 Demo</h1>
</body>
</html>

请注意

  • 你需要一个有效的 "Origin Trial token" 才能运行此代码。
  • 此代码只是演示了如何创建重复属性,并不能直接实现 RCE。 完整的 RCE 利用需要更多复杂的步骤,想要深入学习的同学可以继续看下面内容。

漏洞利用完整流程

  1. 创建具有重复属性的快速对象

    • 正如前面提到的,我们需要创建一个具有重复属性的 JavaScript 对象。由于 Chrome 的安全补丁,直接创建快速对象已经不可能。
    • 因此,需要先创建一个具有重复属性的字典对象,然后将其转换为快速对象。
    var x = WebAssembly.Tag.prototype;
    x.type = {};
    // 删除属性,导致对象变成字典对象
    delete x.constructor;
    // 触发漏洞,创建重复的 type 属性
    // ... (需要 Origin Trial token 和相关代码) ...
    
  2. 将字典对象转换为快速对象

    • 通过原型链访问,可以触发 MakePrototypesFast 函数,将字典对象转换为快速对象。
    var y = {};
    // 设置 x 为 y 的原型
    y.__proto__ = x;
    // 访问 y 的属性,触发 MakePrototypesFast
    y.a = 1;
    z = y.a;
    
  3. 触发 PropertyArray 的 OOB 写入

    • 克隆具有重复属性的快速对象,导致 PropertyArraymap 之间的不一致。
    • 向对象添加新属性,触发 JIT 优化,实现 PropertyArray 的 OOB 写入。
    const clonedObj = { ...obj1 };
    
  4. 控制 Array 的 length 属性

    • 利用 OOB 写入,覆盖相邻 Array 对象的 length 属性,实现对该 Array 对象的越界访问。
    // 假设 corrupted_arr 是越界访问的 Array 对象
    corrupted_arr[index] = value; // 越界写入
    
  5. 实现任意地址读写

    • 通过越界 Array 对象,读取 V8 堆中其他对象的地址。
    • 修改 Array 对象中的字段,实现对任意地址的读写。
  6. 绕过 V8 堆沙箱

    • V8 堆沙箱将 V8 堆与其他进程内存隔离,防止直接执行代码。
    • 通过修改 WebAssembly 导入函数的跳转目标,实现代码执行。
    // 创建 WebAssembly 实例
    const importObject = {
      imports: {
        imported_func(arg) {
          console.log(arg);
        },
      },
    };
    var mod = new WebAssembly.Module(wasmBuffer);
    const instance = new WebAssembly.Instance(mod, importObject);
    
    // 修改 imported_func 的跳转目标为 shellcode 地址
    // ...
    
    // 调用 WebAssembly 函数,执行 shellcode
    instance.exports.exported_func();
    

代码示例补充说明

  • 以上代码示例仅为演示漏洞利用的思路,实际利用过程需要更精细的内存布局控制和 JIT 代码分析。
  • YOUR_ORIGIN_TRIAL_TOKEN 需要替换为有效的 Origin Trial Token。
  • wasmBuffer 需要替换为有效的 WebAssembly 代码。
  • 具体的 shellcode 注入和执行方式,需要根据目标环境和 V8 版本进行调整。

总结

通过以上步骤,攻击者可以利用 CVE-2024-3833 漏洞,最终实现 Chrome 渲染进程中的 RCE。 漏洞利用链条比较长,需要多个步骤的配合,但每个步骤都依赖于对 V8 引擎内部机制的深入理解。

希望这个补充完整的教程能够帮助你更好地理解 CVE-2024-3833 漏洞的原理和利用方式。 及时更新浏览器版本,可以有效防御此类漏洞攻击。

漏洞修复

Chrome 已经发布了新版本 (124.0.6367.60/.61) 修复了 CVE-2024-3833 漏洞。请及时更新你的 Chrome 浏览器,以避免受到攻击。

总结

CVE-2024-3833 是一个比较底层的 V8 引擎漏洞,利用起来有一定难度。但是,一旦攻击者成功利用此漏洞,就可以完全控制用户的 Chrome 浏览器,造成严重的安全威胁。通过了解这个漏洞的原理和利用方式,我们可以更好地保护自己的电脑安全。