首页
社区
课程
招聘
[原创]从0到1开始使用syzkaller进行Linux内核漏洞挖掘
发表于: 2021-1-18 22:39 32931

[原创]从0到1开始使用syzkaller进行Linux内核漏洞挖掘

2021-1-18 22:39
32931

觉得前面踩坑的过程繁琐可以直接去看过程总结
整个环境搭建的过程踩了很多坑。有不少是网上没提到的,于是我详细记录了一下,希望能帮到以后踩坑的同学。

这里我使用了一个完全全新的Ubuntu18.04来搭建环境。

存储空间分配40G。

安装基本的软件

注意,此时我的gcc版本是 gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)

接下来尝试

然而这一步慢的离谱。。我查了一下-u -d的选项,似乎跟直接git clone没什么区别。

于是我换了个方式,直接使用git clone拉取源码.

然后也慢的离谱。

于是我直接在宿主机上下载了syzkaller.zip,然后复制到虚拟机中直接unzip解压。

然后直接make,发现报错:

使用 dmesg | egrep -i -B100 'killed process' 查看:

发现触发了 OOM-killer ,内存不够。

按照网上的方法建立了一个swap分区:

https://studygolang.com/articles/11781?fr=sidebar

重新编译又报错:

似乎是因为golang版本太低。(1.10)

于是使用wget下载新版本的golang。进行如下操作:

root@ubuntu:~/gopath/src/github.com/google/syzkaller# go version
go version go1.14.2 linux/amd64

接下来把syzkaller.zip在:/root/gopath/src/github.com/google/ 下解压。

make!

又报OOM。

于是我查看了一下,似乎是因为同时编译多个文件造成的?

于是我尝试先单独编译一下第一个文件:

然后在 ./bin/ 下看到了编译好的 syz-manager

于是在进行make。

似乎是成功了。.git产生的fatal不用理他。

./bin/ 下我们看到了如下文件:

应该是编译好了。大概说一下这几个 syz-* 都是干嘛的:

总结一下我此时的环境:

克隆主线 linux 代码,使用

如果太慢可以或者直接去: https://gitee.com/mirrors/linux/repository/archive/master.zip

下载解压好后。

运行如下命令:

编译完就生成了内核,不过这次不同于我们之前make bzImage。这次应该是驱动也编译了。

然后建立一个image文件夹,cd进去

但我这里wget老是失败,于是我直接在这里:https://github.com/google/syzkaller/blob/master/tools/create-image.sh

copy了一份下来运行。

实际上就是先获取arch信息,然后使用 debootstrap 来构建基本的文件系统。

这一步也很慢,不过我寻思文件系统应该可以换成 CTF 题的 rootfs.img,毕竟只要内核对了就行。

漫长的等待后:

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

接下来安装qemu环境:

一般kvm什么的都是自带的。不过如果是vmware可能需要开启一下虚拟化引擎 里的 虚拟化 Intel VT-x/EPT 或 AMD-V/RVI(V)

就在虚拟机的设置界面中。

boot.sh如下:

启动起来后显示:

root@syzkaller:~#

然后poweroff掉。

回到 root@ubuntu:~/gopath/src/github.com/google/syzkaller#

新建my.cfg文件

然后尝试运行 syz-manger发现报错:

猜测是 .git ?的问题,因为我在源码中发现了这样一行:

于是尝试 git init 一下,重新编译。

这次启动起来了。但是http panic了。

定位问题:

切片越界了。本来只有length=4,但是切到了8。

看一下这部分的代码:

这里似乎是一个获取版本的操作。尝试了一下把这个地方从8改成4就可以跑了。但是显示如下

首先看这个revision这里,确实是一个长度为4的字符串,所以切片越界了。

但是底下都显示的0,没跑起来啊。。。

于是我重新在宿主机里挂了一下git的代理:

然后绑定到远程的git仓库。pull下来,处理冲突。

然后重新make。启动。

然而还是这样子。(泪)

