LWN: 再次審視 syzbot 報出的問題!
關(guān)注了就能看到更多這么棒的文章哦~
Scrutinizing bugs found by syzbot
By Jake Edge
October 13, 2021
LSSNA
DeepL assisted translation
https://lwn.net/Articles/872649/
syzbot kernel-fuzzing system (內(nèi)核模糊測試系統(tǒng))發(fā)現(xiàn)了許多 bug,但是,由于其中不少 bug 看起來嚴重性相對比較低,因此在開發(fā)者這邊注重度較低。在最近舉行的北美 Linux 安全峰會(Linux Security Summit North America)上的一個講座介紹了一些針對 syzbot 所發(fā)現(xiàn)的錯誤進行進一步研究的工作,結(jié)果相當(dāng)令人擔(dān)憂。與其被稱為是一堆很難被攻擊者利用或不可能利用的 bug,其實事實上有許多更嚴重的問題潛伏在其中。
SyzScope
峰會第一天的第一位演講者是加州大學(xué)河濱分校的博士生 Xiaochen Zou,他介紹了他和他的同事對 syzbot (它使用 syzkaller coverage-guided fuzzer)在 Linux 內(nèi)核中報告的 bug 進行的分析。在過去的四年里,syzbot 報告了大約 4000 個錯誤,其中 3000 個已經(jīng)被修復(fù)。他說,這些錯誤主要分為八類,但其中只有部分類別是表示出現(xiàn)了 security bug。這些都是經(jīng)典的、嚴重的內(nèi)核安全漏洞,比如 free 后仍在使用、多次 free,和越界寫入。它們大多是由 syzkaller 檢測中的 Kernel Address Sanitizer(KASAN)發(fā)現(xiàn)的。

