内核模糊测试工具Healer的安装

Healer是一个基于Syzkaller的内核模糊测试工具,通过动态分析检测系统调用间的影响关系。本文详细介绍了如何构建Healer,包括安装rust工具链、设置Syzkaller构建环境、编译内核以及使用Healer对Linux内核进行模糊测试的步骤。在实际运行中,可能遇到QEMU启动失败的问题,解决方案是修改healer的qemu配置参数。
摘要由CSDN通过智能技术生成

Healer的安装和初步使用

简介

​ Healer 是受 Syzkaller 启发的内核模糊测试器。
​ 与 Syzkaller 类似,Healer 使用 Syzlang 描述提供的 syscall 信息生成确认参数结构约束和部分语义约束的系统调用序列,并通过不断执行生成的调用序列导致内核崩溃,从而发现内核错误。
​ 与 Syzkaller 不同,Healer 不使用经验选择表,而是通过动态移除最小化调用序列中的调用并观察覆盖变化,来检测系统调用之间的影响关系,并利用影响关系来指导调用序列的生成和变异。 此外,Healer 还使用了与 Syzkaller 不同的架构设计。

构建Healer

  • 除了一些修补代码之外,Healer 是用纯rust编写的。 因此,首先应安装 rust 工具链。

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 
    rustc --version # check install
    

    检查安装结果:

    image-20211129084016844

  • 为了使用 Syzlang 描述,Healer 的构建脚本会自动下载 Syzkaller 并在源代码中添加补丁并构建 Syzkaller,这可能会增加构建时间。 因此,需要安装Syzkaller 所需的构建工具,例如:GO111MODULE开启的golang 编译器,GCC 6.1.0 或更高版本。

    image-20211129083949436

    • GO111MODULE的开启命令:

      go env -w GO111MODULE="on"
      go env #check
      
  • 一旦安装了所有必需的工具,就可以使用以下命令轻松构建 Healer:

    cargo build --release
    
  • 最后,可以在 target/release目录中找到 Healer 本身和打补丁的 Syzkaller 二进制文件 (syz-bin)。

    image-20211129083924376

使用 Healer 对 Linux 内核进行模糊测试

​ 总的来说,使用 Healer 对 Linux 内核进行模糊测试需要三个步骤:(1) 准备磁盘映像,(2) 编译内核, (3) 启动 Healer。

​ Healer 使用 qumu 来引导内核,所以需要准备磁盘镜像和内核镜像。启动后的 qemu 需要能够通过 ssh 密钥登录,内核至少需要具备 kcov 功能。(可以参照Syzkaller文档的详细介绍)

先决条件

sudo apt update 
sudo apt install make gcc flex bison libncurses-dev libelf-dev libssl-dev 

准备磁盘映像

安装 debootstrap
sudo apt install debootstrap
创建 Debian Stretch Linux 映像
mkdir $IMAGE 
cd $IMAGE/ wget https://raw.githubusercontent.com/google/syzkaller/master/tools/create-image.sh -O create-image.sh 
chmod +x create-image.sh 
./create-image.sh
  • 注意将$IMAGE替换为自己的路径。
附加工具
./create-image.sh --feature full
./create-image.sh --add-perf

编译内核

获取内核源码
git clone --branch v5.14 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git $KERNEL
  • 建议从最新的稳定版本开始。V5.14是一个示例。
  • 在虚拟机中git clone运行时间较长。在较好的网络环境下,可以选择在物理机中前往https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/下载内核源码的压缩包,然后拖入虚拟机解压
生成默认配置
cd $KERNEL
make defconfig
make kvm_guest.config
  • 同样注意将$IMAGE替换为自己的路径。
启用所需的配置选项
  • 手动编辑.config文件来启用它们:
# 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
  • 重新生成配置:

    make olddefconfig
    
