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

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

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

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

工具目录

分类

查看所有分类
Loading categories
工具/GitHubGitHub/googleprojectzero/fuzzilli
漏洞分析模糊测试二进制分析论文与研究学习与教育
GitHubgoogleprojectzero/fuzzilli

fuzzilli

一个 JavaScript 引擎模糊测试器

查看仓库
2.3k366556天前Kitploit 审核通过

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Fuzzilli

一个基于自定义中间语言("FuzzIL")的(基于覆盖率的)动态语言解释器引导式模糊测试器,该中间语言可以被变异并翻译成JavaScript。

使用方法

使用此模糊测试器的基本步骤如下:

  1. 下载其中一个受支持的JavaScript引擎的源代码。参见 Targets/ 目录,了解受支持的JavaScript引擎列表。
  2. 应用目标目录中相应的补丁。同时请阅读该目录中的 README.md。
  3. 使用覆盖率检测编译引擎(需要 clang >= 4.0),如 README 中所述。
  4. 编译模糊测试器:swift build [-c release]。
  5. 运行模糊测试器:swift run [-c release] FuzzilliCli --profile=<profile> [other cli options] /path/to/jsshell。另请参阅 swift run FuzzilliCli --help。

在Docker和Google Compute Engine中构建和运行Fuzzilli及受支持的JavaScript引擎也是支持的。

开发

查看 main.swift 以了解Fuzzilli库的使用示例,并尝试各种配置选项。接下来,查看 Fuzzer.swift 以了解高级的模糊测试逻辑。然后可以深入研究任何看起来有趣的部分。

非常欢迎对此项目的补丁、添加和其他贡献!不过,请先快速查看 贡献者须知。Fuzzilli 大致遵循 Google 的 Swift 代码风格指南。

如果您通过此项目发现了任何漏洞,能通过 [email protected] 发送简短说明(可能包括 CVE 编号)或开启一个拉取请求,以便将其包含在漏洞展示部分,将不胜感激。除此之外,您当然可以保留任何漏洞赏金、CVE 积分等。

概念

在模糊测试核心解释器漏洞(例如 JIT 编译器中的漏洞)时,生成程序的语义正确性成为一个关注点。这与大多数其他情况(例如模糊测试运行时API)不同,在后一种情况下,可以通过将生成的代码包裹在 try-catch 构造中来轻松处理语义正确性问题。有几种不同的方法可以实现可接受的语义正确样本比例,其中一种是基于变异的策略,即语料库中的所有样本也是语义有效的。在这种情况下,每次变异只有很小的机会将有效样本变成无效样本。

为了实现基于变异的JavaScript模糊测试器,需要定义对JavaScript代码的变异。不是对程序的AST或其他语法元素进行变异,而是定义一种自定义中间语言(IL),在该语言上可以更直接地进行程序控制流和数据流的变异。然后,该中间语言被翻译成JavaScript以执行。中间语言大致如下所示:

root@kitploit:~
v0 <− LoadInteger '0'
v1 <− LoadInteger '10'
v2 <− LoadInteger '1'
v3 <− LoadInteger '0'
BeginFor v0, '<', v1, '+', v2 −> v4
   v6 <− BinaryOperation v3, '+', v4
   Reassign v3, v6
EndFor
v7 <− LoadString 'Result: '
v8 <− BinaryOperation v7, '+', v3
v9 <− LoadGlobal 'console'
v10 <− CallMethod v9, 'log', [v8]

例如,可以轻松地翻译成以下JavaScript代码:

root@kitploit:~
const v0 = 0;
const v1 = 10;
const v2 = 1;
let v3 = 0;
for (let v4 = v0; v4 < v1; v4 = v4 + v2) {
    const v6 = v3 + v4;
    v3 = v6;
}
const v7 = "Result: ";
const v8 = v7 + v3;
const v9 = console;
const v10 = v9.log(v8);

或者通过内联中间表达式,翻译成以下JavaScript代码:

root@kitploit:~
let v3 = 0;
for (let v4 = 0; v4 < 10; v4++) {
    v3 = v3 + v4;
}
console.log("Result: " + v3);

FuzzIL 具有以下特性:

  • 一个 FuzzIL 程序只是一个指令列表。
  • 一个 FuzzIL 指令是一个操作,以及输入和输出变量,可能还有一个或多个参数(在上面的表示法中,参数用单引号括起来)。
  • 指令的输入始终是变量,没有立即数。
  • 每条指令的输出都是一个新变量,现有变量只能通过专用操作(如 Reassign 指令)重新赋值。
  • 每个变量都在使用前定义。

