近期在研究安全渗透,雁过拔毛,留点记录,以备后查。
Syzkaller是Google开发的一款内核模糊测试工具,简单点说就是自动化向内核输入各种有效的、无效的、完全随机化的参数数据,并观察内核的运行状况,是否发生了panic、内存泄漏等问题,以此发现隐藏在内核中的漏洞。近些年很多内核的CVE发现均来自于此,而且该工具的开发维护还挺活跃的。而且它不仅支持x86,还支持ARM、Power、MIPS等处理器,而且不仅支持Linux,还支持windows、FreeBSD、Fuchsia等系统,同时还能支持对远程物理机、本地虚拟机的测试,此外还能支持分布式多机器测试。
回归正题,其实把整个环境搭建起来并不费力,就是有点不太容易察觉的点会误入歧途。搭建的环境是在Ubuntu 20.04系统上基于x86-64环境的。总的来说,实施步骤就是根据syzkaller的这个文档进行操作的:https://github.com/google/syzkaller/blob/master/docs/linux/setup_ubuntu-host_qemu-vm_x86-64-kernel.md
- 编译Kernel
首先需要有一个能够支持syzkaller的内核,它需要额外开启一些特性的支持,但是又不能全开,有些配置选项会带来问题。解压预备编译的内核源码并进入源码目录。然后执行以下两条命令去使能默认配置:
make defconfig
make kvmconfig
千万别一开始就上make menuconfig配置内核,然后根据https://github.com/google/syzkaller/blob/master/docs/linux/kernel_configs.md这个配置建议就立马开干。为什么呢?可以make help看一下make menuconfig都是干什么的,它会默认开启很多无关甚至影响运行的配置项,然后大概率会最终进入这个编译好的内核系统的时候看到各种报错。
然后把syzkaller依赖的几个必须的配置项打开。
# Coverage collection.
CONFIG_KCOV=y
# Debug info for symbolization.
CONFIG_DEBUG_INFO=y
# Memory bug detector
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y
# Required for Debian Stretch
CONFIG_CONFIGFS_FS=y
CONFIG_SECURITYFS=y
可以通过echo的方式追加到.config文件的末端或者make menuconfig手动开启。千万别把这几项修改并放到.config的前端,因为后面的操作会以.config后面的配置生效。这几项修改会被覆盖掉的。
如果要是echo的方式修改追加到.config文件的话,接下来就是执行以下命令刷新.config文件配置,而make menuconfig修改的话则无需执行。
make olddefconfig
最后就开始编译内核了。
make -j8
编译好之后检查一下vmlinux和arch/x86/boot/bzImage是否都编出来的,然后编译内核就结束了。
- 构建Image
最终是通过qemu来跑这个内核的,所以需要构造一个Image文件系统映像以使得系统可以运行起来。构建Image需要安装debootstrap,可以通过下面命令完成。
sudo apt-get install debootstrap
然后下载构建Image的脚本。
wget https://raw.githubusercontent.com/google/syzkaller/master/tools/create-image.sh -O create-image.sh
然后修改一下脚本里面的软件下载源。
sed -i -e ‘s~sudo debootstrap .*~\0 https://mirrors.huaweicloud.com/debian/~’ create-image.sh
如果机器的网络可以飞过高山穿过重洋的话,可以无视修改下载源的这个操作。然后修改脚本文件,添加可执行权限。
chmod +x create-image.sh
接着通过执行脚本,让它把镜像文件构造好。
./create-image.sh –feature full
跑完之后,就可以看到有img还有2个rsa的密钥文件。待会儿就知道怎么用了。
- Qemu安装
这个就很简单了,安装qemu-system-x86。然后通过以下命令试运行一下,确保内核和Qemu都是好的。
qemu-system-x86_64 \
-m 2G \
-smp 2 \
-kernel $KERNEL/arch/x86/boot/bzImage \
-append “console=ttyS0 root=/dev/sda earlyprintk=serial” \
-drive file=$IMAGE/stretch.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
主要修改一下kernel路径,改为前面编好的bzImage文件路径,最好是绝对路径。以及drive里面的img文件路径为前面构造好的img文件路径。
然后就可以看到系统运行起来了,如果是一路的OK,说明系统运行正常良好,接着试一下ssh的连通性。
ssh -i $IMAGE/stretch.id_rsa -p 10021 -o “StrictHostKeyChecking no” root@localhost
同样id_rsa改为前面构造Image的时候,生成的stretch.id_rsa文件路径。如果不出意外的话,能够直接登录进入到qemu启动的系统当中。最后ps查找并把当前运行的qemu进程kill掉。至此,Qemu安装运行验证结束,必须能够ssh登陆,才能够进行syzkaller测试。
- 编译syzkaller
Syzkaller是基于go开发的,所以需要先安装好go。可以通过下面命令进行go安装包的下载解压以及环境路径的设置。
wget https://dl.google.com/go/go1.14.2.linux-amd64.tar.gz tar -xf go1.14.2.linux-amd64.tar.gz mv go goroot mkdir gopath export GOPATH=/home/jean/gopath export GOROOT=/home/jean/goroot export PATH=$GOPATH/bin:$PATH export PATH=$GOROOT/bin:$PATH
具体路径可以自行更改指定。接着就下载依赖件并编译。
go get -u -d github.com/google/syzkaller/prog cd gopath/src/github.com/google/syzkaller/ make
- Syzkaller之旅
如果前面都顺利的话,尤其是qemu能够正常拉起系统并能ssh登入的情况下, syzkaller肯定能够正常跑起来。
运行前,需要构造cfg配置文件。接着在前面编译syzkaller的目录(/home/jean/gopath/src/github.com/google/syzkaller)下,通过vim syz.config打开编辑syzkaller配置。下面是我的配置,实际上差异是大同小异的,按照自己的路径进行修改即可。
{ "target": "linux/amd64", "http": "127.0.0.1:56741", "workdir": "/home/jean/gopath/src/github.com/google/syzkaller/workdir", "kernel_obj": "/home/jean/syzkaller/linux-4.19.120/", "image": "/home/jean/image2wheezy/stretch.img", "sshkey": "/home/jean/image2wheezy/stretch.id_rsa", "syzkaller": "/home/jean/gopath/src/github.com/google/syzkaller", "procs": 8, "type": "qemu", "vm": { "count": 4, "kernel": "/home/jean/syzkaller/linux-4.19.120/arch/x86/boot/bzImage", "cpu": 2, "mem": 2048 } }
然后根据下面命令,构建一个workdir目录,这是用来记录syzkaller运行产生的日志,包括发现的问题信息等。最后通过syz-manager程序开始运行syzkaller。
mkdir workdir
./bin/syz-manager -config=syz.config
由此开始运行模糊测试。效果如图:
同时注意有个地址:http://127.0.0.1:56741,通过这个地址可以进入查看syzkaller运作状态。如果运行正常是能够看到executed *,corpus cover *是处于递增的状态。这是运行了一宿的结果,还是能够发现一些问题。
有跳转链接,可以点进去看到具体的问题信息。
每个发现的问题都有个id的,可以通过id复现问题,同时还可以分布式集群测试,这块暂时还没研究,改天研究了再细述。
Wow Thanks for this publish i find it hard to discover really good information and facts out there when it comes to this content thank for the information website