编译内核命令
make -j`nproc`
  • 检查:

    ls $KERNEL/vmlinux
    # sample output - $KERNEL/vmlinux
    ls $KERNEL/arch/x86/boot/bzImage
    # sample output - $KERNEL/arch/x86/boot/bzImage
    

    image-20211129091321934

安装QEMU

命令
sudo apt install qemu-system-x86
核查
  • 先确定虚拟机的处理器开启虚拟化引擎-虚拟化Intel VT-x/EPT或AMD-V/RVI (我使用的是VMware Workstation)

    image-20211129092011086
  • 确认sshd开启

    ps -e |grep ssh
    

    image-20211129092306518

    • 如果没有出现sshd,则输入命令:

      /etc/init.d/ssh start
      
  • 正式启动QEMU:

    qemu-system-x86_64 \
    	-m 2G \
    	-smp 2 \
    	-kernel $KERNEL/arch/x86/boot/bzImage \
    	-append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
    	-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
    
    • 同样注意路径替换

    image-20211129093353035

    • 输入root即可登录

    image-20211129093430583

  • 此后,可以在另一终端中测试ssh能否工作

    ssh -i $IMAGE/stretch.id_rsa -p 10021 -o "StrictHostKeyChecking no" root@localhost
    

    image-20211129093824085

运行Healer

  • 一旦stretch.img$IMAGE/stretch.img)、ssh-stretch.id_rsa$IMAGE/ssh-stretch.id_rsa)、bzImage$KERNEL/linux-5.14/arch/x86/boot/bzImage准备就绪,建议是创建一个工作目录workdir。 然后,在 workdir 中创建一个 bin 目录,并将修补后的 Syzkaller 二进制文件和修复程序二进制文件复制到该目录中(healer-main/target/release/syz-bin),注意不要更改 syz-bin 目录结构。 最终的工作目录需要有以下文件。

    cd path/to/workdir && ls  
    bin  bzImage  stretch.id_rsa  stretch.img 
    ls ./bin 
    healer linux_amd64  syz-repro  syz-symbolize  syz-sysgen
    
  • 最后,在workdir执行以下命令开始模糊测试,其中 -d 指定磁盘映像的路径,-k 指定内核映像的路径,–ssh-key 指定 ssh 密钥的路径。

    sudo ./bin/healer -d stretch.img --ssh-key stretch.id_rsa -k bzImage 
    
  • 若正常运行,界面如下: image-20211129150723525

遇到的错误

1

$ sudo ./bin/healer -d stretch.img --ssh-key stretch.id_rsa -k bzImage

 ___   ___   ______   ________   __       ______   ______
/__/\ /__/\ /_____/\ /_______/\ /_/\     /_____/\ /_____/\
\::\ \\  \ \\::::_\/_\::: _  \ \\:\ \    \::::_\/_\:::_ \ \
 \::\/_\ .\ \\:\/___/\\::(_)  \ \\:\ \    \:\/___/\\:(_) ) )_
  \:: ___::\ \\::___\/_\:: __  \ \\:\ \____\::___\/_\: __ `\ \
   \: \ \\::\ \\:\____/\\:.\ \  \ \\:\/___/\\:\____/\\ \ `\ \ \
    \__\/ \::\/ \_____\/ \__\/\__\/ \_____\/ \_____\/ \_\/ \_\/

[2021-11-28T05:20:10Z INFO  healer_fuzzer] loading target linux/amd64...
[2021-11-28T05:20:15Z INFO  healer_fuzzer] pre-booting one vm...
Error: failed to boot qemu