然后可以对这些程序执行多种变异:

  • InputMutator:将指令的输入变量替换为不同的变量,以改变程序的数据流。
  • CodeGenMutator:生成代码并将其插入到被变异程序中的某个位置。代码通过运行代码生成器或从语料库中另一个程序复制一些指令(拼接)来生成。
  • CombineMutator:将语料库中的一个程序插入到被变异程序中的随机位置。
  • OperationMutator:变异操作的参数,例如将整数常量替换为不同的值。
  • 以及更多...

关于 Fuzzilli 工作原理的更详细讨论,请参见此处。

实现

该模糊测试器使用 Swift 实现,部分功能(如覆盖率测量、套接字交互等)使用 C 实现。

架构

一个模糊测试器实例(实现在 Fuzzer.swift 中)由以下核心组件组成:

  • MutationFuzzer:通过应用变异,从现有程序生成新程序。然后执行生成的样本并评估它们。
  • ScriptRunner:执行目标语言的程序。
  • Corpus:存储有趣的样本,并为核心模糊测试器提供样本。
  • Environment:了解运行时环境,例如可用的内置函数、属性名称和方法。
  • Minimizer:最小化崩溃程序和有趣程序。
  • Evaluator:根据某些度量(例如代码覆盖率)评估样本是否有趣。
  • Lifter:将 FuzzIL 程序翻译成目标语言(JavaScript)。

此外,还有一些可选模块:

  • Statistics:收集各种统计信息。
  • NetworkSync:通过网络同步多个实例。
  • ThreadSync:在同一进程内同步多个实例。
  • Storage:将崩溃程序存储到磁盘。

模糊测试器是事件驱动的,大多数不同类之间的交互通过事件发生。事件例如因崩溃、发现有趣程序、执行新程序、生成日志消息等而分发。事件完整列表请参见 Events.swift。事件机制有效地解耦了模糊测试器的各个组件,并简化了额外模块的实现。

可以使用 ProgramBuilder 实例构建 FuzzIL 程序。ProgramBuilder 提供了创建和追加新指令、从另一个程序追加指令、检索现有变量、查询当前位置的执行上下文(例如是否在循环内部)等方法。

执行

Fuzzilli 使用一种称为 REPRL(读取-求值-打印-重置-循环)的自定义执行模式。为此,目标引擎被修改为通过管道和/或共享内存接受脚本输入,执行脚本,然后重置其内部状态并等待下一个脚本。这消除了进程创建的开销,并在很大程度上消除了引擎初始化的开销。

可扩展性

每个目标进程有一个 Fuzzer 实例。这使得程序能够同步执行,从而简化了各种算法(如连续变异和最小化)的实现。此外,它避免了实现线程安全的内部状态访问(例如语料库)的需要。每个模糊测试器实例都有自己的 DispatchQueue,在概念上对应一个线程。通常,与 Fuzzer 实例的每次交互都必须在该实例的调度队列上进行。这保证了线程安全,因为队列是串行的。更多详情请参见文档。

为了实现扩展,模糊测试器实例可以形成树形层次结构,在这种情况下,它们将新发现的有趣样本和崩溃报告给其父节点。反过来,父节点将其语料库与其子节点同步。树中节点之间的通信可以通过不同的方式进行,每种方式都实现为一个模块:

  • 线程间通信:通过将任务入队到另一个模糊测试器的 DispatchQueue 来同步同一进程中的实例。
  • 机器间通信:通过简单的基于 TCP 的协议同步实例。

这种设计允许模糊测试器在单个机器上扩展到多个核心,以及扩展到多台机器。由于如果太多实例向一个父节点发送程序,该父节点可能会迅速过载,因此可以配置多级实例,例如一个根实例、16个连接到根实例的中间节点,以及256个连接到中间节点的“叶子”节点。关于分布式模糊测试的更多信息,请参见 Cloud/ 目录。

资源

有关本模糊测试器的更多资源:

  • 在 Offensive Con 2019 上关于 Fuzzilli 的演示文稿。
  • 最初实现所用的硕士论文。
  • Sensepost 关于使用 Fuzzilli 在 v8 中发现漏洞的博客文章。
  • Doyensec 关于使用 Fuzzilli 模糊测试 JerryScript 引擎的博客文章。
  • NDSS 2023 研讨会关于 Fuzzilli 及其与其他模糊测试器比较的论文。

