一、简述

Syzkaller是Google开发的一款内核模糊测试工具,简单点说就是自动化向内核输入各种有效的、无效的、完全随机化的参数数据,并观察内核的运行状况,是否发生了panic、内存泄漏等问题,以此发现隐藏在内核中的漏洞。近些年很多内核的CVE发现均来自于此,该工具的开发维护也相对活跃。它不仅支持x86,还支持ARM、Power、MIPS等处理器,而且不仅支持Linux,还支持windows、FreeBSD、Fuchsia等系统,同时还能支持对远程物理机、本地虚拟机的测试,此外还能支持分布式多机器测试。

本篇文章侧重于使用,并无太多原理与代码分析,仅需一点linux使用基础即可,适合用于syzkaller入门,整个环境搭建和使用过程踩了很多坑,有不少是网上没提到的。

二、基础环境

【一>所有资源获取<一】
1、网络安全学习路线
2、电子书籍(白帽子)
3、安全大厂内部视频
4、100份src文档
5、常见安全面试题
6、ctf大赛经典题目解析
7、全套工具包
8、应急响应笔记

三、环境搭建

3.1 Ubuntu虚拟机配置

Ubuntu虚拟机配置如下图所示,因为需要编译Linux内核与syzkaller所以内存尽量的设置大一些。

Vmware自带的vmtools安装在Ubunut1804上不能与物理机之间互相拷贝文件可以尝试如下命令解决:

sudo apt update
sudo apt install open-vm-tools-desktop fuse

3.2 安装基本软件

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
sudo apt-get install g++
sudo apt-get install build-essential
sudo apt install gcc
sudo apt install openssh-server

安装go编程语言并没有使用apt install golang-go,使用apt安装的go编程语言版本为1.10,使用这个版本的go会在编译syzkaller时报错,所以在这选择下载安装1.17版本的go。

wget https://dl.google.com/go/go1.17.6.linux-amd64.tar.gz
tar -zxvf go1.17.6.linux-amd64.tar.gz
export GOPATH=/home/test/git/go/go //路径替换为自己虚拟机中的路径
export GOROOT=/home/test/git/go/go
export PATH=$GOPATH/bin:$PATH
export PATH=$GOROOT/bin:$PATH

运行go命令可以执行,即为安装成功。

3.3 编译syzkaller

使用下面的命令拉取编译syzkaller代码。

git clone https://github.com/google/syzkaller.git
cd syzkaller
make //这一步有可能会报错

如果出现卡死或killed process,使用dmesg | egrep -i -B100 ‘killed process’查看,如果为Out of memory即为内存不足。这时可以先使用如下命令单独编译第一个文件:

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

查看bin目录下是否有编译好的syz-manager文件:

继续使用make命令完成编译,如下图所示:

如果单独编译第一个文件之后还是存在内存不足的问题,可以通过添加swap分区解决。

dd if=/dev/zero of=/root/swapfile bs=1M count=1024 //创建要作为swap分区的文件:增加1GB大小的交换分区,则命令写法如下,其中的count等于想要的块的数量(bs*count=文件大小)。
mkswap /root/swapfile #建立swap的文件系统
swapon /root/swapfile #启用swap文件
/root/swapfile swap swap defaults 0 0 //使系统开机时自启用,在文件/etc/fstab中添加

3.4 编译Linux内核

git拉取linux代码:

git clone https://mirrors.tuna.tsinghua.edu.cn/git/linux.git
cd linux

如果拉取代码的时候报证书校验错误如下图所示:

通过如下命令解决:

sudo apt update
sudo apt install -y libgnutls30

进入linux目录后使用如下命令进行配置:

make CC="/usr/bin/gcc" defconfig
make CC="/usr/bin/gcc" kvm_guest.config

配置完成后打开当前目录下的.config文件进行手动添加配置,添加内容如下:

CONFIG_KCOV=y
CONFIG_DEBUG_INFO=y
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y
CONFIG_CONFIGFS_FS=y
CONFIG_SECURITYFS=y

