如今,云原生平臺越來越多的使用了基于eBPF的安全探測技術(shù)。這項技術(shù)通過創(chuàng)建安全的Hook鉤子探針來監(jiān)測內(nèi)部函數(shù)和獲取重要數(shù)據(jù),從而支持對應(yīng)用程序的運(yùn)行時做監(jiān)測和分析。Tracee是用于Linux的運(yùn)行時安全和取證的開源項目,它基于eBPF實(shí)現(xiàn),所以在安全監(jiān)測方面效果更加優(yōu)化。
在本文中,我們將探索控制eBPF事件的方法,并研究一個使用BPF事件捕獲rootkit的案例。Rootkit是一種存在于內(nèi)核中復(fù)雜類型的惡意漏洞攻擊,并將介紹Tracee用于檢測Syscall 鉤子的新特性,它實(shí)現(xiàn)了在內(nèi)核中使用eBPF事件的獨(dú)特方式。
eBPF: 不只是用來跟蹤
eBPF是一種Linux內(nèi)核技術(shù),它允許在不更改內(nèi)核源代碼或添加新模塊的前提下,在Linux內(nèi)核中運(yùn)行沙盒程序。因此,eBPF可以支持安全的Hook到事件上,而不會造成內(nèi)核崩潰的風(fēng)險。
具體來說,eBPF程序使用內(nèi)核機(jī)制(如kprobes、kretprobes、Linux安全模塊(LSM) Hooks、uprobes和traceponits)來創(chuàng)建和設(shè)置鉤子,并加以驗(yàn)證代碼不會使內(nèi)核崩潰。eBPF有一個Verifier驗(yàn)證器,其目標(biāo)是確保eBPF程序安全運(yùn)行(而不是通過加載內(nèi)核模塊來與內(nèi)核交互,如果操作不當(dāng),會導(dǎo)致系統(tǒng)崩潰)。
攻擊者為何喜歡Hook內(nèi)核函數(shù)?
目前使用rootkit的復(fù)雜攻擊往往是針對內(nèi)核空間,這是因?yàn)楣粽咴噲D避免被安全防御方案,以及監(jiān)控用戶空間事件或分析基本系統(tǒng)日志的取證工具檢所測到。此外,在內(nèi)核空間中嵌入惡意軟件也會使得安全研究員和響應(yīng)團(tuán)隊更難找到它。惡意軟件越接近于底層,檢測起來就越困難。
下面,我們將看看TNT團(tuán)隊的例子,并查看他們是如何利用Diamorphine 這個rootkit,以及Tracee如何檢測到它。
內(nèi)核中的函數(shù)操作
攻擊者為了自身利益最大化,會尋找內(nèi)核級別的目標(biāo)函數(shù)。常用的一種方法是函數(shù)鉤子,旨在通過操縱內(nèi)核中的函數(shù)來隱藏惡意活動。這樣做的原因是內(nèi)核函數(shù)執(zhí)行的是來自用戶空間的任務(wù)。如果它們被破壞,攻擊者即可控制所有用戶空間程序的行為。
當(dāng)攻擊者試圖Hook系統(tǒng)調(diào)用(syscall)函數(shù)時,這就是函數(shù)鉤子的一個很好示例。這些高級內(nèi)核函數(shù)用于執(zhí)行來自用戶空間的任務(wù),Hook住它們主要目的是隱藏惡意行為。例如,攻擊者將getdents系統(tǒng)調(diào)用Hook起來,以隱藏用于列出文件命令(如ps、top和ls)的惡意文件和進(jìn)程。
通常,通過讀取系統(tǒng)調(diào)用表并獲取系統(tǒng)調(diào)用函數(shù)的地址來Hook他們。一旦獲得系統(tǒng)調(diào)用函數(shù)地址,攻擊者將保存原始地址,并試圖用包含惡意代碼的新函數(shù)覆蓋它。
攻擊者如何Hook內(nèi)核函數(shù)?
現(xiàn)在,讓我們研究一下攻擊者如何在真實(shí)環(huán)境下的網(wǎng)絡(luò)攻擊中劫持內(nèi)核函數(shù)。
為了Hook內(nèi)核函數(shù),必須首先獲得想要鉤住的對象訪問權(quán)。例如,它可以是保存所有系統(tǒng)調(diào)用函數(shù)地址的系統(tǒng)調(diào)用表。然后,保存函數(shù)的原始地址并覆蓋它。在某些情況下,由于當(dāng)前位置的內(nèi)存權(quán)限,還需要獲取CPU中控制寄存器的權(quán)限。
接下來是TNT團(tuán)隊使用Diamorphine隱藏加密的活動,這作為他們攻擊的一部分可以很好的解釋這樣的方法:
使用內(nèi)存邊界技術(shù)檢測Syscall鉤子
現(xiàn)在我們已經(jīng)確定了攻擊者的動機(jī)以及他們?nèi)绾涡薷膬?nèi)核行為,問題是,我們該如何檢測這種活動? 明確的目標(biāo)是找到一種方法,以區(qū)分內(nèi)核中的原始內(nèi)部函數(shù)(或與核心內(nèi)核關(guān)聯(lián)的syscall)和新的內(nèi)核模塊代碼(或換句話說,被攻擊后的函數(shù))。
我們可以通過內(nèi)核的core_text邊界檢測來實(shí)現(xiàn)這一點(diǎn)。內(nèi)核中的內(nèi)存被分為幾個部分。其中一個是core_text段,它保存內(nèi)核中的原始函數(shù)。此部分注冊在特定的內(nèi)存映射區(qū)域中,該區(qū)域不受更改或操作的影響。此外,如果我們加載一個新的內(nèi)核模塊--也就是說,編寫一個新函數(shù)或覆蓋原始函數(shù)——這個新函數(shù)將寫入另一個專門為新函數(shù)保留的內(nèi)存區(qū)域??梢栽谙旅娴奶摂M內(nèi)存映射中看到這一點(diǎn)。注意,分配給原始內(nèi)核代碼的地址范圍(文本部分,又名“核心內(nèi)核文本”)和分配給新內(nèi)核模塊的地址范圍是不同的。
因此,當(dāng)前的目標(biāo)是獲取一個系統(tǒng)調(diào)用地址,然后將其與內(nèi)核core_text邊界進(jìn)行比較,正如我們所看到的,core_text邊界表示原始內(nèi)核源的范圍。
使用Tracee檢測Syscall鉤子
現(xiàn)在,我們已經(jīng)了解了惡意軟件如何以及為什么以內(nèi)核函數(shù)為目標(biāo),以及如何檢測被鉤住的內(nèi)核函數(shù),接下需要知道如何使用eBPF來提取函數(shù)的地址。使用Tracee可以確定函數(shù)是否被鉤住,即使鉤子是在Tracee執(zhí)行之前放置的。
首先創(chuàng)建一個在用戶空間中觸發(fā)的BPF程序,并在內(nèi)核空間中捕獲相應(yīng)BPF事件。如果內(nèi)核程序需要來自用戶空間的信息,可以通過BPF映射來進(jìn)行傳遞。
例如在Tracee中創(chuàng)建一個事件,該事件將從系統(tǒng)調(diào)用表中獲取系統(tǒng)調(diào)用地址,接下來確認(rèn)系統(tǒng)調(diào)用是否被內(nèi)核模塊鉤住了。如果它被鉤住了,繼續(xù)將創(chuàng)建一個派生事件(由內(nèi)核另一個事件而創(chuàng)建的事件),它將提示系統(tǒng)調(diào)用鉤住的情況,如下:
先使用libbpfgo的helper來獲取系統(tǒng)調(diào)用表地址,并將其添加到事件內(nèi)核符號依賴項中。
注意,detect_hooked_sycalls事件是派生事件。這意味著在我們接收到系統(tǒng)調(diào)用的地址并檢查它們之后,我們將創(chuàng)建一個新的detect_hooked_sycalls事件。
然后,我們將它與系統(tǒng)調(diào)用號一起傳遞,以便使用BPFMap檢查內(nèi)核空間。
為了檢查內(nèi)核空間中的那些系統(tǒng)調(diào)用,基于security_file_ioctl上的kprobe創(chuàng)建一個事件,它是ioctl系統(tǒng)調(diào)用的一個內(nèi)部函數(shù)。這樣我們就可以通過使用用戶空間的特定參數(shù)觸發(fā)系統(tǒng)調(diào)用來控制程序流,接下來用一個特定的命令觸發(fā)ioctl:
此時,在內(nèi)核空間中開始檢查ioctl命令是否相同,以及調(diào)用該系統(tǒng)調(diào)用的進(jìn)程是否為Tracee。這樣就可以驗(yàn)證只有當(dāng)用戶要求Tracee檢查時才會發(fā)生檢測的需求。
檢測代碼很簡單,遍歷系統(tǒng)調(diào)用映射,通過使用READ_KERN()來獲取系統(tǒng)調(diào)用表的地址如下:
然后在用戶空間中,我們將這些地址與libbpfgo helpers進(jìn)行比較:
狩獵時間: 用eBPF檢測Diamorphine rootkit
現(xiàn)在,開始運(yùn)行Tracee,來看看它將如何檢測出Diamorphine rootkit。
使用insmod函數(shù)加載Diamorphine (.ko)的內(nèi)核對象文件。目標(biāo)是看看Tracee的探測結(jié)果。通常,在加載一個內(nèi)核模塊的情況下啟動Tracee,如果選擇了detect_hooked_sycall事件,Tracee將發(fā)送一個hooked_sycalls事件,以確保系統(tǒng)沒有被破壞:
Tracee檢測到getdents和getdents64這些掛起的系統(tǒng)調(diào)用。TNT團(tuán)隊使用它們來隱藏大量加密活動導(dǎo)致的CPU負(fù)載過高,以及通常用于從用戶空間發(fā)送命令來殺死進(jìn)程的kill函數(shù)。在這種情況下,rootkit使用kill -63作為用戶空間和內(nèi)核空間之間的通信通道。同樣,如果再次運(yùn)行Diamorphine和Tracee使用json輸出,參數(shù)將顯示Diamorphine的惡意鉤子:
如果運(yùn)行Tracee-rules,我們可以看到detect_hooked_sycall事件的新簽名:
結(jié)論
現(xiàn)代攻擊者的目標(biāo)是包括內(nèi)核層的操作系統(tǒng)各個層級,此外,由于開源項目(如Diamorphine)的流行,攻擊性網(wǎng)絡(luò)工具變得越來越容易獲得。因此,安全研究員需要提高自身的防御能力知識,開發(fā)出合適的檢測方法。
審核編輯:劉清
-
Linux系統(tǒng)
+關(guān)注
關(guān)注
4文章
590瀏覽量
27317 -
rootkit
+關(guān)注
關(guān)注
0文章
8瀏覽量
2699 -
BPF
+關(guān)注
關(guān)注
0文章
24瀏覽量
3968
原文標(biāo)題:利用eBPF探測Rootkit漏洞
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論