Caused by:
    boot: failed to boot in 0s: "qemu-system-x86_64" "-display" "none" "-serial" "stdio" "-no-reboot" "-snapshot" "-device" "virtio-rng-pci" "-enable-kvm" "-cpu" "host,migratable=off" "-m" "4096" "-smp" "2" "-device" "e1000,netdev=net0" "-netdev" "user,id=net0,host=10.0.2.10,hostfwd=tcp::1025-:22" "-drive" "file=/home/yuhan/workdir/stretch.img,index=0,media=disk" "-kernel" "/home/yuhan/workdir/bzImage" "-append" "root=/dev/sda console=ttyS0 kvm-intel.nested=1 kvm-intel.unrestricted_guest=1 kvm-intel.vmm_exclusive=1 kvm-intel.fasteoi=1 kvm-intel.ept=1 kvm-intel.flexpriority=1 kvm-intel.vpid=1 kvm-intel.emulate_invalid_guest_state=1 kvm-intel.eptad=1 kvm-intel.enable_shadow_vmcs=1 kvm-intel.pml=1 kvm-intel.enable_apicv=1 earlyprintk=serial oops=panic nmi_watchdog=panic panic_on_warn=1 panic=1 ftrace_dump_on_oops=orig_cpu vsyscall=native net.ifnames=0 biosdevname=0" "-device" "ivshmem-plain,memdev=hostmem0" "-object" "memory-backend-file,size=4194304,share,mem-path=/dev/shm/healer-in_shm-0-35410,id=hostmem0" "-device" "ivshmem-plain,memdev=hostmem1" "-object" "memory-backend-file,size=16777216,share,mem-path=/dev/shm/healer-out_shm_0-35410,id=hostmem1"
    stderr:
    failed to boot, qemu exited with: signal: 6 (core dumped)
    cmdline: "qemu-system-x86_64" "-display" "none" "-serial" "stdio" "-no-reboot" "-snapshot" "-device" "virtio-rng-pci" "-enable-kvm" "-cpu" "host,migratable=off" "-m" "4096" "-smp" "2" "-device" "e1000,netdev=net0" "-netdev" "user,id=net0,host=10.0.2.10,hostfwd=tcp::1025-:22" "-drive" "file=/home/yuhan/workdir/stretch.img,index=0,media=disk" "-kernel" "/home/yuhan/workdir/bzImage" "-append" "root=/dev/sda console=ttyS0 kvm-intel.nested=1 kvm-intel.unrestricted_guest=1 kvm-intel.vmm_exclusive=1 kvm-intel.fasteoi=1 kvm-intel.ept=1 kvm-intel.flexpriority=1 kvm-intel.vpid=1 kvm-intel.emulate_invalid_guest_state=1 kvm-intel.eptad=1 kvm-intel.enable_shadow_vmcs=1 kvm-intel.pml=1 kvm-intel.enable_apicv=1 earlyprintk=serial oops=panic nmi_watchdog=panic panic_on_warn=1 panic=1 ftrace_dump_on_oops=orig_cpu vsyscall=native net.ifnames=0 biosdevname=0" "-device" "ivshmem-plain,memdev=hostmem0" "-object" "memory-backend-file,size=4194304,share,mem-path=/dev/shm/healer-in_shm-0-35410,id=hostmem0" "-device" "ivshmem-plain,memdev=hostmem1" "-object" "memory-backend-file,size=16777216,share,mem-path=/dev/shm/healer-out_shm_0-35410,id=hostmem1"
    STDERR:
    qemu-system-x86_64: error: failed to set MSR 0x48f to 0x7fffff00036dfb
    qemu-system-x86_64: /build/qemu-A1914X/qemu-4.2/target/i386/kvm.c:2691: kvm_buf_set_msrs: Assertion `ret == cpu->kvm_msr_buf->nmsrs' failed.

解决方案

找到healer-main/healer_utils/healer_vm/src/qemu.rs,这是healer中关于qemu的配置文件。将“linux/amd64”的对应参数args改为:"-enable-kvm"(下图中的第487行)。

image-20211129152303710
:2691: kvm_buf_set_msrs: Assertion `ret == cpu->kvm_msr_buf->nmsrs’ failed.

参考链接

  1. https://github.com/SunHao-0/healer
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yuhan_2001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值