未分类 · 2020-10-11 1

Syzkaller环境搭建

近期在研究安全渗透,雁过拔毛,留点记录,以备后查。

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复现问题,同时还可以分布式集群测试,这块暂时还没研究,改天研究了再细述。