syzkaller


环境搭建

首先要解决翻墙的问题,翻不出去go就配不成;

#安装go
wget https://go.dev/dl/go1.23.9.linux-amd64.tar.gz #最好换成最新的版本
tar -xf go1.23.9.linux-amd64.tar.gz #解压go包
export GOROOT=/path/to/go #设置环境变量GOROOT,是go包解压的位置,这里边有可执行文件/bin/go
export GOPATH=/path/to/gopath #随便一个空文件,用于存放go配置过程中生成的一些文件
export PATH=GOROOT:$PATH
export PATH=gopath:$PATH

git clone https://github.com/google/syzkaller.git
cd syzkaller
make

问题一:

1745211745888

解决方法:

直接修改go.mod文件,将版本中的最后一位删掉;

问题二:

1747983447802

应该就是前面配置过程中有残留,将goroot删除,重新配一个go就好了;

问题三:

1748312082276

就是之前的gopath没清空导致的,记得检查GOPATH环境变量设置的是哪一个;

Go包被墙

虚拟机使用主机VPN

https://blog.xzr.moe/archives/124/#section-3

https://yumi1.top/linux-proxy/index.html#%E8%99%9A%E6%8B%9F%E6%9C%BA%E8%AE%BE%E7%BD%AE

1745213477706

使用代理

https://goproxy.cn/

1745217974678

export GO111MODULE=on
export GOPROXY=https://goproxy.cn

最终生效的方法

首先在clash中打开几个配置:

  1. Allow LAN
  2. System Proxy
  3. 固定端口号(我现在是7890)

然后用ipconfig命令查看本地的WLAN地址:

1748068785697

最后加入环境变量:

export http_proxy=http://10.201.104.16:7890
export https_proxy=http://10.201.104.16:7890

syzcaller的使用

编译内核

# Coverage collection.
CONFIG_KCOV=y # must

# Debug info for symbolization.
CONFIG_DEBUG_INFO=y

# Memory bug detector
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y

# Code coverage works better when KASLR Is disabled
# CONFIG_RANDOMIZE_BASE is not set

# 可选
CONFIG_KCOV_INSTRUMENT_ALL=y
CONFIG_KCOV_ENABLE_COMPARISONS=y
CONFIG_DEBUG_FS=y

CONFIG_DEBUG_KMEMLEAK=y
make olddefconfig
make -j4

fuzz nf_tables的内核编译配置:

# Coverage collection.
CONFIG_KCOV=y # must

# Debug info for symbolization.
CONFIG_DEBUG_INFO=y

# Memory bug detector
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y

# Code coverage works better when KASLR Is disabled
# CONFIG_RANDOMIZE_BASE is not set

# 可选
CONFIG_KCOV_INSTRUMENT_ALL=y
CONFIG_KCOV_ENABLE_COMPARISONS=y
CONFIG_DEBUG_FS=y

CONFIG_DEBUG_KMEMLEAK=y

CONFIG_USER_NS=y
CONFIG_SECURITY_SELINUX_DISABLE=y
# for debug
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_DEBUG_INFO_DWARF4=y
# for msg_msg copy
CONFIG_CHECKPOINT_RESTORE=y
# for syzkaller image
CONFIG_CONFIGFS_FS=y
CONFIG_SECURITYFS=y

CONFIG_SLAB_FREELIST_RANDOM=n
CONFIG_SLAB_FREELIST_HARDENED=n
CONFIG_SHUFFLE_PAGE_ALLOCATOR=n
CONFIG_HARDENED_USERCOPY=n
CONFIG_FORTIFY_SOURCE=n
CONFIG_STATIC_USERMODEHELPER=n
CONFIG_DEBUG_INFO_NONE=n
CONFIG_RANDOMIZE_BASE=n

CONFIG_DEBUG_INFO=y #调试

CONFIG_NETFILTER=y
CONFIG_NF_TABLES=y

创建img

sudo apt-get install debootstrap
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

最终会得到如下文件:

1748064314916

qemu启动内核

用如下命令启动:(不用输入密码登录,想登录的话也是直接root用户名+无密码即可)

qemu-system-x86_64 \
-m 2G \
-smp 2 \
-kernel ./bzImage \
-append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \
-drive file=/home/qym/image/bullseye.img,format=raw -net user,hostfwd=tcp:127.0.0.1:10021-:22 \
-net nic,model=e1000 \
-enable-kvm \
-nographic \
-pidfile vm.pid 2>&1 | tee vm.log

然后利用我们创建镜像时生成的ssh密钥,就可以直接连接了:

ssh -p 10021 -i ~/image/bullseye.id_rsa root@127.0.0.1

运行syzkaller

首先在syzkaller目录下,新建一个workdir目录:

mkdir workdir
./bin/syz-manager -config=a.cfg

编写cfg文件如下:

