SpiderMonkey漏洞利用入门:从基础到高级技术解析

本文详细介绍了针对SpiderMonkey JavaScript引擎和Mozilla Firefox的漏洞利用开发过程,涵盖基础内存操作、JIT代码重用及高级Payload注入技术,适合安全研究人员和漏洞利用开发者阅读。

SpiderMonkey漏洞利用入门

背景介绍

本文记录了针对SpiderMonkey JavaScript Shell解释器和Mozilla Firefox在Windows 10 RS5 64位环境下的三个漏洞利用开发过程。作者从零开始,逐步深入浏览器漏洞利用领域,通过三个不同阶段的利用代码展示了技术演进过程。

环境搭建

首先需要设置调试环境,建议在虚拟机中进行。获取Mozilla的gecko-dev代码库:

1
git clone --depth 1 https://github.com/mozilla/gecko-dev.git

应用blaze.patch补丁文件,该补丁为Array对象添加了blaze方法,允许将数组长度修改为420,从而产生越界访问漏洞。

使用MozillaBuild工具链编译JavaScript Shell解释器js.exe,支持调试和发布两种构建模式。

SpiderMonkey内部机制

JS::Values和JSObjects

JavaScript对象在内存中的布局使用JS::Value结构,高17位用于编码类型信息,低47位存储实际值或对象指针。数组对象在内存中连续存储,包含长度、容量和初始化长度等信息。

形状(Shapes)和槽(Slots)

形状对象描述对象的属性和类信息,通过链表结构连接。属性值存储在对象的槽中,可以通过形状对象找到对应的存储位置。

漏洞利用开发

基础利用(basic.js)

第一个利用针对特定的js.exe构建,包含大量硬编码偏移。通过越界访问相邻的TypedArray对象,构建内存读写原语和控制流劫持能力。

关键步骤包括:

  • 构建任意内存访问原语
  • 构建对象地址泄露原语
  • 劫持控制流
  • 栈转移
  • 泄露ntdll基地址
  • 执行任意本地代码

改进利用(kaizen.js)

第二个利用改进了可靠性和动态解析能力:

  • 提高内存访问原语的可靠性
  • 动态解析导出函数地址
  • 利用基线JIT生成ROP gadget

高级利用(ifrit.js)

最终利用针对Firefox浏览器:

  • 编译Windows 64位Firefox版本
  • 配置Firefox开发环境
  • 利用JIT编译完整本地Payload

技术细节

内存操作原语

通过越界写入TypedArray的DATA_SLOT和LENGTH_SLOT,实现任意内存读写能力。使用Int64.js库处理64位整数操作。

控制流劫持

通过覆盖js::ObjectGroup的clasp_字段,最终修改cOps函数指针,在添加对象属性时触发控制流劫持。

JIT代码重用

利用基线JIT没有常量盲化的特性,通过精心构造的JavaScript函数,让JIT引擎生成特定的机器指令片段,实现代码复用攻击。

工具和资源

提供了完整的代码库和相关工具:

  • sm.js调试器扩展
  • 三个利用的源代码
  • JavaScript Shell调试和发布构建
  • Firefox二进制文件和符号信息
  • Payload生成脚本

结论

通过三个逐步改进的漏洞利用,展示了从基础内存操作到高级JIT代码重用的完整技术演进过程。文章提供了深入的技术细节和实际代码示例,为浏览器漏洞利用研究提供了有价值的参考。

所有相关材料和代码可在blazefox GitHub仓库中找到,鼓励读者亲自实践和探索。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计