内核漏洞挖掘技术系列(4)——syzkaller(5)
字数 1682 2025-08-05 08:19:19
Syzkaller 内核漏洞挖掘技术详解(第五部分)
1. 概述
本文是内核漏洞挖掘技术系列的第九篇,重点分析 Syzkaller 的 Generate 和 Mutate 实现机制。这是 Syzkaller 分析系列的第五部分,前四部分分别介绍了 Syzkaller 的基本架构和 fuzz 流程。
2. Generate 机制分析
2.1 生成流程
Generate 函数负责随机生成含有 ncalls 个系统调用的程序,主要调用链如下:
generateCallgenerateParticularCallgenerateArgsgenerateArggenerateArgImpl
2.2 关键函数解析
generateCall:
- 从
r.target.Syscalls中选择系统调用 - 使用
Choose函数(基于 ChoiceTable)选择系统调用号 - 调用
generateParticularCall生成具体系统调用
generateArgImpl:
- 生成参数本身但不生成具体内容
- 后续调用特定类型的 generate 函数进行处理
2.3 参数类型处理
指针类型:
- 可能生成三种特殊值:
0x0000000000000000(空指针)0xffffffffffffffff(未映射的内核地址)0x9999999999999999(不规范地址)
数组类型:
- 根据数组长度范围随机生成长度
- 根据数组元素类型调用对应的
generateArg生成每个元素
3. Mutate 机制分析
3.1 变异类型
Mutate 会随机选择以下几种变异类型:
squashAny- 参数压缩(概率最低)splice- 系统调用克隆与拼接insertCall- 插入系统调用mutateArg- 参数变异removeCall- 移除系统调用
3.2 变异函数详解
squashAny:
- 压缩参数结构
- 示例:
- 之前:
foo$any0(&(0x7f0000000000)={0x11,0x11223344,0x2233,...}) - 之后:
foo$any0(&(0x7f0000000000)=ANY=[@ANYBLOB="11000000..."])
- 之前:
splice:
- 克隆一份系统调用
- 拼贴到原程序中间
- 移除拼贴后的后半部分
insertCall:
- 在程序中插入新的系统调用
mutateArg:
- 调用链:
mutateArg→Target.mutateArg→ 类型特定变异函数 - 处理方式与 Generate 类似,某些类型直接调用
regenerate - 类型处理:
- flag类型(实质是int):
- 加随机数
- 减随机数
- 异或随机数
- struct/union类型:
- 检查是否含有
SpecialTypes - 无
SpecialTypes则调用generateArg替换原值
- 检查是否含有
- 其他类型:
- 文件名变异
- 数组变异
- 长度变异
- 进程变异
- flag类型(实质是int):
removeCall:
- 随机移除一个系统调用
3.3 Linux 中的 SpecialTypes
在 Linux 系统中,以下成员属于 SpecialTypes,允许对特定 struct/union 类型进行定制的 Generate/Mutate 操作。
4. 变异示例
flag变异:
- 修改标志位值
filename变异:
- 修改文件名参数
array变异:
- 修改数组内容或长度
len变异:
- 修改长度字段
proc变异:
- 修改进程相关参数
5. 总结
本文详细分析了 Syzkaller 的 Generate 和 Mutate 实现机制,包括:
- 系统调用和参数的生成流程
- 多种变异策略及其实现细节
- 特殊参数类型的处理方法
- Linux 系统中特有的 SpecialTypes 机制
这些机制共同构成了 Syzkaller 强大的内核漏洞挖掘能力,通过智能生成和变异系统调用序列来发现潜在的内核漏洞。