再执行如下命令:
make CC="/usr/bin/gcc" olddefconfig

如果出现如下图所示:

再次打开.config文件发现刚才添加的配置被删除了,那是因为配置文件中存在如下图所示:

重新执行olddefconfig之前的所有配置命令,然后在.config文件中,删除我们想添加配置的注释命令所在的行如:# CONFIG_KCOV is not set,最后在上面重新添加配置,然后执行make CC=”/usr/bin/gcc” olddefconfig命令可以发现不会出现warning。

如果不删除在之后进行qemu虚拟化时会出现Failed to start Remount Root and Kernel File Systems的错误。

最后执行如下命令即可完成编译。
make CC="/usr/bin/gcc" -j64

3.5 制作文件系统

使用如下命令:

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命令下载文件失败,可以直接浏览器访问拷贝一份也不影响使用。

可以看到目录下出现stretch.id_rsa、stretch.id_rsa.pub、stretch.img文件即为成功。

3.6 运行syzkall

这里需要打开Vmware虚拟机的虚拟化。

安装qemu虚拟工具。

sudo apt-get install qemu-system-x86

在当前目录创建boot.sh文件,文件内容如下:

qemu-system-x86_64 \
-kernel 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 2560M \
-smp 2 \
-pidfile vm.pid \
2>&1 | tee vm.log

运行boot.sh,出现Failed to start Remount Root and Kernel File Systems是上面配置文件没配置好,出现不能访问KVM为虚拟机设置问题。

运行qemu虚拟机有登录提示输入root如下图所示,无密码登录。

在Vmware虚拟机使用如下命令,以是否能登录qemu虚拟机判断qemu虚拟机的ssh服务是否成功启动(syzkaller需要使用ssh)。