突然发现qemu启动的时候似乎在这里有一些问题,Kernel File Systems mount不上去:

于是查找解决方案:

https://github.com/google/syzkaller/issues/760

按照上面的,删掉那些注释。

重新编译内核生成bzImage

成功!!!

1.网上很多说是必须 gcc 8 的版本,实际并不需要,直接apt安装gcc即可。但是golang版本最好是最新的。当然你可以先apt install golang-go,然后手动升级到最新版本就行。

2.go get -u -d效果跟直接git clone一样的。如果git clone太慢可以挂一下代理。

3.如果你是直接下载的.zip,记得先git init一下,然后绑定到远程仓库。

4.注意编译内核的时候要添加那些选项,并且要把下面那些选项对应的注释删掉!!(比如:# CONFIG_KCOV is not set)要不然会被rewrite掉。。

官方给出了一个如下的overview图片。

图片描述

Syzkaller 采用一套自己的系统调用的描述or声明(syzlang),来操纵fuzz的系统调用序列。

官方给出的语法如下:https://github.com/google/syzkaller/blob/master/docs/syscall_descriptions_syntax.md

这里有已经声明好的:https://github.com/google/syzkaller/blob/master/sys/linux/sys.txt

具体的过程是:

使用syz-extract得到常量和值一一对应的.const文件(例如/sys/linux/tty.txt被转换为sys/linux/tty_amd64.const),然后使用syz-sysgen编译AST(Abstract Syntax Tree,抽象语法树)和常量值,并返回包含生成的prog对象的Prog(根据系统调用模板和第一步中生成的const文件使用syz-sysgen生成syzkaller用的go代码)。syz-sysgen具体又分为下面4步。
    1.assignSyscallNumbers:分配系统调用号,检测不受支持的系统调用并丢弃
    2.patchConsts:将AST中的常量patch成对应的值
    3.check:对AST进行语义检查
    4.genSyscalls:从AST生成prog对象

以上是先知上的 houjingyi 大师傅分析总结的。对应的源码分析的文章链接如下,我这个初学者就不献丑了。。

内核漏洞挖掘技术系列(4)——syzkaller(2)

这部分主要参考 :

bsauce

https://github.com/hardenedlinux/Debian-GNU-Linux-Profiles/tree/master/docs/harbian_qa/fuzz_testing

使用Syzkaller&QEMU捕捉内核堆溢出Demo

整体过程大概如下:

test.c中有一个堆溢出的demo。我们将他编译然后insmod上去。

当我们想要尝试编译内核模块的时候,涉及到一个linux header的问题。(比如说我在5.4.0-62-generic的系统下编译5.11.0-rc3的驱动)

我的解决方案是:

然后make。这里发现了一个问题。

源码中有这样几行:

但是编译的时候会报:

这个版本下:proc_create的最后一个参数要求是 const struct proc_ops * 而不是旧的 const struct file_operations *。

解决方案参照:https://stackoverflow.com/questions/64931555/how-to-fix-error-passing-argument-4-of-proc-create-from-incompatible-pointer

最终我对test.c改动如下:

Makefile如下:

此时可以正常通过编译,生成 test.ko。说明可以正常编译了。

这种不用自己找linux header,然后手动创建的方式屡试不爽orz,很适合调试的时候错版本加载一些内核驱动,之前我调试内核cve的时候也用的这种方式

接下来我们把test.c cp到/linux/drivers/char/下,然后vim /linux/drivers/char/Kconfig,添加如下:

然后make -j64编译。中途看了一眼,刚好发现了:

然后启动:

已经有了。

1.

syzkaller/sys/linux/ 下新建

对应的 proc_operation.txt 如下:

这里我 引用bsauce师傅 的对于调用规则的讲解:

调用规则:$号前的syscallname是系统调用名,$号后的type是指特定类型的系统调用。如上文的 open$proc 指的就是open这个类调用中proc这个具体的调用,这个名字是由规则编写者确定的,具体行为靠的是后面的参数去确定。 参数的格式如下: ArgumentName ArgumentType[Limit] ArgumentName是指参数名,ArgumentType指的是参数类型,例如上述例子有string、flags等类型。[ ]号中的内容就是具体的类型的值,不指定的时候由syzkaller自动生成,若要指定须在后文指定,以上文为例:

​ mode flags[proc_open_mode]

​ proc_open_mode = ...

​ 因为我们给的例子是通过/proc/test这个内核接口的写操作来触发堆溢出,因此我们需要控制的参数是open函数中的file参数为“/proc/test”即可,其他操作参考sys.txt即可。

2.

编译 syz-extract 和 syz-sysgen

接下来我们使用 syz-extract 生成 .const 文件:

生成了 proc_operation.txt.const 内容如下:

重新运行

然后:

重新编译syzkaller。

最后我们修改 my.cfg

加上:

最后

boot起来虚拟机将其拷贝到虚拟机的/root/bin 下。

启动:bin/syz-manager -config my.cfg -vv 10
一段时间后出现:

但不知为什么我这里是空指针未引用orz。。不过确实是跑出来了 /proc/test 的洞。

图片描述
还有这种的:
图片描述

一段时间后:
图片描述
产生了一个c报告。可以直接在里面看对应的产生漏洞c代码(syzkaller生成的)

编译delve时报错\"../../pkg/proc/native/proc_linux.go:170:16: undefined: strings.ReplaceAll\"如何处理?

解决golang编译项目时出现signal: killed

Setup: Ubuntu host, QEMU vm, x86-64 kernel

ubuntu系统debootstrap的使用

Git clone走ss代理

tools/create-image.sh: image does not boot in qemu

在Ubuntu 16.04.6 LTS上升级Go到最新版1.12.5实录

Syzkaller

内核漏洞挖掘技术系列(4)——syzkaller(2)

【漏洞挖掘】使用Syzkaller&QEMU捕捉内核堆溢出Demo

如何将一个驱动编译进内核

 
 
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
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
 
go get -u -d github.com/google/syzkaller/prog
go get -u -d github.com/google/syzkaller/prog
 
git clone https://github.com/google/syzkaller /usr/local/golang/src/github.com/google/syzkaller
git clone https://github.com/google/syzkaller /usr/local/golang/src/github.com/google/syzkaller
 
 
 
 
 
 
 
 
 
vm/vmimpl/merger.go:69:12: undefined: bytes.ReplaceAll
vm/vmimpl/merger.go:69:12: undefined: bytes.ReplaceAll
 
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=/root/gopath
export GOROOT=/root/goroot
export PATH=$GOPATH/bin:$PATH
export PATH=$GOROOT/bin:$PATH #把这几行加到.bashrc中
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=/root/gopath
export GOROOT=/root/goroot
export PATH=$GOPATH/bin:$PATH
export PATH=$GOROOT/bin:$PATH #把这几行加到.bashrc中
 
 
 
 
 
GOOS=linux GOARCH=amd64 go build "-ldflags=-s -w -X github.com/google/syzkaller/prog.GitRevision= -X 'github.com/google/syzkaller/prog.gitRevisionDate='" -o ./bin/syz-manager github.com/google/syzkaller/syz-manager
GOOS=linux GOARCH=amd64 go build "-ldflags=-s -w -X github.com/google/syzkaller/prog.GitRevision= -X 'github.com/google/syzkaller/prog.gitRevisionDate='" -o ./bin/syz-manager github.com/google/syzkaller/syz-manager
 
 
 
 
 
 
 
Ubuntu18.04,内核5.4.0-42-generic
 
 
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
 
 
go version go1.14.2 linux/amd64
Ubuntu18.04,内核5.4.0-42-generic
 
 
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
 
 
go version go1.14.2 linux/amd64
https://mirrors.tuna.tsinghua.edu.cn/git/linux.git
https://mirrors.tuna.tsinghua.edu.cn/git/linux.git
 
 
1.首先:
make CC="/usr/bin/gcc" defconfig
make CC="/usr/bin/gcc" kvmconfig    (这个选项没设置成功?)
 
2.在.config文件中添加
CONFIG_KCOV=y
CONFIG_DEBUG_INFO=y
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y
CONFIG_CONFIGFS_FS=y
CONFIG_SECURITYFS=y
 
3.然后:
make CC="/usr/bin/gcc" olddefconfig
make CC="/usr/bin/gcc" -j64
1.首先:
make CC="/usr/bin/gcc" defconfig
make CC="/usr/bin/gcc" kvmconfig    (这个选项没设置成功?)
 
2.在.config文件中添加
CONFIG_KCOV=y
CONFIG_DEBUG_INFO=y
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y
CONFIG_CONFIGFS_FS=y
CONFIG_SECURITYFS=y
 
3.然后:
make CC="/usr/bin/gcc" olddefconfig
make CC="/usr/bin/gcc" -j64
sudo apt-get install debootstrap
sudo apt-get install 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
wget https://raw.githubusercontent.com/google/syzkaller/master/tools/create-image.sh -O create-image.sh
 
chmod +x create-image.sh
 
./create-image.sh
 
 
 
 
root@ubuntu:~/source/linux/image# ls
chroot  create-image.sh  stretch.id_rsa  stretch.id_rsa.pub  stretch.img
root@ubuntu:~/source/linux/image# ls
chroot  create-image.sh  stretch.id_rsa  stretch.id_rsa.pub  stretch.img
 
sudo apt-get install qemu-system-x86
sudo apt-get install qemu-system-x86
 
 
qemu-system-x86_64 \
 -kernel /root/source/linux/arch/x86/boot/bzImage \
 -append "console=ttyS0 root=/dev/sda debug earlyprintk=serial slub_debug=QUZ"\
 -hda ./stretch.img \
 -net user,hostfwd=tcp::10021-:22 -net nic \
 -enable-kvm \
 -nographic \
 -m 256M \
 -smp 2 \
 -pidfile vm.pid \
 2>&1 | tee vm.log
qemu-system-x86_64 \
 -kernel /root/source/linux/arch/x86/boot/bzImage \
 -append "console=ttyS0 root=/dev/sda debug earlyprintk=serial slub_debug=QUZ"\
 -hda ./stretch.img \
 -net user,hostfwd=tcp::10021-:22 -net nic \
 -enable-kvm \
 -nographic \
 -m 256M \
 -smp 2 \
 -pidfile vm.pid \
 2>&1 | tee vm.log
 
 
 
 
 
2021/01/16 20:57:54 bad syz-manager build: build with make, run bin/syz-manager
2021/01/16 20:57:54 bad syz-manager build: build with make, run bin/syz-manager
if prog.GitRevision == "" {
        log.Fatalf("bad syz-manager build: build with make, run bin/syz-manager")
    }
if prog.GitRevision == "" {
        log.Fatalf("bad syz-manager build: build with make, run bin/syz-manager")
    }
 
 
 
2021/01/17 01:41:29 http: panic serving 127.0.0.1:56498: runtime error: slice bounds out of range [:8] with length 4
goroutine 53 [running]:
net/http.(*conn).serve.func1(0xc00087e780)
    /root/goroot/src/net/http/server.go:1772 +0x139
panic(0x10f68c0, 0xc0004f74a0)
    /root/goroot/src/runtime/panic.go:975 +0x3e3
main.(*Manager).collectStats(0xc000100820, 0x0, 0x0, 0x0)
    /root/gopath/src/github.com/google/syzkaller/syz-manager/html.go:111 +0x106f
2021/01/17 01:41:29 http: panic serving 127.0.0.1:56498: runtime error: slice bounds out of range [:8] with length 4
goroutine 53 [running]:
net/http.(*conn).serve.func1(0xc00087e780)
    /root/goroot/src/net/http/server.go:1772 +0x139
panic(0x10f68c0, 0xc0004f74a0)
    /root/goroot/src/runtime/panic.go:975 +0x3e3
main.(*Manager).collectStats(0xc000100820, 0x0, 0x0, 0x0)
    /root/gopath/src/github.com/google/syzkaller/syz-manager/html.go:111 +0x106f
 
 
 
 

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2021-1-19 23:06 被Roland_编辑 ,原因: test.c为我修改好的文件
上传的附件:
收藏
免费 7
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  Editor   +1.00 2021/01/23 精品文章~
最新回复 (15)
雪    币: 14517
活跃值: (17538)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2021-1-19 08:42
0
雪    币: 15187
活跃值: (16852)
能力值: (RANK:730 )
在线值:
发帖
回帖
粉丝
3
精品,期待下一部
2021-1-19 08:57
0
雪    币: 4168
活跃值: (15932)
能力值: ( LV9,RANK:710 )
在线值:
发帖
回帖
粉丝
4
谢谢师傅们支持
2021-1-19 09:08
0
雪    币: 3475
活跃值: (1350)
能力值: ( LV9,RANK:150 )
在线值:
发帖
回帖
粉丝
5
mark
2021-1-19 09:19
0
雪    币: 12453
活跃值: (9422)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感谢大佬分享~
2021-1-19 10:24
0
雪    币: 156
活跃值: (3801)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
感谢分享,内存40G直接把我劝退了
2021-1-19 22:36
0
雪    币: 4168
活跃值: (15932)
能力值: ( LV9,RANK:710 )
在线值:
发帖
回帖
粉丝
8
TUGOhost 感谢分享,内存40G直接把我劝退了
啊,抱歉,用词不当,不是运行内存40G,是存储空间分40G………
2021-1-19 23:05
0
雪    币: 26245
活跃值: (63297)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
9
感谢分享!mark!
2021-1-23 10:41
0
雪    币: 436
活跃值: (2668)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
感谢分享!mark!
2021-1-26 16:14
0
雪    币: 117
活跃值: (892)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
11
非常好的文章,受益匪浅,跟着作者做了一遍,基本把坑都过了
2021-6-17 17:53
0
雪    币: 80
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
make CC="/usr/bin/gcc" kvmconfig 这里可以用kvm_guest.config,官方教程也改成这个了
2021-7-5 10:00
0
雪    币: 18
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13

师们编译的时候报这种错误有什么解决的办法嘛

cc1: all warnings being treated as errors

make[4]: *** [/root/linux/tools/build/Makefile.build:97:/root/linux/tools/objtool/sigchain.o] 错误 1

  UPD     include/generated/asm-offsets.h

  CALL    scripts/checksyscalls.sh

make[3]: *** [Makefile:59:/root/linux/tools/objtool/libsubcmd-in.o] 错误 2

make[2]: *** [Makefile:63:/root/linux/tools/objtool/libsubcmd.a] 错误 2

make[1]: *** [Makefile:69:objtool] 错误 2

make: *** [Makefile:1364:tools/objtool] 错误 2

                                                                                                







最后于 2022-10-27 20:46 被mb_eiurpggt编辑 ,原因:
2022-10-27 13:23
0
雪    币: 1020
活跃值: (62)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
感谢分享了
2023-1-2 10:43
0
雪    币: 3738
活跃值: (3872)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
15
感谢分享!
2023-1-2 19:40
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
16
mb_eiurpggt 师们编译的时候报这种错误有什么解决的办法嘛cc1: all warnings being treated as errorsmake[4]: *** [/root/linux/tools/build/ ...
gcc版本高了之后,gcc自己的安全检查会导致编译报错,我试过把makefile里面的Werror全删了也不行,最后是换了个gcc-10编译的
2024-8-2 16:01
0
游客
登录 | 注册 方可回帖
返回
//