漏洞展示

以下是一些借助 Fuzzilli 发现的漏洞列表。只有至少出现在受影响软件 Beta 版本中并具有安全影响的漏洞才应列入此列表。由于 Fuzzilli 通常用于开发期间的持续模糊测试,因此许多由它发现的问题未包含在此列表中,因为它们通常在易受攻击的代码达到 Beta 版本之前就被发现。然而,最近由 Fuzzilli 在 V8 中发现的所有问题列表可以在此处找到。

特别感谢所有使用 Fuzzilli 并报告其所发现漏洞的用户!

WebKit/JavaScriptCore

  • Issue 185328:DFG 编译器为 NumberIsInteger 操作使用了错误的输出寄存器
  • CVE-2018-4299:performProxyCall 将内部对象泄露给脚本
  • CVE-2018-4359:compileMathIC 生成错误的机器码
  • CVE-2019-8518:由于 LICM 将数组访问移到边界检查之前,导致 FTL JIT 中的 OOB 访问
  • CVE-2019-8558:由于悬垂的 Watchpoints 导致 CodeBlock 释放后使用
  • CVE-2019-8611:AIR 优化错误地删除了对寄存器的赋值
  • CVE-2019-8623:DFG JIT 中的循环不变代码移动 (LICM) 使栈变量未初始化
  • CVE-2019-8622:DFG 的 doesGC() 关于 HasIndexedProperty 操作在 StringObjects 上的行为不正确
  • CVE-2019-8671:DFG:循环不变代码移动 (LICM) 使对象属性访问未受保护
  • CVE-2019-8672:ValueProfiles 中的 JSValue 释放后使用
  • CVE-2019-8678:当某些原型被修改时,JSC 未能运行 haveABadTime(),导致类型混淆
  • CVE-2019-8685:JSPropertyNameEnumerator 使用了错误的结构 ID
  • CVE-2019-8765:DFG 编译期间 GetterSetter 类型混淆
  • CVE-2019-8820:在重构 arguments 对象时,bailout 期间的类型混淆
  • CVE-2019-8844:ObjectAllocationSinkingPhase 不应为不再有效的分配插入提示
  • CVE-2020-3901:FTL JIT 代码中的 GetterSetter 类型混淆(由于并非总是安全的 LICM)
  • CVE-2021-30851:并发 HashTable 查找期间缺少锁
  • CVE-2021-30818:DFG OSR 退出时重构参数时的类型混淆

Gecko/Spidermonkey

  • CVE-2018-12386:IonMonkey 寄存器分配错误导致类型混淆
  • CVE-2019-9791:IonMonkey 对于通过 OSR 进入的构造函数的类型推断不正确
  • CVE-2019-9792:IonMonkey 将 JS_OPTIMIZED_OUT 幻数泄露给脚本
  • CVE-2019-9816:ObjectGroupDispatch 操作中出现意外的 ObjectGroup
  • CVE-2019-9813:IonMonkey 编译代码未能更新推断的属性类型,导致类型混淆
  • CVE-2019-11707:IonMonkey 错误地预测了 Array.prototype.pop 的返回类型,导致类型混淆
  • CVE-2020-15656:IonMonkey 中特殊 arguments 的类型混淆
  • CVE-2021-29982:错误的寄存器分配(由 JIT-Picker 发现)
  • CVE-2021-29984:指令重排序与意外的 GC 结合可能导致内存损坏
  • CVE-2022-28285:MLoadTypedArrayElementHole 的 AliasSet 过于宽松
  • CVE-2022-31745:增量 GC 中的错误
  • CVE-2022-42928:某些 BigInt 操作缺少 KeepAlive 注释可能导致内存损坏
  • CVE-2022-45406:JavaScript Realm 的释放后使用
  • CVE-2023-4577:GC 与正则表达式交互导致的内存损坏
  • CVE-2023-5171:GC 在编译期间导致释放后使用条件
  • CVE-2023-25735:由区域不匹配导致的潜在释放后使用
  • CVE-2023-25751:Jitted 代码损坏
  • CVE-2023-29535:弱映射 GC 期间的内存损坏