{
"target": "linux/amd64",
"http": "127.0.0.1:10021",
"workdir": "/home/qym/syzkaller/workdir",
"kernel_obj": "/home/qym/linux-8bb7eca972ad531c9b149c0a51ab43a417385813",
"image": "/home/qym/image/bullseye.img",
"sshkey": "/home/qym/image/bullseye.id_rsa",
"syzkaller": "/home/qym/syzkaller/",
"procs": 8,
"type": "qemu",
"vm": {
"count": 4,
"kernel": "/mnt/hgfs/kernel/kfuzz/bzImage",
"cpu": 2,
"mem": 2048,
"cmdline": "net.ifnames=0 noapic"
}
}

其中kernel_obj是调试符号vmlinux所在的目录;

运行界面如下:

1748078149952

用浏览器可以访问到:

1748078203524

使用ssh的端口转发:

ssh -L 10021:127.0.0.1:10021 qym@192.168.186.162

1748078456480

即可在本地的浏览器上查看分析结果:

1748078505749

服务器相关

ssh -p 10021 -i /home/qym/qym/image/bullseye.id_rsa root@127.0.0.1
{
"target": "linux/amd64",
"http": "127.0.0.1:10121",
"workdir": "/home/qym/qym/syzkaller/workdir",
"kernel_obj": "/home/qym/qym/source/linux-2c85ebc57b3e1817b6ce1a6b703928e113a90442/",
"image": "/home/qym/qym/image/bullseye.img",
"sshkey": "/home/qym/qym/image/bullseye.id_rsa",
"syzkaller": "/home/qym/qym/syzkaller/",
"procs": 8,
"type": "qemu",
"vm": {
"count": 4,
"kernel": "/home/qym/qym/source/linux-2c85ebc57b3e1817b6ce1a6b703928e113a90442/arch/x86/boot/bzImage",
"cpu": 2,
"mem": 2048
}
}
ssh -L 10121:127.0.0.1:10121 qym@xxx.xxx.xxx.xxx

几个运行时错误

错误一

1748079681005

这表明虚拟机在启动时遇到了 内核 panic,具体原因是 IO-APIC 和定时器不兼容。这类问题通常是因为内核与虚拟机配置之间的硬件兼容性问题,尤其是在使用 QEMU/KVM 模拟时。

在 QEMU 的 -append 参数中添加 noapic,这样它就会禁用 APIC。

{
"target": "linux/amd64",
"http": "127.0.0.1:10021",
"workdir": "/home/qym/syzkaller/workdir",
"kernel_obj": "/home/qym/linux-8bb7eca972ad531c9b149c0a51ab43a417385813",
"image": "/home/qym/image/bullseye.img",
"sshkey": "/home/qym/image/bullseye.id_rsa",
"syzkaller": "/home/qym/syzkaller/",
"procs": 8,
"type": "qemu",
"vm": {
"count": 4,
"kernel": "/mnt/hgfs/kernel/kfuzz/bzImage",
"cpu": 2,
"mem": 2048,
"cmdline": "noapic"
}
}

错误二

1748080577912

应该就是有别的进程在用你的端口,kill掉就行了;

注意syzkaller是会自己启动qemu的;

错误三

遇到一个ssh不能连接的错误:

syzkaller crash: can’t ssh into the instance

参考:https://zhuanlan.zhihu.com/p/678339489

加入如下:

"cmdline": "net.ifnames=0 noapic"

错误四

内存不足会导致kill:

1748087100906

编译多个syzkaller

由于笔者后续想开发属于自己的syzkaller,因此想在机器上同时拥有多个syzkaller,这里记录一下问题;

首先要记得改一下gcc和g++的版本;

还有就是go的问题,笔者发现go似乎要重新安装,因此笔者的解决办法是,在当前目录下再重新安装一个go,创建gopath目录,并通过export命令临时修改一个GOROOT和GOPATH两个环境变量,之后即可成功编译;

最后笔者发现,每次运行新编译的syzkaller的时候不需要export上述两个环境变量;

另外,如果想要重新编译,最好是删除gopath中的内容,(虽然很多非root删除不掉,但是只要删除掉普通用户能够删除的文件就好了)

参考

https://blingblingxuanxuan.github.io/2019/10/26/syzkaller/

https://www.giantbranch.cn/2021/06/25/syzkaller%E7%9A%84%E5%AE%89%E8%A3%85%E4%B8%8E%E8%BF%90%E8%A1%8C/

https://blog.xzr.moe/archives/124/#section-3

https://yumi1.top/linux-proxy/index.html#%E8%99%9A%E6%8B%9F%E6%9C%BA%E8%AE%BE%E7%BD%AE

https://goproxy.cn/

https://v3rdant.cn/Fuzz.Kernel-Fuzz-With-Syzkaller/#%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE

https://bbs.kanxue.com/thread-265405.htm


文章作者: q1ming
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 q1ming !
  目录