觉得前面踩坑的过程繁琐可以直接去看过程总结
整个环境搭建的过程踩了很多坑。有不少是网上没提到的,于是我详细记录了一下,希望能帮到以后踩坑的同学。
这里我使用了一个完全全新的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
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
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
chroot create
-
image.sh stretch.id_rsa stretch.id_rsa.pub stretch.img
root@ubuntu:~
/
source
/
linux
/
image
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
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2021-1-19 23:06
被Roland_编辑
,原因: test.c为我修改好的文件