Chromium/v8* Issue 939316:Turbofan 在优化 Reflect.construct 时可能越界读取 Map 指针

  • Issue 944062:JSCallReducer::ReduceArrayIndexOfIncludes 未能插入 Map 检查
  • CVE-2019-5831:V8 中错误的 Map 处理
  • Issue 944865:V8 中无效的值表示
  • CVE-2019-5841:内联启发式算法中的错误
  • CVE-2019-5847:V8 密封/冻结元素导致崩溃
  • CVE-2019-5853:正则表达式长度检查中的内存损坏
  • Issue 992914:Map 迁移未考虑元素种类,导致类型混淆
  • CVE-2020-6512:V8 中的类型混淆
  • CVE-2020-16006:DescriptorArray 中哈希碰撞处理不当导致的内存损坏
  • CVE-2021-37991:并发 JIT 编译期间的竞争条件
  • Issue 1359937:BigInt 反序列化可能导致无效的 -0n 值
  • Issue 1377775:在 Turbofan 中内联 Array.prototype.at 时类型检查错误

Duktape

  • Issue 2323:putprop 中不稳定的 valstack 指针
  • Issue 2320:字符串内建函数中的 Memcmp 指针溢出

JerryScript

  • CVE-2020-13991:展开参数释放不正确
  • Issue 3784:属性枚举不正确导致的内存损坏
  • CVE-2020-13623:通过 Proxy 对象的属性键导致的堆栈溢出
  • CVE-2020-13649 (1):OOM 情况下错误处理导致的内存损坏
  • CVE-2020-13649 (2):OOM 情况下错误处理导致的内存损坏
  • CVE-2020-13622:Proxy 对象属性键处理不正确导致的内存损坏
  • CVE-2020-14163:添加键/值对时垃圾回收触发的竞争条件导致的内存损坏
  • Issue 3813:SerializeJSONProperty 函数中错误的错误处理
  • Issue 3814:ecma_op_function_has_instance 断言中出现意外的 Proxy 对象
  • Issue 3836:TypedArray 初始化不正确导致的内存损坏
  • Issue 3837:getOwnPropertyDescriptor 中内存处理不正确导致的内存损坏

Hermes

  • CVE-2020-1912:延迟编译的内部生成器函数执行时导致的内存损坏
  • CVE-2020-1914:处理 SaveGeneratorLong 指令时的字节码损坏

免责声明

这不是 Google 官方支持的产品。

下载工具
  • CVE-2022-46696:由于 JIT 编译代码中缺少异常检查导致断言失败
  • CVE-2022-46699:由于 IC 中特殊属性的错误缓存导致断言失败
  • CVE-2022-46700:Intl.Locale.prototype.hourCycles 将空 JSValue 泄露给脚本
  • CVE-2025-43214:遍历堆栈时,JSToWasmEntry 中的内存损坏
  • CVE-2025-43213:NewRegExpUntyped 操作的类型无效
  • CVE-2023-29543:Debugger 内的内存损坏
  • CVE-2023-29544:并行标记期间的内存损坏
  • CVE-2023-29549:对象分配到错误的 Realm
  • CVE-2024-0744:JIT 编译代码可能解引用野指针值
  • CVE-2024-3854:JIT 错误地优化了 switch 语句并生成越界读取的代码
  • CVE-2024-3855:JIT 错误地优化了 MSubstr 操作,导致越界读取
  • CVE-2024-3857:JIT 生成了错误的代码,导致垃圾回收期间的释放后使用
  • CVE-2024-3858:在 GC 追踪时修改 JavaScript 对象会使 jitted 代码崩溃
  • CVE-2024-6613:WASM 栈帧的错误列出
  • CVE-2024-6614:WASM 栈帧的错误列出
  • CVE-2024-7521:不完整的 WebAssembly 异常处理
  • CVE-2024-7652:AsyncGeneratorPrototype 规范中的错误
  • CVE-2024-8381:在 "with" 块中查找属性名时的类型混淆
  • CVE-2024-9396:克隆某些对象时可能发生潜在的内存损坏
  • CVE-2025-0240:解析 JavaScript JSON 模块时的区域不匹配
  • CVE-2025-0241:使用 JavaScript 文本分割时的内存损坏
  • CVE-2025-1012:并发延迟解析期间的释放后使用
  • CVE-2025-1934:正则表达式 bailout 处理期间的意外 GC