基于 Syzkaller 的 Linux 内核 Fuzzing 环境搭建与种子收集
基于 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 能否快速穿透浅层参数校验。在实际内核攻防研究中,可以通过以下三种手段强化种子库:
- 导入公开 Corpus:从 syzbot 长期运行的历史数据库中提取特定子系统(如
net/packet,bpf,io_uring)的种子包。 - 提取真实 Linux 单元测试:使用
strace追踪 Linux 内核自测套件(Kselftests)或 LTP(Linux Test Project)的系统调用序列,并转换为 Syzkaller 理解的 program 格式。 - 定制编写 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 无法触及的内核临界区死锁与条件竞争漏洞。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)