一、fuzz

模糊测试 (fuzz testing, fuzzing)是一种软件测试技术。其核心思想是自动或半自动的生成随机数据输入到一个程序中,并监视程序异常,如崩溃,断言(assertion)失败,以发现可能的程序错误,比如内存泄漏。模糊测试常常用于检测软件或计算机系统的安全漏洞。

进行软件漏洞挖掘时,通常有静态分析(staticanalysis)、动态分析(dynamicanalysis)、符号执行(symbolicexecution)、模糊测试(fuzzing)这几种技术手段。

静态分析就是不真正的运行目标程序,但是通过对它进行各种语法、语义、数据流等的分析,来进行漏洞发掘。静态分析是由静态分析软件完成的;它的速度快,但是误报率高。

动态分析就是我们通常见到的大佬们用od一步步跟踪程序运行进行的分析。它的准确率很高,但是需要调试人员丰富的知识储备,而且这种调试方法很难进行大规模的程序漏洞挖掘。

符号执行简单来说,就是试图找到什么输入对应什么样的运行状态,它要去覆盖所有的执行路径。因此,当被分析的程序比较复杂,有很多执行路径时,就会遇到路径爆炸的问题。

模糊测试不需要人过多的参与,也不像动态分析那样要求分析人员有丰富的知识。简单解释,它就是用大量的输入数据自动去执行程序,从而发现哪些输入能够使程序发生异常,进而分析可能存在的漏洞。当前比较成功的fuzzer(执行模糊测试的程序)有AFL、libFuzzer、OSS-Fuzz等。

二、syzkaller简介

syzkaller是google的安全研究人员开发并维护的内核fuzz工具。它主要是用go写的,也有少部分C代码,支持akaros/fuchsia/linux/android/freebsd/netbsd/openbsd/windows等系统,发现的漏洞多达上千。不过它支持最全面的还是linux系统,对其它系统的支持都不同程度差一点,也不支持Darwin/XNU。有研究人员做过移植syzkaller fuzz windows WSL和Darwin/XNU的尝试,也都取得了较好的成果。可以说,syzkaller是当今宇宙最强大的内核fuzz工具了。

三、syzkaller整体架构

syz-manager通过ssh调用syz-fuzzer,syz-fuzzer和syz-manager之间通过RPC进行通信。syz-fuzzer将输入传给syz-executor,从kernel中读取代码覆盖率信息。syz-executor执行syscall系统调用。
在这里插入图片描述

