内核漏洞挖掘技术系列(4)——syzkaller(5)
字数 1682 2025-08-05 08:19:19

Syzkaller 内核漏洞挖掘技术详解(第五部分)

1. 概述

本文是内核漏洞挖掘技术系列的第九篇,重点分析 Syzkaller 的 Generate 和 Mutate 实现机制。这是 Syzkaller 分析系列的第五部分,前四部分分别介绍了 Syzkaller 的基本架构和 fuzz 流程。

2. Generate 机制分析

2.1 生成流程

Generate 函数负责随机生成含有 ncalls 个系统调用的程序,主要调用链如下:

  1. generateCall
  2. generateParticularCall
  3. generateArgs
  4. generateArg
  5. generateArgImpl

2.2 关键函数解析

generateCall:

  • r.target.Syscalls 中选择系统调用
  • 使用 Choose 函数(基于 ChoiceTable)选择系统调用号
  • 调用 generateParticularCall 生成具体系统调用

generateArgImpl:

  • 生成参数本身但不生成具体内容
  • 后续调用特定类型的 generate 函数进行处理

2.3 参数类型处理

指针类型:

  • 可能生成三种特殊值:
    • 0x0000000000000000(空指针)
    • 0xffffffffffffffff(未映射的内核地址)
    • 0x9999999999999999(不规范地址)

数组类型:

  1. 根据数组长度范围随机生成长度
  2. 根据数组元素类型调用对应的 generateArg 生成每个元素

3. Mutate 机制分析

3.1 变异类型

Mutate 会随机选择以下几种变异类型:

  1. squashAny - 参数压缩(概率最低)
  2. splice - 系统调用克隆与拼接
  3. insertCall - 插入系统调用
  4. mutateArg - 参数变异
  5. removeCall - 移除系统调用

3.2 变异函数详解

squashAny:

  • 压缩参数结构
  • 示例:
    • 之前: foo$any0(&(0x7f0000000000)={0x11,0x11223344,0x2233,...})
    • 之后: foo$any0(&(0x7f0000000000)=ANY=[@ANYBLOB="11000000..."])

splice:

  1. 克隆一份系统调用
  2. 拼贴到原程序中间
  3. 移除拼贴后的后半部分

insertCall:

  • 在程序中插入新的系统调用

mutateArg:

  • 调用链:mutateArgTarget.mutateArg → 类型特定变异函数
  • 处理方式与 Generate 类似,某些类型直接调用 regenerate
  • 类型处理:
    • flag类型(实质是int):
      • 加随机数
      • 减随机数
      • 异或随机数
    • struct/union类型
      • 检查是否含有 SpecialTypes
      • SpecialTypes 则调用 generateArg 替换原值
    • 其他类型
      • 文件名变异
      • 数组变异
      • 长度变异
      • 进程变异

removeCall:

  • 随机移除一个系统调用

3.3 Linux 中的 SpecialTypes

在 Linux 系统中,以下成员属于 SpecialTypes,允许对特定 struct/union 类型进行定制的 Generate/Mutate 操作。

4. 变异示例

flag变异:

  • 修改标志位值

filename变异:

  • 修改文件名参数

array变异:

  • 修改数组内容或长度

len变异:

  • 修改长度字段

proc变异:

  • 修改进程相关参数

5. 总结

本文详细分析了 Syzkaller 的 Generate 和 Mutate 实现机制,包括:

  • 系统调用和参数的生成流程
  • 多种变异策略及其实现细节
  • 特殊参数类型的处理方法
  • Linux 系统中特有的 SpecialTypes 机制

这些机制共同构成了 Syzkaller 强大的内核漏洞挖掘能力,通过智能生成和变异系统调用序列来发现潜在的内核漏洞。

Syzkaller 内核漏洞挖掘技术详解(第五部分) 1. 概述 本文是内核漏洞挖掘技术系列的第九篇,重点分析 Syzkaller 的 Generate 和 Mutate 实现机制。这是 Syzkaller 分析系列的第五部分,前四部分分别介绍了 Syzkaller 的基本架构和 fuzz 流程。 2. Generate 机制分析 2.1 生成流程 Generate 函数负责随机生成含有 ncalls 个系统调用的程序,主要调用链如下: generateCall generateParticularCall generateArgs generateArg generateArgImpl 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 替换原值 其他类型 : 文件名变异 数组变异 长度变异 进程变异 removeCall : 随机移除一个系统调用 3.3 Linux 中的 SpecialTypes 在 Linux 系统中,以下成员属于 SpecialTypes ,允许对特定 struct/union 类型进行定制的 Generate/Mutate 操作。 4. 变异示例 flag变异 : 修改标志位值 filename变异 : 修改文件名参数 array变异 : 修改数组内容或长度 len变异 : 修改长度字段 proc变异 : 修改进程相关参数 5. 总结 本文详细分析了 Syzkaller 的 Generate 和 Mutate 实现机制,包括: 系统调用和参数的生成流程 多种变异策略及其实现细节 特殊参数类型的处理方法 Linux 系统中特有的 SpecialTypes 机制 这些机制共同构成了 Syzkaller 强大的内核漏洞挖掘能力,通过智能生成和变异系统调用序列来发现潜在的内核漏洞。