基于 Syzkaller 的 Linux 内核 Fuzzing 环境搭建与种子收集

封面信息图

在操作系统二进制安全与内核漏洞挖掘领域,Google 开源的 Syzkaller 是目前事实上的 Linux 内核引导式模糊测试(Coverage-guided Kernel Fuzzing)标杆工具。通过基于覆盖率反馈(KCOV)、地址消毒剂(KASAN)以及声明式系统调用描述语言(Syzlang),Syzkaller 能够高效生成结构合法的复杂系统调用序列,精准触达深层内核逻辑。

许多安全研究员在搭建 Syzkaller 环境时,常卡在内核编译选项缺失、Debian/Ubuntu rootfs 镜像挂载失败或 QEMU 实例与 Manager 通信异常等问题上。系统化梳理一套从内核源码编译、Rootfs 自动化构建、Manager 配置文件编写到高质量种子语料收集的工业级实践方案至关重要。

内核 Fuzzing 整体架构

Syzkaller 的运行架构由宿主机控制端(syz-manager)和运行在虚拟机内部的 Fuzzer 探针(syz-fuzzer / syz-executor)组成:

+-------------------------------------------------------------+
|                      Host Machine (Master)                  |
|  +-------------------------------------------------------+  |
|  | syz-manager (RPC Server / Corpus DB / Web Dashboard)  |  |
|  +-------------------------------------------------------+  |
|         | SSH / QEMU Pipe                     ^ Coverage    |
|         v Control                             | / Crash     |
+---------+-------------------------------------+-------------+
          |                                     |
          v                                     |
+-------------------------------------------------------------+
|                     QEMU VM 1..N (Target)                   |
|  +-------------------------------------------------------+  |
|  | Linux Kernel (KCOV + KASAN + Fault Injection)         |  |
|  +-------------------------------------------------------+  |
|  | syz-fuzzer  <--->  syz-executor (Executes Syscalls)   |  |
|  +-------------------------------------------------------+  |
+-------------------------------------------------------------+

步骤一:定制编译插桩内核

内核必须开启 KCOV(代码覆盖率收集)、KASAN(内存越界与释放后使用检测)以及调试符号支持。

在 Linux 内核源码树下配置 .config:

# 进入内核源码目录
cd linux-6.6

# 生成默认配置并开启核心 Fuzzing 特性
make defconfig
make kvm_guest.config

# 手动注入 Syzkaller 必需的内核编译选项
./scripts/config -e CONFIG_KCOV \
                 -e CONFIG_KCOV_INSTRUMENT_ALL \
                 -e CONFIG_KCOV_ENABLE_COMPARISONS \
                 -e CONFIG_KASAN \
                 -e CONFIG_KASAN_INLINE \
                 -e CONFIG_CONFIGFS_FS \
                 -e CONFIG_SECURITYFS \
                 -e CONFIG_DEBUG_INFO \
                 -e CONFIG_DEBUG_INFO_DWARF4 \
                 -e CONFIG_NAMESPACES \
                 -e CONFIG_USER_NS \
                 -e CONFIG_NET_NS \
                 -e CONFIG_PID_NS \
                 -e CONFIG_IPC_NS \
                 -e CONFIG_UTS_NS \
                 -e CONFIG_FAULT_INJECTION \
                 -e CONFIG_FAIL_PAGE_ALLOC \
                 -e CONFIG_FAULT_INJECTION_DEBUG_FS

# 编译内核镜像与 bzImage
make -j$(nproc)

编译完成后,会在 arch/x86/boot/bzImage 生成内核启动镜像,在根目录下生成带有完整符号表的 vmlinux。

步骤二:制作最小化 Debian Rootfs 磁盘镜像

Syzkaller 官方提供了 create-image.sh 脚本,可快速构建基于 Debian 的 QEMU 镜像:

# 安装依赖工具
sudo apt-get install -y debootstrap qemu-utils

# 创建 rootfs 构建工作区
mkdir -p rootfs && cd rootfs

# 利用 debootstrap 下载 Debian Bookworm 最小系统
sudo debootstrap --include=openssh-server,curl,tar,gcc,libc6-dev,time,strace,sudo,less,psmisc \
                 bookworm ./bookworm_dir http://deb.debian.org/debian/

