SpiderMonkey 漏洞利用简介(一)
字数 1324 2025-08-03 16:49:35
SpiderMonkey 漏洞利用简介(一)
介绍
本文是SpiderMonkey JavaScript引擎漏洞利用系列的第一部分,主要介绍基础知识和背景。SpiderMonkey是Mozilla Firefox浏览器使用的JavaScript引擎,本文从一个从未编写过浏览器漏洞利用的开发者角度出发,介绍了如何开始研究JavaScript引擎漏洞利用。
环境设置
获取源码
Mozilla使用mercurial进行开发,但也维护只读的GIT镜像:
git clone --depth 1 https://github.com/mozilla/gecko-dev.git
编译JavaScript Shell
- 首先应用必要的补丁文件
- 安装Mozilla-Build工具链
- 配置x64调试版本:
autoconf-2.13
mkdir build.asserts
cd build.asserts
../configure --host=x86_64-pc-mingw32 --target=x86_64-pc-mingw32 --enable-debug
mozmake -j2
SpiderMonkey基础知识
JS::Values和JSObjects
JavaScript对象在内存中的表示:
JS::Value是JavaScript值的内部表示- 高17位(JSVAL_TAG)用于编码类型信息
- 低47位(JSVAL_TAG_SHIFT)是普通类型的值或指向JSObject的指针
JS::Value结构
union alignas(8) Value {
private:
uint64_t asBits_;
double asDouble_;
struct {
union {
int32_t i32_;
uint32_t u32_;
JSWhyMagic why_;
} payload_;
类型标记
enum JSValueType : uint8_t
{
JSVAL_TYPE_DOUBLE = 0x00,
JSVAL_TYPE_INT32 = 0x01,
JSVAL_TYPE_BOOLEAN = 0x02,
JSVAL_TYPE_UNDEFINED = 0x03,
// ...其他类型
};
对象内存布局
JavaScript对象主要由两部分组成:
- 形状对象(Shape) - 描述属性
- 存储元素或属性值的存储槽(Slots)
对象层次结构
JSObject
↑
JS::ShapedObject
↑
JS::NativeObject
↑
JS::ArrayObject (和其他特定对象类型)
调试技巧
- 使用
Math.atan2设置断点 - 使用
objectAddress获取对象地址 - 使用
dumpObject查看对象详细信息
Shapes(形状)
Shape对象描述对象的属性:
- 每个属性对应一个Shape对象
- 通过父字段链接形成形状链
- 包含属性名和槽号信息
Shape结构
class js::Shape {
js::GCPtr<js::BaseShape *> base_;
js::PreBarriered<jsid> propid_; // 属性名
uint32_t immutableFlags; // 包含槽号信息
uint8_t attrs;
uint8_t mutableFlags;
js::GCPtr<js::Shape *> parent; // 父Shape
js::KidsPointer kids;
};
属性查找示例
- 获取对象地址
- 找到shapeOrExpando_字段指向的Shape
- 遍历Shape链获取所有属性信息
- 从immutableFlags中提取槽号
- 在对象存储中查找对应槽的值
Slots(存储槽)
属性值存储在对象的内存区域中:
- 紧接在对象头之后
- 每个槽存储一个JS::Value
- 数组有特殊的ObjectElements头存储长度信息
ObjectElements结构
struct js::ObjectElements {
uint32_t flags;
uint32_t initializedLength;
uint32_t capacity;
uint32_t length; // 对于数组
};
数组内存布局示例
+-------------------+ 0x00
| group_ |
+-------------------+ 0x08
| shapeOrExpando_ |
+-------------------+ 0x10
| slots_ |
+-------------------+ 0x18
| elements_ |
+-------------------+ 0x20
| ObjectElements |
| (flags, lengths) |
+-------------------+ 0x30
| element[0] |
+-------------------+ 0x38
| element[1] |
+-------------------+
| ... |
调试工具
sm.js扩展
作者开发了WinDbg JavaScript扩展sm.js,用于:
- 查看SpiderMonkey内部结构
- 检查对象内存布局
- 辅助漏洞利用开发
TTD (Time Travel Debugging)
使用TTD可以:
- 记录程序执行
- 前后浏览执行历史
- 更容易分析复杂对象状态变化
漏洞利用计划
作者计划分三步开发漏洞利用:
- basic.js - 针对特定版本js.exe的硬编码利用
- kaizen.js - 动态解析偏移,使用JIT生成ROP gadgets
- ifrit.js - 针对Firefox浏览器,使用JIT编写完整payload
总结
本文介绍了SpiderMonkey引擎的基础知识,包括:
- JS::Value的内部表示
- JavaScript对象的内存布局
- 属性存储机制(Shapes和Slots)
- 调试工具和方法
- 漏洞利用的开发计划
这些基础知识为后续实际的漏洞利用开发奠定了基础。在第二部分中,将详细介绍具体的漏洞利用过程和技术。