ssh -i stretch.id_rsa -p 10021 -o "StrictHostKeyChecking no" root[@localhost](https://github.com/localhost "@localhost")

进入之前下载的syzkaller目录,创建my.cfg配置文件,文件内容如下:

{
"target": "linux/amd64",
"http": "127.0.0.1:56741",
"workdir": "/home/test/git/syzkaller/workdir",
"kernel_obj": "/home/test/git/linux",
"image": "/home/test/git/stretch.img",
"sshkey": "/home/test/git/stretch.id_rsa",
"syzkaller": "/home/test/git/syzkaller",
"procs": 8,
"type": "qemu",
"vm": {
"count": 4,
"kernel": "/home/test/git/linux/arch/x86/boot/bzImage",
"cpu": 2,
"mem": 2048
}
}

使用./bin/syz-manager -config my.cfg命令运行。运行时稍微有些慢需要等待一下。

四、解决Failed to start Raise network interfaces错误

执行syz-manager或qemu模拟运行的时候经常会出现Failed to start Raise network interfaces错误。

执行boot.sh脚本,运行起虚拟机,执行ifconfig命令,发现不存在此命令。

目前qemu虚拟机ping不通外网不能使用apt命令进行安装,所以这里选择下载net-tools离线包编译好,拷贝进qemu虚拟机。

qemu虚拟机初始有默认的ip为10.0.2.15,同时也会初始化物理机ip为10.0.2.2。

可以使用如下命令进行文件拷贝操作:

ip link set enp0s3 up
scp -r [test@10.0.2](mailto:test@10.0.2).2:/home/test/Desktop/net-tools-2.10 ./

拷贝完成后就可以执行ifconfig命令了,如下图所示:

当使用boot.sh脚本运行qemu虚拟机,出现报错Failed to start Raise network interfaces的时候,再次执行ifconfig命令发现只存在lo网卡、enp0s3网卡未启动或未分配ip地址。进行删除qemu虚拟机中的/etc/network/interfaces文件,新建interfaces文件,文件内容如下,拷贝到到qemu虚拟机/etc/network/interfaces路径。

auto eth0
iface eth0 inet dhcpauto enp0s3
iface enp0s3 inet dhcp

多次使用boot.sh启动qemu虚拟机,有时报错Failed to start Raise network interfaces,然后使用ifconfig命令查看结果依旧存在ip地址。

本机网卡名不为eth0可以使用如下命令进行更改:

ip link set ens33 down ip link set ens33 name eth0 ip link set eth0 up

再次使用syzkaller 进行fuzz,效果会好很多,至于根本原因笔者目前也并未分析源码,以后可能会更新。

五、fuzz Linux驱动程序

5.1 编译驱动

在test.c中存在一个堆溢出的demo:

编译内核模块的时候,涉及到一个linux header的问题。(比如说我在5.4.0的系统下编译5.17的驱动)所以这里的Makefile如下:

CONFIG_MODULE_SIG=nobj-m += test.oEXTRA_CFLAGS += -fno-stack-protector -no-pie
all:
make -C /lib/modules/5.17.0-rc3-00316-gb81b1829e7e3/build M=$(PWD) modules

创建目录test,将test.c和Makefile拷贝到目录下,运行make命令。

如果找不到
/lib/modules/5.17.0-rc3-00316-gb81b1829e7e3路径,在linux源代码目录下执行make modules_install /lib/module命令即可。

将test.c拷贝到linux/drivers/char目录下:

在char目录下的Kconfig文件中添加如下配置:

config TEST_MODULE
tristate "Heap Overflow Test"
default y
help
This file is to test a buffer overflow.

在char目录下的Makefile中添加obj-$(CONFIG_TEST_MODULE) += test.o

进入linux源码目录重新make,编译后使用boot.sh启动虚拟机,进入proc目录,可以看到test,表明成功编译代码并加载。

5.2 添加syzkaller规则

进入syzkaller/sys/linux/目录,新建proc_operation.txt,文件内容如下所示:

include <linux/fs.h>open$proc(file ptr[in, string[“/proc/test”]], flags flags[proc_open_flags], mode flags[proc_open_mode]) fd
read$proc(fd fd, buf buffer[out], count len[buf])
write$proc(fd fd, buf buffer[in], count len[buf])
close$proc(fd fd)proc_open_flags = O_RDONLY, O_WRONLY, O_RDWR, O_APPEND, FASYNC, O_CLOEXEC, O_CREAT, O_DIRECT, O_DIRECTORY, O_EXCL, O_LARGEFILE, O_NOATIME, O_NOCTTY, O_NOFOLLOW, O_NONBLOCK, O_PATH, O_SYNC, O_TRUNC, __O_TMPFILE
proc_open_mode = S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH

回到syzkaller目录,编译syz-extract和syz-sysgen:

make bin/syz-extract
make bin/syz-sysgen

使用syz-extract生成.const文件:

bin/syz-extract -os linux -sourcedir "/home/test/git/linux" -arch amd64 proc_operation.txt

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

接下来执行如下命令:

bin/syz-sysgen
make clean
make //这里参考上面`修改my.cfg文件,在其中加上如下字段:`"enable_syscalls": [
"open$proc",
"read$proc",
"write$proc",
"close$proc"
],

5.3 fuzz linux 驱动程序

使用bin/syz-manager -config my.cfg命令:

syzkaller将其识别为空指针解引用错误。

六、总结

从使用体验来讲这个框架进行漏洞发掘还是存在一定难度,尤其对一些具有复杂接口的内核模块来说更是如此,并且是使用go编写的增加了学习成本,但它确实挖出了不少漏洞值得学习。

web安全之挖掘Linux内核漏洞相关推荐

  1. 零基础syzkaller挖掘Linux内核漏洞

    网络安全,web,Kali,渗透测试相关课件,工具,资料 可以关注公众号:"掌控安全课堂" 回复:"我想学黑客"即可免费获得 作者:维阵漏洞研究员--km1ng ...

  2. 103.网络安全渗透测试—[权限提升篇1]—[Linux内核漏洞提权]

    我认为,无论是学习安全还是从事安全的人,多多少少都有些许的情怀和使命感!!! 文章目录 一.LINUX 内核漏洞提权 1.漏洞背景: 2.漏洞利用: (1)实验环境 (2)靶机链接 (3)突破MIME ...

  3. Linux内核漏洞精准检测如何做?SCA工具不能只在软件层面

    摘要:二进制SCA工具要想更好的辅助安全人员实现安全审计.降低漏洞检测的误报率,必须向更细颗粒度的检测维度发展,而不仅仅停留在开源软件的层面,同时对漏洞库的要求也需要向细颗粒度的精准信息提出的挑战. ...

  4. Linux 内核漏洞暴露栈内存,造成数据泄露

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士 思科 Talos 团队最近在 Linux 内核中发现了一个信息泄露漏洞 (CVE-2020-28588). Linux 内核是类 Unix ...

  5. 三个已存在15年的 Linux 内核漏洞

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 Linux 内核的 iSCSI 子系统中存在三个漏洞,可导致具有普通用户权限的本地攻击者获得未修复 Linux 系统的 root 权限 ...

  6. Pwn2Own 2020 曝出的Linux 内核漏洞已修复

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 周二,ZDI 发布安全公告称, Pwn2Own 2020 黑客大赛上被用于在 Ubuntu Desktop上将权限提升至 root 的 ...

  7. 异域linux内核漏洞,Linux内核再现漏洞!这次11年后才发现

    原标题:Linux内核再现漏洞!这次11年后才发现 还记得上一次Linux内核出现大的漏洞是什么时候吗?2009年Linux内核出现严重安全漏洞,直到2014年才被发现,这个严重安全漏洞整整存在了5年 ...

  8. 22岁精神小伙居然利用 Linux 内核漏洞实现 Docker 逃逸

    1 前言 Docker是时下使用范围最广的开源容器技术之一,具有高效易用等优点.由于设计的原因,Docker天生就带有强大的安全性,甚至比虚拟机都要更安全,但如此的Docker也会被人攻破,Docke ...

  9. 获取linux内核基址,Linux内核漏洞利用技术:覆写modprobe_path

    0x00 前言 如果大家阅读过我此前发表的Linux内核漏洞利用的相关文章,可能会知道我们最近一直在学习这块内容.在过去的几周里,我的团队参加了DiceCTF和UnionCTF比赛,其中都包括了Lin ...

最新文章

  1. 现代软件工程 结对编程 (I) 三维棋类游戏
  2. 派森编程软件python-零基础学习Python需要用什么开发工具?
  3. Maven 多模块项目,多个root解决方法
  4. qrcode——js生成二维码
  5. DOS中判断进程是否存在的方法
  6. mac 环境变量设置
  7. 揭秘微信「扫一扫」识物为什么这么快?
  8. html5 学习笔记三(web存储)
  9. leetcode1046. 最后一块石头的重量(堆)
  10. 网段和子网的区别_电焊石笼网与普通石笼网区别
  11. [react] props.children.map和js的map有什么区别?为什么优先选择react的?
  12. java创建response对象_javaweb入门-----request与response的作用
  13. Java基础学习总结(93)——Java编码规范之代码性能及惯例
  14. 淡入淡出效果 (jQuery)
  15. Python open()函数文件打开、读、写基础操作
  16. 2019 序列号_苹果序列号知识扫盲:iPhone序列号含义与查询真伪全攻略
  17. 真是恍然大悟啊!java从入门到精通pdf百度云
  18. Oracle 11g Rac搭建
  19. python-opencv尺寸测量
  20. 从物联网到元宇宙-李正海在物联网大会上的发言

热门文章

  1. 用oracle database作为hvr的hub的一个注意点
  2. 模拟电子技术经验公式-放大的概念和放大电路的主要性能指标
  3. Java学习笔记(持续更新中)
  4. 基于5G的仓储信息化解决方案2022
  5. 人们的烦躁症,来自于社会结构的不稳定
  6. 怎么录制视频教程?课件录制分享
  7. 七夕给自己的礼物-上线排盘小程序
  8. 通用版路由器设置:华硕路由器设置图解
  9. 多媒体编程——屏幕截图
  10. 2006-京淘Day01