# 配置 SSH 免密登录与自动挂载
sudo chroot ./bookworm_dir /bin/bash -c "
echo 'root:root' | chpasswd
echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config
echo 'PermitEmptyPasswords yes' >> /etc/ssh/sshd_config
ssh-keygen -A
"

# 生成无密码 SSH 密钥对供 syz-manager 远程调用
ssh-keygen -f ./bookworm.id_rsa -t rsa -N ''
sudo mkdir -p ./bookworm_dir/root/.ssh
sudo cp ./bookworm.id_rsa.pub ./bookworm_dir/root/.ssh/authorized_keys

# 打包为 raw 格式的虚拟磁盘文件
dd if=/dev/zero of=bookworm.img bs=1M count=4096
mkfs.ext4 -F bookworm.img
sudo mkdir -p /mnt/rootfs
sudo mount -o loop bookworm.img /mnt/rootfs
sudo cp -a ./bookworm_dir/* /mnt/rootfs/
sudo umount /mnt/rootfs

步骤三:编写 syz-manager 配置文件

syz-manager 需要一个 JSON 格式的配置文件来统一指定内核镜像路径、QEMU 硬件参数、系统调用白名单与并发 VM 实例数量。

{
  "target": "linux/amd64",
  "http": "0.0.0.0:56741",
  "workdir": "/opt/syzkaller/workdir",
  "kernel_obj": "/opt/linux-6.6",
  "image": "/opt/syzkaller/rootfs/bookworm.img",
  "sshkey": "/opt/syzkaller/rootfs/bookworm.id_rsa",
  "syzkaller": "/opt/syzkaller/bin",
  "procs": 4,
  "type": "qemu",
  "vm": {
    "count": 4,
    "kernel": "/opt/linux-6.6/arch/x86/boot/bzImage",
    "cpu": 2,
    "mem": 2048,
    "qemu_args": "-enable-kvm -net nic,model=e1000 -net user,host=10.0.2.10,hostfwd=tcp::10022-:22"
  },
  "enable_syscalls": [
    "socket",
    "bind",
    "connect",
    "sendto",
    "recvfrom",
    "setsockopt",
    "getsockopt",
    "bpf$*"
  ]
}

启动 Fuzzing 任务:

./bin/syz-manager -config=my_kernel_fuzz.cfg

访问 http://localhost:56741 即可在 Web 面板中实时查看覆盖的代码分支、系统调用执行频率以及捕获到的内核 Crash 日志(如 Slab-out-of-bounds、UAF 或 Kernel NULL Pointer Dereference)。

种子语料收集与 Syzlang 语法精炼

初始种子语料的质量直接决定了 Fuzzer 能否快速穿透浅层参数校验。在实际内核攻防研究中,可以通过以下三种手段强化种子库:

  1. 导入公开 Corpus:从 syzbot 长期运行的历史数据库中提取特定子系统(如 net/packet, bpf, io_uring)的种子包。
  2. 提取真实 Linux 单元测试:使用 strace 追踪 Linux 内核自测套件(Kselftests)或 LTP(Linux Test Project)的系统调用序列,并转换为 Syzkaller 理解的 program 格式。
  3. 定制编写 Syzlang 描述定义(.txt):针对新增的驱动或漏洞频发的子系统(如自定义字符设备驱动),在 sys/linux/ 目录下编写精确的系统调用结构体描述:
# Syzlang 示例:定义自定义 IOCTL 接口
openat$mydev(fd const[AT_FDCWD], file ptr[in, string["/dev/my_crypto_dev"]], flags flags[open_flags], mode const[0]) fd_mydev

ioctl$MY_IOCTL_ENCRYPT(fd fd_mydev, cmd const[0xC0106B01], arg ptr[in, crypto_request_struct])

crypto_request_struct {
    key_len     int32[1..32]
    key_data    array[int8, 32]
    cipher_text ptr[in, array[int8]]
    cipher_len  len[cipher_text, int32]
}

通过精准约束输入范围与结构体依赖关系,Fuzzer 可以在数小时内深挖出传统随机黑盒 Fuzz 无法触及的内核临界区死锁与条件竞争漏洞。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