[Xiaochen Zou]
還有其他幾類也需要修復(fù)的 bug,但它們往往得到的關(guān)注較少。這些 bug 包括 kernel 或者 Sanitizer 里的 assertion 以及 general protection faults(例如無效的指針解析引用)。此外,有些允許讀取內(nèi)存內(nèi)容的 bug 可以導(dǎo)致信息泄露,比如泄露內(nèi)核地址,但這些通常無法用來破壞內(nèi)核,Zou 指出。研究人員將這些歸為低風(fēng)險的漏洞。屬于低風(fēng)險類別的錯誤平均就需要更長的時間來修復(fù),而且也需要更長的時間來 backport 到之前的舊內(nèi)核上。syzbot 報告的 bug 數(shù)量非常多,使得內(nèi)核社區(qū)顧不上在所有地方來完成 fix。
如果那些 fix 速度較慢的錯誤確實是低風(fēng)險的,那也就無所謂了,但研究發(fā)現(xiàn),許多這樣歸類的 bug 實際上并不是低風(fēng)險。除此之外,Syzbot 的報告也并不總是能說明清楚這個 bug 會帶來的全部影響。更糟糕的是,有一些方法可以從這些低風(fēng)險的 bug 中自動發(fā)現(xiàn)更高風(fēng)險的一些后果。SyzScope 就是一個旨在揭示那些被報告為低風(fēng)險類別的錯誤的高風(fēng)險影響的工具。SyzScope 不是為了自動完成完整漏洞入侵(create full exploits),因為已經(jīng)有許多其他研究項目在解決這部分問題了。比如說 FUZE 專注于對那些 use-after-free bug 來進行這類工作,而 KOOBE 是針對越界寫入的漏洞。
Zou 說,研究人員有幾點看法,從而開啟了 SyzScope 的開發(fā)。Syzbot 只顯示它在測試的執(zhí)行路徑中發(fā)現(xiàn)的第一個 bug,通常它就會停止在這里并把這個漏洞報告出來。這樣做是有其合理性的,因為 Syzbot 正在尋找 bug,不一定是要找到與 security 有關(guān)的 bug。但是,它可能會忽略它所報告的 bug 之后的更多、更危險的影響,這可能就會淡化 bug 的風(fēng)險,從而可能導(dǎo)致它不會被優(yōu)先及時地 fix。
他說,即使你讓 fuzzing 測試繼續(xù)往后跑,但其實有幾種類型的后續(xù)影響是它無法發(fā)現(xiàn)的。比如 control-flow hijacking 和寫入某些值或者地址(無論是任意寫入還是受限寫入)都不能被 sanitizers、kernel assertion、或 syzkaller 使用的其他機制檢測到。
他舉了一個例子:KASAN 檢測到的越界讀取,而 syzbot 也報告了出來。這里可以變成向任意地址寫入 null。但是,由于這個檢測依賴于這個越界內(nèi)存位置的中的具體的值,因此 fuzzing 檢測將無法發(fā)現(xiàn)這個問題。只有當(dāng)越界位置的內(nèi)存被專門準備好時,才能達到這個效果。
heap spraying 是一種讓攻擊者用來把內(nèi)存安排成這種形式的技術(shù)。不過,除了寫 null 之外,在 syzbot 相關(guān)漏洞的再后面一些的位置,是采用來自越界內(nèi)存的內(nèi)容作為地址進行的函數(shù)調(diào)用,這也是可以由攻擊者控制的。于是這就會導(dǎo)致 control-flow hijacking 以及對 kernel 的全面攻破。
但后續(xù)這些進一步的影響是由人類中的專家來發(fā)掘出來的,而不是由 syzkaller 或其他工具所發(fā)現(xiàn)的。研究人員希望有一種方法能自動發(fā)現(xiàn)這些類型的問題。Fuzzers 無法像攻擊者常做的那樣來對 use-after-free 或者越界內(nèi)存的內(nèi)容進行控制。
Symbolic execution
有一種技術(shù)就可以完成這種工作:symbolic execution。通過在對程序進行分析中使用 symbolic value 而不是具體的值,就可以通過 symbolic execution 來很有效地模擬出 heap spraying 的結(jié)果。比如它可以算出來需要存儲什么值、以及應(yīng)該把它們放在哪個位置,就可以使得這個函數(shù)能在攻擊者所選擇的位置被調(diào)用。
SyzScope 有兩種操作模式,都是在尋找隱藏在低風(fēng)險報告背后的高風(fēng)險 bug。在第一種模式下,它會對 syzbot 報告的尚未解決的 bug 來進行靜態(tài)分析(static-analysis)以及 symbolic execution。在另一種模式中,它會使用 fuzzing (模糊分析)、static analysis 以及 symbolic execution 來針對已經(jīng) fix 的 bug 進行分析。后者主要加入了 fuzzing 來尋找原來那個 bug 的后續(xù)影響位置,并使用 bug fix patch 來驗證這里發(fā)現(xiàn)的新 bug 是原來那個 bug 的后果。
為了節(jié)省時間,Zou 說他將跳過關(guān)于 static analysis 部分的介紹。這部分是可選的,只是用來協(xié)助 symbolic execution 的步驟。它實際上是一個優(yōu)化而已。
這里使用了一個限制版的 fuzzing 分析來試圖找到與原始 bug 有相同 root cause 的一些其他有錯誤的上下文,然后把這些信息用在 symbolic-execution 中,看看它們是否真的是高風(fēng)險的 bug。與 syzbot 不同的是,這種 fuzzing 處理雖然也使用了 syzkaller,但是并不會在發(fā)現(xiàn) bug 時就停止。相反它會繼續(xù)運行來看看還能發(fā)現(xiàn)什么。這個 fuzzing 檢測會從 syzkaller 生成的的用來展示原始問題的概念驗證性代碼開始,然后使用 "conservative mutating strategy" 來嘗試發(fā)現(xiàn) use-after-free bug、out-of-bound write 等問題。它使用 bug-fix patch 來確定哪些新的上下文是原來的已經(jīng) fix 的 bug 有關(guān)的。如果這些新的上下文中的檢測在使用打了 patch 的內(nèi)核時沒有報錯,那么這些問題就被判定為隱藏在原先 bug report 之下的高風(fēng)險 bug,而當(dāng)時這些 bug 都被按照低風(fēng)險 bug 來處理的。
fuzzer 會用 impact feedback(影響信息反饋)來增強 syzkaller 的代碼覆蓋率反饋(code-coverage feedback)。它希望能找到那些具有較大影響的 bug,以便來找到高風(fēng)險 bug。代碼覆蓋率反饋有時會引導(dǎo) fuzzer 去尋找全新的錯誤,而這并不是他們的工作目標(biāo)。
symbolic execution 階段使用了 QEMU,會在 KASAN 報告問題的地方設(shè)置一個斷點(breakpoint),而且先構(gòu)造并觸發(fā)該 bug。然后啟動 "angr" (他們的 symbolic-execution 引擎)。angr 會從 KASAN 的報告中找到越界的內(nèi)存地址并將其 "符號化(symbolize)"。QEMU 中的寄存器值被發(fā)送給 angr,并且它也可以從 QEMU 中動態(tài)獲取內(nèi)存中的內(nèi)容。
該引擎會尋找會對 KASAN 報告的越界內(nèi)存范圍內(nèi)的數(shù)值進行操作的某些類型匯編指令。這使它能夠檢測到各種類型的利用缺陷的方式。例如,如果傳遞給 kfree() 的值來自可以被控制的內(nèi)存位置,那么它就會被標(biāo)記為 invalid free。類似地,對來自越界內(nèi)存地址的調(diào)用是產(chǎn)生 control-flow-hijacking 攻擊的一種方式。通過這種方式來檢測出五種不同類型的高風(fēng)險影響。
Results
研究人員對 syzbot 報告出來的近 1200 個低風(fēng)險漏洞進行了實驗。對每個漏洞進行了 3 小時的 fuzzing 處理以及 4 小時的 symbolic execution。總的來說,該實驗發(fā)現(xiàn)了 147 個低風(fēng)險漏洞導(dǎo)致的高風(fēng)險影響問題。很多低風(fēng)險漏洞都有許多其他一些影響,其中很多都會帶來高風(fēng)險類別的后果。例如,發(fā)現(xiàn)了 51 個 control-flow hijacking 的問題,這個數(shù)字包括了 syzbot 對于低風(fēng)險類別中報告出來的已經(jīng) fix 的和尚未 fix 的 bug 進行的分析結(jié)果。在 syzbot 報告的內(nèi)容之外,還發(fā)現(xiàn)了大約 3200 個與之無關(guān)的安全問題。
針對大約 5% 的全部 impact 來僅僅依靠 fuzzing 就發(fā)現(xiàn)了接近半數(shù)的 high-risk bug。如前所述,fuzzing 方式只能發(fā)現(xiàn)那些不需要控制越界內(nèi)存內(nèi)容的安全問題。因此對于已經(jīng)被修復(fù)的 bug (可以使用 fuzzing 階段分析了),平均每個被測試過的內(nèi)核 bug 都有接近 28 個進一步的安全問題(further impact)。從尚未解決的 bug 中進行的測試平均每個都發(fā)現(xiàn)了約 17 個額外的安全影響。
symbolic execution 報出了這個實驗中所發(fā)現(xiàn)的另一半的高風(fēng)險漏洞,包括所有 34 個由 syzbot 報告但仍未在內(nèi)核中修復(fù)的漏洞。它還報出了絕大部分(95%)的 impact,包括所有的超高風(fēng)險 impact 都是它報出來的,比如 control-flow-hijacking 和對任意地址的寫入問題。
研究人員向 CVE 維護者提交了 32 個高風(fēng)險漏洞,其中 8 個被分配了 CVE 編號(可以在 Zou 的幻燈片 28 中看到)。他們的論文將在 2022 年 8 月舉行的第 31 屆 USENIX 安全研討會上發(fā)表。鄒說論文應(yīng)該很快就能拿到。
多年來,syzbot 的輸出的大量 bug report,以及內(nèi)核開發(fā)人員無法跟上這個速度,一直是人們比較擔(dān)心的一個問題。這次的發(fā)現(xiàn)只會更加加劇這些擔(dān)憂。毫不意外我們會發(fā)現(xiàn)黑帽子(惡意攻擊者)或者政府機構(gòu)正在使用類似的技術(shù)來將看似不太有害的漏洞變成能用來完全攻破內(nèi)核的方法。事實上,如果他們不這樣做,那才是令人驚訝的。在某種程度上,這些發(fā)現(xiàn)都表明來根據(jù) syzbot 報告的 impact 來確定 bug 的優(yōu)先級的做法,可能經(jīng)常低估了危險性,但這些數(shù)據(jù)確實有利于證實 "所有 bug 都是 security bug" 的觀點,這種態(tài)度在一些內(nèi)核開發(fā)社區(qū)中是很流行的。
全文完
LWN 文章遵循 CC BY-SA 4.0 許可協(xié)議。
長按下面二維碼關(guān)注,關(guān)注 LWN 深度文章以及開源社區(qū)的各種新近言論~
