一、Syzkaller工具介绍:
Syzkaller 是一个用于自动化系统内核 fuzz 测试的工具。它是一个开源的测试工具,专门设计用于发现和报告操作系统内核中的软件漏洞和错误。
以下是 Syzkaller 的主要特点和功能:
-
Fuzz 测试:Syzkaller 使用 fuzzing 技术,通过生成大量随机输入来测试操作系统内核的代码路径,以发现潜在的漏洞和错误。它能够对系统内核的不同部分进行广泛的测试,包括系统调用、驱动程序和内核 API 等。
-
自动化:Syzkaller 能够自动化执行 fuzz 测试过程,包括生成随机测试用例、运行测试用例、监视系统崩溃和异常、收集和分析测试结果等。这减少了人工干预的需求,提高了测试的效率和覆盖范围。
-
覆盖率分析:Syzkaller 能够分析测试用例覆盖的代码路径,帮助用户了解哪些代码路径已经被覆盖,以及哪些路径尚未被测试到。这有助于优化测试用例生成策略,提高漏洞和错误的发现率。
-
错误报告:Syzkaller 能够及时报告系统内核中发现的漏洞和错误。它会生成详细的错误报告,包括导致问题的输入样本、调用堆栈信息、系统状态等,帮助开发人员快速定位和修复问题。
-
支持多种操作系统:Syzkaller 不仅支持 Linux 内核的 fuzz 测试,还支持其他操作系统内核的测试,如 FreeBSD、NetBSD、Windows 等。
总的来说,Syzkaller 是一个强大的系统内核 fuzz 测试工具,能够帮助发现和修复操作系统内核中的漏洞和错误,提高系统的稳定性和安全性。
二、环境搭建步骤:
1.下载go语言编译器
wget https://dl.google.com/go/go1.20.1.linux-amd64.tar.gz
tar -xf go1.20.1.linux-amd64.tar.gz
export GOROOT=`pwd`/go
export PATH=$GOROOT/bin:$PATH
2.下载并编译syzkaller
git clone https://github.com/google/syzkaller
cd syzkaller
make
3.编译内核
更改.config文件
CONFIG_KCOV=y
CONFIG_DEBUG_INFO=y
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y
CONFIG_KCOV_INSTRUMENT_ALL=y
CONFIG_KCOV_ENABLE_COMPARISONS=y
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KMEMLEAK=y
make olddefconfig
编译内核
make -j`nproc`
4.安装QEMU并验证
安装 QEMU
命令:sudo apt install qemu-system-x86
验证确保内核启动并启动ssh
qemu-system-x86_64 \
-m 2G \
-smp 2 \
-kernel /root/test/kernel_linux_5.10/arch/x86_64/boot/bzImage \
-append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
-drive file=/root/syzkaller/temp/bullseye.img,format=raw \
-net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
-net nic,model=e1000 \
-enable-kvm \
-nographic \
-pidfile vm.pid \
2>&1 | tee vm.log
另开启一个终端通过 ssh 连接到 QEMU 实例
ssh -i /root/syzkaller/temp/bullseye.id_rsa -p 10021 -o "StrictHostKeyChecking no" root@localhost
5.syzkaller测试
创建一个工作目录
mkdir workdir
创建配置文件xx.cfg
路径需要更换对应的
{
"target": "linux/amd64",
"http": "127.0.0.1:56741",
"workdir": "/root/syzkaller/workdir",
"kernel_obj": "/root/test/kernel_linux_5.10",
"image": "/root/syzkaller/temp/bullseye.img",
"sshkey": "/root/syzkaller/temp/bullseye.id_rsa",
"syzkaller": "/root/syzkaller",
"procs": 8,
"type": "qemu",
"vm": {
"count": 4,
"cmdline": "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0",
"kernel": "/root/test/kernel_linux_5.10/arch/x86_64/boot/bzImage",
"cpu": 2,
"mem": 2048
}
}
6.启动syzkaller
./bin/syz-manager -config=xx.cfg
打开网页http://127.0.0.1:56741/
无页面系统下载w3m执行如下命令
w3m http://127.0.0.1:56741/
"enable_syscalls"可以指定执行测试用例:如下仅做参考
{
"target": "linux/amd64",
"http": "127.0.0.1:56741",
"workdir": "/root/syzkaller/workdir",
"kernel_obj": "/root/test/kernel_linux_5.10",
"image": "/root/syzkaller/temp/bullseye.img",
"sshkey": "/root/syzkaller/temp/bullseye.id_rsa",
"syzkaller": "/root/syzkaller",
"procs": 8,
"type": "qemu",
"enable_syscalls" :[
"socket$inet",
"accept$inet",
"accept4$inet",
"bind$inet",
"connect$inet",
"sendto$inet",
"recvfrom$inet",
"getsockname$inet",
"getpeername$inet",
"getsockopt$inet_int",
"setsockopt$inet_int",
"getsockopt$inet_buf",
"setsockopt$inet_buf",
],
"vm": {
"count": 4,
"cmdline": "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0",
"kernel": "/root/test/kernel_linux_5.10/arch/x86_64/boot/bzImage",
"cpu": 2,
"mem": 2048
}
}
三、syzlang语法介绍:
Syzlang 是 Syzkaller 使用的一种特定领域语言(DSL),用于描述系统调用序列和输入数据结构,以生成 fuzz 测试用例。Syzlang 具有简洁的语法和丰富的特性,使其成为进行内核 fuzz 测试的强大工具。以下是 Syzlang 的主要语法介绍:
-
系统调用描述:
- 使用
call
关键字描述系统调用。例如:call futex_wait$int(fd fd_in, key int64, timeout timespec64, utime timespec64) = (errno int32);
call
后面跟着系统调用名称和参数列表。- 系统调用名称后面可以加上
$
和返回值类型(如int
、int32
等)。 - 等号后面是系统调用的返回值列表。
- 使用
-
输入数据结构:
- 使用
type
关键字定义输入数据结构。例如:type buf [40]byte;
type
后面跟着数据结构名称和其描述,描述可以是基本数据类型(如int
、int32
、int64
、flags
等)或者其他已定义的数据结构。
- 使用
-
枚举类型:
- 使用
flags
关键字定义枚举类型。例如:flags { FOO = 1; BAR = 2; BAZ = 4; };
flags
后面跟着枚举类型名称,然后在大括号内列出枚举值。
- 使用
-
数组和指针:
- 支持数组和指针类型。例如:
type buf *[4]uint64;
- 支持数组和指针类型。例如:
-
结构体:
- 使用
struct
关键字定义结构体。例如:struct foo { a uint64; b uint64; };
- 使用
-
函数:
- 使用
func
关键字定义函数。例如:func foo(a int64, b int64) int64 { return a + b; }
- 使用
-
注释:
- 支持
//
单行注释和/* */
多行注释。
- 支持
-
内置函数:
- Syzlang 支持一些内置函数,用于生成随机数据或调用其他函数。
-
环境变量:
- 使用
$
前缀来引用环境变量。
- 使用
以上是 Syzlang 的主要语法特性,它们可以组合使用来描述系统调用序列和输入数据结构,生成 fuzz 测试用例。Sykzaller 会根据 Syzlang 描述生成的测试用例进行 fuzz 测试,并帮助发现潜在的内核漏洞和错误。
在syzkaller/sys/linux下增加xxx_test.txt接口配置
重新编译
首先使用syz-extract工具将txt配置转换为.const文件,该工具需要提前编译
cd syzkaller
make bin/syz-extract
make bin/syz-sysgen
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" xxx_test.txt
接下来,将文件转为go文件,供syzkaller直接使用,并重新编译syzkaller
touch .descriptions
syz-sysgen
make TARGETOS=linux TARGETARCH=amd64
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" socket_inet.txt
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" socket_inet_dccp.txt
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" socket_inet_icmp.txt
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" socket_inet_l2tp.txt
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" socket_inet_sctp.txt
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" socket_inet_igmp.txt
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" socket_inet_udp.txt
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" socket_netlink_generic_fou.txt
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" socket_netlink_generic_wireguard.txt
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" socket_netlink_xfrm.txt
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" socket_rxrpc.txt
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" socket_inet_tcp.txt
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" socket.txt
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" socket_netlink_generic_mptcp.txt
bin/syz-extract -os linux -arch amd64 -sourcedir "/root/test/kernel_linux_5.10" socket_netlink_route.txt