我们再看一下代码的整体目录。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tNY0nsKj-1629717745743)(evernotecid://736F44E9-16CA-47A4-A9A3-42A3B531B7D0/appyinxiangcom/25753275/ENResource/p25)]

  • dashboard目录:主要与syzbot有关,syzbot会自动fuzz linux内核主线分支并向内核邮件列表报告发现的错误。我们可以在https://syzkaller.appspot.com上看到相关的情况。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bg1mVyNc-1629717745744)(evernotecid://736F44E9-16CA-47A4-A9A3-42A3B531B7D0/appyinxiangcom/25753275/ENResource/p26)]

  • docs目录:相关文档。

  • pkg目录:配置文件。

  • prog目录:目标系统相关信息以及需要执行的系统调用。

  • sys目录:系统调用描述。该目录下的结构如下图。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jj6bJrEk-1629717745746)(evernotecid://736F44E9-16CA-47A4-A9A3-42A3B531B7D0/appyinxiangcom/25753275/ENResource/p27)]

四、使用syzkaller进行Linux内核漏洞挖掘

环境准备
  • 准备一台linux机器

安装基本软件

sudo apt-get install debootstrap
sudo apt install qemu-kvm
sudo apt-get install subversion
sudo apt-get install git
sudo apt-get install make
sudo apt-get install qemu
sudo apt install libssl-dev libelf-dev
sudo apt-get install flex bison libc6-dev libc6-dev-i386 linux-libc-dev linux-libc-dev:i386 libgmp3-dev libmpfr-dev libmpc-dev
apt-get install g++
apt-get install build-essential
apt install golang-go
apt install gcc
  • 获取syzkaller源码
git clone https://github.com/google/syzkaller.git
  • 获取linux内核代码,可在linux kernel官网下载

https://www.kernel.org/

  • 生成小型Linux发行版所需的镜像(用debootstrap生成)
    这里使用官方提供的构建脚本。实际上我们可以参考脚本内容构建其他发行版的镜像。
wget https://raw.githubusercontent.com/google/syzkaller/master/tools/create-image.sh -O create-image.sh
 
chmod +x create-image.sh
 
./create-image.sh

完成后可以看到出现了:stretch.id_rsa、stretch.id_rsa.pub、stretch.img 这几个文件。

构建
  • 编译syzkaller
root@kylinos:~/fuzz-kernel/syzkaller# cd ~/fuzz-kernel/syzkaller/
root@kylinos:~/fuzz-kernel/syzkaller# make
  • 编译kernel
    1、在内核源码目录同级创建目录build
    2、拷贝需要测试系统的内核config到build目录下并改名.config
    3、配置编译内核选项
make O=../build/ menuconfig

4、增加syzkaller测试所需要配置(通过3步的menuconfig进行查找配置,并修改配置。y代表编译到核内)

CONFIG_KCOV=y
CONFIG_DEBUG_INFO=y
CONFIG_KASAN=y 
CONFIG_KASAN_INLINE=y  
CONFIG_CONFIGFS_FS=y
CONFIG_SECURITYFS=y

5、编译

make O=../build/ -j10

6、在内核源码目录同级创建目录install_path/boot目录
7、安装内核到…/install_path

export INSTALL_PATH=../install_path/boot && export INSTALL_MOD_PATH=../install_path/ && export INSTALL_MOD_STRIP=1 && make modules_install install O=../build
  • 添加内核核外模块到镜像。
root@kylinos:~/fuzz-kernel# ls
kernel  my.cfg  stretch  syzkaller  syzkaller.sh  vm.log
root@kylinos:~/fuzz-kernel# mount stretch/stretch.img /mnt/
mount: /mnt/: /root/fuzz-kernel/stretch/stretch.img 已经挂载.        
root@kylinos:~/fuzz-kernel# cp kernel/install_path/lib/modules/5.4.18-32+ /mnt/lib/modules/ -rfa
root@kylinos:~/fuzz-kernel# chroot /mnt/
root@kylinos:/# depmod -a -b . 5.4.18-32+
root@kylinos:/# exit
exit
root@kylinos:~/fuzz-kernel# umount /mnt 
运行syzkaller
  • 测试构建镜像是否正常。(使用以下qemu启动命令测试,正常无任何报错进入系统,然后init 0 关机。)
root@kylinos:~/fuzz-kernel# vim syzkaller.sh 

qemu-system-x86_64 \
 -kernel /root/fuzz-kernel/kernel/build/arch/x86/boot/bzImage \
 -append "console=ttyS0 root=/dev/sda debug earlyprintk=serial slub_debug=QUZ" \
 -hda /root/fuzz-kernel/stretch/stretch.img \
 -net user,hostfwd=tcp::10021-:22 -net nic \
 -enable-kvm \
 -nographic \
 -m 2G \
 -smp 2 \
 -pidfile vm.pid \
 2>&1 | tee vm.log                   
  • 运行syzkaller
    编写配置文件
root@kylinos:~/fuzz-kernel# vim ./syzkaller/my.cfg 

{
        "target": "linux/amd64",
        "http": "127.0.0.1:56741",
        "workdir": "/root/fuzz-kernel/syzkaller/workdir", #工作目录
        "kernel_obj": "/root/fuzz-kernel/kernel/build", #内核编译build目录
        "image": "/root/fuzz-kernel/stretch/stretch.img", #镜像位置
        "sshkey": "/root/fuzz-kernel/stretch/stretch.id_rsa", 
        "syzkaller": "/root/fuzz-kernel/syzkaller", 
        "procs": 8,
        "type": "qemu",
        "vm": {
                "count": 4,
                "kernel": "/root/fuzz-kernel/kernel/build/arch/x86/boot/bzImage",
                "cpu": 2,
                "mem": 2048
        }
}

配置无误后运行syzkaller

root@kylinos:~/fuzz-kernel/syzkaller# ./bin/syz-manager -config=my.cfg

启动成功如图示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F1JOBsmK-1629717745748)(evernotecid://736F44E9-16CA-47A4-A9A3-42A3B531B7D0/appyinxiangcom/25753275/ENResource/p28)]

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