内核漏洞挖掘技术系列(4)——syzkaller(3)
字数 2308 2025-08-05 08:17:20
Syzkaller内核漏洞挖掘技术深入解析(3):Crash复现与最小化
一、Syzkaller配置参数详解
1.1 基本配置参数
在syz-manager的配置文件中,以下参数是核心配置项:
- http: 显示运行中syz-manager进程信息的URL
- email_addrs: 首次出现bug时接收通知的电子邮件地址(仅支持Mailx)
- workdir: 工作目录位置,包含以下子内容:
crashes/*: crash输出文件corpus.db: 程序语料库instance-x: 每个VM实例的临时文件
- syzkaller: syzkaller二进制文件位置
- kernel_obj: 包含目标文件(如vmlinux)的目录
- procs: 每个VM中的并行测试进程数(通常4或8)
- image: QEMU实例的磁盘镜像文件位置
- sshkey: 用于与虚拟机通信的SSH密钥位置
1.2 沙盒模式配置
sandbox参数支持以下模式:
none: 默认设置,不做特殊处理setuid: 冒充用户nobody(65534)namespace: 使用命名空间删除权限(需内核支持相关配置)
1.3 系统调用控制
- enable_syscalls: 指定要测试的系统调用列表
- disable_syscalls: 指定禁用的系统调用列表
- suppressions: 已知错误的正则表达式列表
1.4 虚拟机配置
- type: 虚拟机类型(如qemu)
- vm: VM类型相关参数:
count: 并行运行的VM数量kernel: 要测试的内核bzImage文件位置cmdline: 启动内核的额外命令行选项cpu: VM中模拟的CPU数量mem: VM内存大小(MB)
二、Syzkaller启动流程
2.1 初始化阶段
- 日志缓存:启用日志缓存功能,限制为1000行或1^29字节
- 配置加载:加载config文件,获取OS和架构信息
- 目标获取:通过
GetTarget函数获取参数对应的target - 系统调用解析:通过
ParseEnabledSyscalls解析enable/disable_syscalls参数
2.2 虚拟机池创建
if config.Type != "none" {
vmPool = vmimpl.Create(config.Type, config.VM)
}
type=none用于调试/开发,需手动启动VM- 虚拟机池(vmPool)用于创建多个独立VM
- 通过qemu.go的Ctor函数检查参数有效性
三、Crash复现机制
3.1 复现队列处理
- crash保存在
reproQueue中 - 通过
len(reproQueue) != 0判断是否有待复现crash - 实例分割:
vmIndexes := append([]int{}, instances[len(instances)-instancesPerRepro:]...) instances = instances[:len(instances)-instancesPerRepro]vmIndexes: 用于crash复现instances: 运行新实例
3.2 复现流程(repro函数)
- 程序提取:调用
extractProg提取触发crash的程序 - 时间控制:Timeouts有三个级别:
- 10s: 简单crash复现
- 1min: 中等复杂度crash
- 5min: 复杂条件竞争crash
- 二分查找:当单个程序无法复现时,使用二分法找出触发crash的程序
- 复现策略:按时间从短到长、从后向前、从单个到多个的顺序尝试复现
四、程序最小化技术
4.1 最小化流程(minimizeProg函数)
- 调用SanitizeCall:对特殊系统调用进行处理
- 移除系统调用:尝试逐个移除非必要系统调用
- 示例:移除open系统调用
- 参数精简:去除系统调用的无关参数
4.2 参数最小化(do函数)
根据参数类型调用不同的minimize函数:
- 指针类型:将指针或指针指向内容置空
- 数组类型:逐个移除数组元素
五、C程序提取与简化
5.1 C程序提取(extractC函数)
- 调用testCProg:
- 使用
csource.Write生成C代码 - 使用
csource.Build编译可执行文件
- 使用
- 生成独立复现程序:创建可独立运行的测试用例
5.2 程序简化(simplifyProg函数)
- 再次提取C程序:调用extractC
- 简化C程序:调用simplifyC
- 简化选项:优化复现crash时的设置:
- 线程配置
- 并发设置
- 沙盒配置
六、关键数据结构与函数
6.1 主要数据结构
- reproQueue: crash复现队列
- vmPool: 虚拟机池
- instances: VM实例集合
6.2 核心函数
| 函数名 | 功能描述 |
|---|---|
| extractProg | 提取触发crash的程序 |
| minimizeProg | 程序最小化主函数 |
| SanitizeCall | 特殊系统调用处理 |
| Minimize | 最小化算法实现 |
| extractC | 生成C语言测试用例 |
| simplifyC | 简化C程序配置 |
七、最佳实践建议
-
配置优化:
- 根据硬件资源合理设置
procs和vm.count - 复杂漏洞设置更长timeout
- 根据硬件资源合理设置
-
调试技巧:
- 使用
debug参数输出VM日志 - 使用
bench参数记录统计信息
- 使用
-
复现策略:
- 优先尝试最后触发的程序
- 从简单配置开始逐步增加复杂度
-
最小化原则:
- 先移除系统调用,再精简参数
- 不同类型参数采用不同最小化策略
通过本文分析的crash复现与最小化技术,Syzkaller能够高效地验证和简化发现的漏洞,为后续分析提供清晰的测试用例。下一部分将深入分析vmLoop函数的fuzz机制。