时时勤拂拭,勿使惹尘埃

TOC

Categories

Syzkaller(一)fuzz Android kernel


0x0 Syzkaller简介

Syzkaller是是一款无监督的覆盖引导Linux内核模糊器,由Google团队开发的开源工具,目前还在不断的维护之中。
Syzkaller支持Android平台,搭配使用KASAN 排错和 KCOV 检测编译的内核版本,可以更有效的检测运行时内存错误以及获取代码覆盖率信息。

0x1 安装编译Syzkaller

安装参考官方文档:32位android64位android
平台:Linux
下载安装golang,其他平台可以去golang官网下载:
//下载安装golang
$ wget https://storage.googleapis.com/golang/go1.11.4.linux-amd64.tar.gz
$ tar -xf go1.11.4.linux-amd64.tar.gz
//添加环境变量
$ export PATH=`pwd`/go/bin:$PATH
//设置golang工作目录
$ mkdir gopath
$ export GOPATH=`pwd`/gopath
//下载syzkaller
$ go get -u -d github.com/google/syzkaller/...
//进入syzkaller源码目录
$ cd gopath/src/github.com/google/syzkaller/
//创建编译目录
$ mkdir workdir
编译32位syzkaller:
$ make TARGETOS=linux TARGETARCH=arm
编译64位syzkaller:
//如果有老版本Android /dev/ion驱动,先编译
$ cp sys/android/* sys/linux
$ make generate
//编译64位syzkaller
$ make TARGETOS=linux TARGETARCH=arm64
坑-缺少交叉编译环境
  • aarch64-linux-gnu-gcc: Command not found
    • 缺少交叉编译工具,安装即可
      • $ sudo apt-get install gcc-aarch64-linux-gnu
      • 32位安装gcc-arm-linux-gnueabihf
  • aarch64-linux-gnu-gcc: error trying to exec ‘cc1plus’: execvp: No such file or directory
    • gcc缺少对应版本g++,安装即可
      • $ sudo apt install g++-aarch64-linux-gnu
      • 32位安装g++-arm-linux-gnueabihf
编译完成后会在./bin目录下生成以下程序:
$ ls -ahl bin/
total 275M
drwxr-xr-x  3 root root 4.0K Jan  4 02:33 .
drwxr-xr-x 19 root root 4.0K Jan  4 02:28 ..
drwxr-xr-x  2 root root 4.0K Jan  4 15:47 linux_arm64
-rwxr-xr-x  1 root root  34M Jan  4 15:47 syz-db
-rwxr-xr-x  1 root root  48M Jan  4 15:47 syz-manager
-rwxr-xr-x  1 root root  34M Jan  4 15:47 syz-mutate
-rwxr-xr-x  1 root root  34M Jan  4 15:47 syz-prog2c
-rwxr-xr-x  1 root root  47M Jan  4 15:47 syz-repro
-rwxr-xr-x  1 root root  47M Jan  4 15:47 syz-runtest
-rwxr-xr-x  1 root root  34M Jan  4 15:47 syz-upgrade

0x2 使用syzkaller fuzz Android kernel

编辑配置文件my.cfg,32位:
{
 "target": "linux/arm",
 "http": "127.0.0.1:50000",
 "workdir": "./workdir",
 "kernel_obj": "$KERNEL",
 "syzkaller": ".",
 "sandbox": none,
 "procs": 1,
 "type": "adb",
 "cover": false,
 "vm": {
  "devices": [$DEVICES],   //设备id
  "battery_check": false
 }
}
编辑配置文件my.cfg,64位:
{
 "target": "linux/arm64",
 "http": "localhost:50000",
 "workdir": "./workdir",
 "syzkaller": ".",
 "sandbox": "none",
 "procs": 8,
 "cover": false,  //关闭coverage
 "type": "adb",
 "vm": {
  "devices": ["ABCD000010"],   //设备id
  "battery_check": false
 }
}
坑-adb no permissions
  • adb连接设备提示user * is not in the plugdev goup
    • linux下需要添加包含 USB 配置的 udev 规则文件,参考Android官方说明
      • 如下添加udev 规则文件,再重新打开Android设备的USB调试
        $ sudo vi /etc/udev/rules.d/51-android.rules
        //通用参数
        SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0666"
        $ sudo chmod a+r /etc/udev/rules.d/51-android.rules
        
执行fuzz,如果syz-manager启动后遇到问题,可以使用-debug参数查看信息:
$ ./bin/syz-manager -config=my.cfg
坑-fuzzer启动问题
  • adb默认写入文件路径/data/syz-fuzzer需要root权限
    • 修改对应源码 or 使用userdebug编译版本
      • 但Syzkaller依赖dmesg监控kernel信息,shell用户无权限执行
  • coverage is not supported (CONFIG_KCOV is not enabled)
    • 需要使用KASAN+KCOV 编译的内核版本,或者my.cfg中添加"cover": false,参数关闭coverage
fuzz开始后,除了终端会输出log,浏览器打开设置的localhost:50000也能看到结果展示界面,包括系统调用的覆盖量、syzkaller生成的程序数量、内核被crash的日志报告等调试信息。
如下图,fuzz执行20分钟后,发现了同一类型的crash共26个: