【漏洞挖掘】使用Syzkaller&QEMU捕捉內(nèi)核堆溢出Demo

參考:

????????使用Syzkaller&QEMU捕捉內(nèi)核堆溢出Demo? ?

????????內(nèi)核漏洞挖掘技術(shù)系列(4)——syzkaller(1)?

????????實驗所需源碼

本文主要參考第一篇文章,但是文章中很多步驟不全面辱魁,而且存在錯誤烟瞧,故記錄本實驗過程。本實驗前提是參照配置syzkaller&QEMU環(huán)境配置好syzkaller環(huán)境染簇。

本文將演示使用Syzkaller聯(lián)合QEMU觸發(fā)一個內(nèi)核溢出的bug参滴。 包括三個步驟:

????????(1)在syzkaller中添加規(guī)則觸發(fā)堆溢出?

????????(2)編譯一個帶有堆溢出模塊的kernel

????????(3)運(yùn)行syzkaller&QEMU捕捉內(nèi)核堆溢出

1.在syzkaller中添加規(guī)則

本例新增調(diào)用模板見proc_operation.txt,/syzkaller/sys/linux目錄下的sys.txt中有通用的調(diào)用形式可以參考锻弓。

解釋:syzkaller使用它自己的聲明式語言來描述系統(tǒng)調(diào)用模板砾赔,docs目錄下的syscall_descriptions.md中可以找到相關(guān)的說明。這些系統(tǒng)調(diào)用模板被翻譯成syzkaller使用的代碼需要經(jīng)過兩個步驟弥咪。第一步是使用syz-extract從linux源代碼中提取符號常量的值过蹂,結(jié)果被存儲在.const文件中十绑,例如/sys/linux/tty.txt被轉(zhuǎn)換為sys/linux/tty_amd64.const聚至。第二步是根據(jù)系統(tǒng)調(diào)用模板和第一步中生成的const文件使用syz-sysgen生成syzkaller用的go代碼”境龋可以在/sys/linux/gen/amd64.go和/executor/syscalls.h中看到結(jié)果扳躬。最后,重新編譯生成帶有相應(yīng)規(guī)則的syzkaller二進(jìn)制可執(zhí)行文件。

調(diào)用規(guī)則:$號前的syscallname是系統(tǒng)調(diào)用名贷币,$號后的type是指特定類型的系統(tǒng)調(diào)用击胜。如上文的 open$proc 指的就是open這個類調(diào)用中proc這個具體的調(diào)用,這個名字是由規(guī)則編寫者確定的役纹,具體行為靠的是后面的參數(shù)去確定偶摔。 參數(shù)的格式如下: ArgumentName ArgumentType[Limit] ArgumentName是指參數(shù)名,ArgumentType指的是參數(shù)類型促脉,例如上述例子有string辰斋、flags等類型。[ ]號中的內(nèi)容就是具體的類型的值瘸味,不指定的時候由syzkaller自動生成宫仗,若要指定須在后文指定,以上文為例:

????????????mode flags[proc_open_mode]

????????????proc_open_mode = ...

????????因為我們給的例子是通過/proc/test這個內(nèi)核接口的寫操作來觸發(fā)堆溢出旁仿,因此我們需要控制的參數(shù)是open函數(shù)中的file參數(shù)為“/proc/test”即可藕夫,其他操作參考sys.txt即可。

步驟

? ? (1)編譯生成syz-extract

? ? ? ? ?~/Desktop/ctf/kernel_fuzz/gopath/src/github.com/google/syzkaller$ make bin/syz-extract

? ? (2)編譯生成syz-sysgen

????????~/Desktop/ctf/kernel_fuzz/gopath/src/github.com/google/syzkaller$ make bin/syz-sysgen

? ? (3)用syz-extract生成.const文件(本例proc_operation.txt有錯誤枯冈,read和write不需要返回值)可選擇只生成你新增的.txt

????????~/Desktop/ctf/kernel_fuzz/gopath/src/github.com/google/syzkaller$ bin/syz-extract -os linux -sourcedir "/home/john/Desktop/ctf/kernel_

fuzz/linux/linux" -arch amd64 sys/linux/proc_operation.txt?

????????同目錄下生成了proc_operation_amd64.const毅贮。

? ? (4)然后運(yùn)行syz-sysgen

????????~/Desktop/ctf/kernel_fuzz/gopath/src/github.com/google/syzkaller$ bin/syz-sysgen

? ? (5)重編譯syzkaller

????????進(jìn)入syzkaller源碼目錄,運(yùn)行:

????????????$ make clean

????????????$ make all

? ? (6)拷貝編譯好的syz-fuzzer到目標(biāo)系統(tǒng):

????????????scp -P 10021 -i ./stretch.id_rsa -r ../gopath/bin root@127.0.0.1:/root/bin

2.編譯帶有堆溢出的內(nèi)核模塊

漏洞:代碼見test.c霜幼,主要是proc_write()函數(shù)有堆溢出嫩码。

編譯:參考https://www.cnblogs.com/zhangjy6/p/5462644.html

????????????$ make

????????????$ scp -P 10021 -i ./stretch.id_rsa -r ./test/test.ko root@127.0.0.1:/root/bin

????????????目標(biāo)機(jī)器上$ sudo insmod test.ko

問題:無法insmod

????????我本機(jī)linux-headers版本是4.4.0-103-generic,目標(biāo)內(nèi)核版本是5.2.0-rc1+(查看版本命令$ uname -r)罪既,編譯出來的driver在目標(biāo)機(jī)上無法ismod铸题,需安裝linux-headers-5.2.0-rc1+。

解決:安裝linux-headers-5.2.0-rc1+方法琢感,先在網(wǎng)頁上找到對應(yīng)版本的headers丢间。

????????$ wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.2-rc1/linux-headers-5.2.0-050200rc1_5.2.0-050200rc1.201905191930_all.deb

????????$ wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.2-rc1/linux-headers-5.2.0-050200rc1-generic_5.2.0-050200rc1.201905191930_amd64.deb

????????$ sudo dpkg -i *.deb

????????修改KDIR =/usr/src/linux-headers-5.2.0-050200rc1-generic

結(jié)果:還是不匹配,很無奈驹针,要么重新編譯內(nèi)核吧烘挫,我選擇linux-4.4.0.184版本,大不了把本機(jī)內(nèi)核也更新為這個版本柬甥。(參考https://www.itsmearunchandel.co.in/linux/ubuntu/upgrade-kernel-version-in-ubuntu.html; 內(nèi)核源碼https://kernel.ubuntu.com/~kernel-ppa/mainline/v4.4.184/)

問題:應(yīng)該更新了也還是不行饮六,linux-headers-5.2.0-050200rc1-generic跟linux-headers-5.2.0-rc1+還是不匹配。

解決:將驅(qū)動模塊編譯進(jìn)內(nèi)核苛蒲。所以要么把模塊編譯到目標(biāo)內(nèi)核卤橄,要么魔改許多module里的數(shù)據(jù)結(jié)構(gòu)進(jìn)行錯版本加載。

????????(參考https://blog.csdn.net/qq_33487044/article/details/81949703https://kouriba.iteye.com/blog/1632767

???????? make menuconfig->Enable loadable module support->Forced module loading(同時關(guān)閉Module versioning support臂外,只開啟前3個)窟扑。

????????修改drvier目錄下的MAKEFILE文件喇颁,在最后一行添加: obj-y += testmod/

????????然后在testmode目錄下,添加一個MAKEFILE 文件嚎货,文件的內(nèi)容為:obj-m := hello.o

步驟如下

????????(1)test.c拷貝到/linux/drivers/char/目錄下

????????(2)/linux/drivers/char/Kconfig下添加

? ? ????????menu "Character devices"? ? ? ? ? ? #已有

? ? ????????config TEST_MODULE

????????????tristate "Heap Overflow Test"? ? ????#在menuconfig中顯示的名字

????????????default y? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #默認(rèn)選項

????????????help

????????????????This file is to test a buffer overflow.

? ? ????????endmenu? ? ? ? ? ? ? #已有

????????(3)/linux/drivers/char/Makefile下添加

? ????????????? obj-$(CONFIG_TEST_MODULE) += test.o

????????(4)如果/linux/drivers/char/是新目錄橘霎,需修改/linux/drivers/Kconfig(加上source "drivers/char/Kconfig");修改/linux/drivers/Makefile(加上obj-$(CONFIG_TEST_MODULE) += char/)殖属。

????????(5)配置文件選擇該模塊$ make menuconfig -> Device Drivers -> Character devices -> Heap Overflow Test? (*表示直接編如內(nèi)核姐叁,M表示模塊形式,)

????????(6)運(yùn)行內(nèi)核洗显,查看模塊是否加載

????????????????$ls /proc/test? 或? ? $dmesg|grep test

3.運(yùn)行syzkaller捕捉溢出

(1)修改my.cfg(只允許某些調(diào)用七蜘,速度更快):

????"enable_syscalls": [

? ? ? ? ? ? ? ? "open$proc",

? ? ? ? ? ? ? ? "read$proc",

? ? ? ? ? ? ? ? "write$proc",

? ? ? ? ? ? ? ? "close$proc"

????????],

(2)運(yùn)行虛機(jī)測試:?

? ? ? ? $ bin/syz-manager -config ./my.cfg? -v 10

????????用瀏覽器打開“127.0.0.1:56741”,運(yùn)行一段時間后出現(xiàn)以下日志:

```

PROC_DEV:into open!

==================================================================

BUG: KASAN: slab-out-of-bounds in copy_from_user arch/x86/include/asm/uaccess.h:698 [inline] at addr ffff88003c1f5e20

BUG: KASAN: slab-out-of-bounds in proc_write+0x64/0x90 drivers/mod_test/test.c:45 at addr ffff88003c1f5e20

Write of size 4096 by task syz-executor0/2569

CPU: 0 PID: 2569 Comm: syz-executor0 Not tainted 4.11.0-rc8+ #23

Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014

Call Trace:

__dump_stack lib/dump_stack.c:16 [inline]

dump_stack+0x95/0xe8 lib/dump_stack.c:52

kasan_object_err+0x1c/0x70 mm/kasan/report.c:164

print_address_description mm/kasan/report.c:202 [inline]

kasan_report_error mm/kasan/report.c:291 [inline]

kasan_report+0x252/0x510 mm/kasan/report.c:347

check_memory_region_inline mm/kasan/kasan.c:326 [inline]

check_memory_region+0x13c/0x1a0 mm/kasan/kasan.c:333

kasan_check_write+0x14/0x20 mm/kasan/kasan.c:344

copy_from_user arch/x86/include/asm/uaccess.h:698 [inline]

proc_write+0x64/0x90 drivers/mod_test/test.c:45

proc_reg_write+0xf6/0x180 fs/proc/inode.c:230

__vfs_write+0x10b/0x560 fs/read_write.c:508

vfs_write+0x187/0x520 fs/read_write.c:558

SYSC_write fs/read_write.c:605 [inline]

SyS_write+0xd4/0x1a0 fs/read_write.c:597

entry_SYSCALL_64_fastpath+0x18/0xad

RIP: 0033:0x450a09

RSP: 002b:00007ff6efd15b68 EFLAGS: 00000216 ORIG_RAX: 0000000000000001

RAX: ffffffffffffffda RBX: 00000000006f8000 RCX: 0000000000450a09

RDX: 0000000000000090 RSI: 0000000020d09000 RDI: 0000000000000005

RBP: 0000000000000046 R08: 0000000000000000 R09: 0000000000000000

R10: 0000000000000000 R11: 0000000000000216 R12: 0000000000000000

R13: 00007ffc210fd8ff R14: 00007ff6efd16700 R15: 0000000000000000

Object at ffff88003c1f5e20, in cache kmalloc-512 size: 512

...

Dumping ftrace buffer:

? (ftrace buffer empty)

Kernel Offset: disabled

```

????????這就是內(nèi)核被crash時打印出來的調(diào)用信息墙懂,我們可以看到溢出發(fā)生在proc_write+0x64/0x90 drivers/mod_test/test.c:45處橡卤,也就是我們添加進(jìn)去的帶有堆溢出的模塊。說明我們用Syzkaller添加規(guī)則捕捉到了堆溢出的代碼损搬。

? ? ? ? 結(jié)果我啥都沒跑出來碧库。

syzkaller網(wǎng)頁顯示
syzkaller所跑的syscall

4.漏洞復(fù)現(xiàn)

????????workdir/crashes目錄下包含crash之前執(zhí)行的程序。/tools目錄下幾個工具值得關(guān)注:syz-execprog以各種模式執(zhí)行單個或一組程序巧勤,首先在循環(huán)中運(yùn)行l(wèi)og中所有的程序來確認(rèn)確實它們之一引發(fā)了crash嵌灰。

????????$./syz-execprog -executor=./syz-executor -repeat=0 -procs=16 -cover=0 crash-log

????????然后嘗試識別是哪個程序?qū)е碌腸rash。

????????$./syz-execprog -executor=./syz-executor -repeat=0 -procs=16 -cover=0 single-program

????????syz-execprog在本地執(zhí)行程序颅悉,所以需要將syz-execprog和syz-executor復(fù)制到帶有測試內(nèi)核的VM中并在那里運(yùn)行它沽瞭。一旦確認(rèn)了引發(fā)崩潰的單個程序,嘗試通過注釋掉單個系統(tǒng)調(diào)用并刪除無關(guān)的數(shù)據(jù)來縮小范圍剩瓶。還可以嘗試將所有mmap調(diào)用合并為一個驹溃。給syz-execprog加上-threaded=0 -collide=0標(biāo)志確認(rèn)這個程序仍然能夠?qū)е耤rash。

????????如果不能復(fù)現(xiàn)的話延曙,嘗試把每個系統(tǒng)調(diào)用移到單獨(dú)的線程中[4]豌鹤。然后通過syz-prog2c得到C程序,C程序應(yīng)該也可以導(dǎo)致crash枝缔。這個過程在某種程度上也可以通過syz-repro自動化布疙,需要提供config文件和crash報告。

$./syz-repro -config my.cfg crash-qemu-1-1455745459265726910

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末愿卸,一起剝皮案震驚了整個濱河市灵临,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌趴荸,老刑警劉巖儒溉,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異赊舶,居然都是意外死亡睁搭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進(jìn)店門笼平,熙熙樓的掌柜王于貴愁眉苦臉地迎上來园骆,“玉大人,你說我怎么就攤上這事寓调⌒客伲” “怎么了?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵夺英,是天一觀的道長晌涕。 經(jīng)常有香客問我,道長痛悯,這世上最難降的妖魔是什么余黎? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮载萌,結(jié)果婚禮上惧财,老公的妹妹穿的比我還像新娘。我一直安慰自己扭仁,他們只是感情好垮衷,可當(dāng)我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著乖坠,像睡著了一般搀突。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上熊泵,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天仰迁,我揣著相機(jī)與錄音,去河邊找鬼顽分。 笑死轩勘,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的怯邪。 我是一名探鬼主播绊寻,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼悬秉!你這毒婦竟也來了澄步?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤和泌,失蹤者是張志新(化名)和其女友劉穎村缸,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體武氓,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡梯皿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年仇箱,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片东羹。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡剂桥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出属提,到底是詐尸還是另有隱情权逗,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布冤议,位于F島的核電站斟薇,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏恕酸。R本人自食惡果不足惜堪滨,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蕊温。 院中可真熱鬧椿猎,春花似錦、人聲如沸寿弱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽症革。三九已至筐咧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間噪矛,已是汗流浹背量蕊。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留艇挨,地道東北人残炮。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像缩滨,于是被迫代替她去往敵國和親势就。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,969評論 2 355