如今,云原生平臺越來越多的使用了基于eBPF的安全探測技術。這項技術通過創建安全的Hook鉤子探針來監測內部函數和獲取重要數據,從而支持對應用程序的運行時做監測和分析。Tracee是用于Linux的運行時安全和取證的開源項目,它基于eBPF實現,所以在安全監測方面效果更加優化。
在本文中,我們將探索控制eBPF事件的方法,并研究一個使用BPF事件捕獲rootkit的案例。Rootkit是一種存在于內核中復雜類型的惡意漏洞攻擊,并將介紹Tracee用于檢測Syscall 鉤子的新特性,它實現了在內核中使用eBPF事件的獨特方式。
eBPF: 不只是用來跟蹤
eBPF是一種Linux內核技術,它允許在不更改內核源代碼或添加新模塊的前提下,在Linux內核中運行沙盒程序。因此,eBPF可以支持安全的Hook到事件上,而不會造成內核崩潰的風險。
具體來說,eBPF程序使用內核機制(如kprobes、kretprobes、Linux安全模塊(LSM) Hooks、uprobes和traceponits)來創建和設置鉤子,并加以驗證代碼不會使內核崩潰。eBPF有一個Verifier驗證器,其目標是確保eBPF程序安全運行(而不是通過加載內核模塊來與內核交互,如果操作不當,會導致系統崩潰)。
攻擊者為何喜歡Hook內核函數?
目前使用rootkit的復雜攻擊往往是針對內核空間,這是因為攻擊者試圖避免被安全防御方案,以及監控用戶空間事件或分析基本系統日志的取證工具檢所測到。此外,在內核空間中嵌入惡意軟件也會使得安全研究員和響應團隊更難找到它。惡意軟件越接近于底層,檢測起來就越困難。
下面,我們將看看TNT團隊的例子,并查看他們是如何利用Diamorphine 這個rootkit,以及Tracee如何檢測到它。
內核中的函數操作
攻擊者為了自身利益最大化,會尋找內核級別的目標函數。常用的一種方法是函數鉤子,旨在通過操縱內核中的函數來隱藏惡意活動。這樣做的原因是內核函數執行的是來自用戶空間的任務。如果它們被破壞,攻擊者即可控制所有用戶空間程序的行為。
當攻擊者試圖Hook系統調用(syscall)函數時,這就是函數鉤子的一個很好示例。這些高級內核函數用于執行來自用戶空間的任務,Hook住它們主要目的是隱藏惡意行為。例如,攻擊者將getdents系統調用Hook起來,以隱藏用于列出文件命令(如ps、top和ls)的惡意文件和進程。
通常,通過讀取系統調用表并獲取系統調用函數的地址來Hook他們。一旦獲得系統調用函數地址,攻擊者將保存原始地址,并試圖用包含惡意代碼的新函數覆蓋它。
攻擊者如何Hook內核函數?
現在,讓我們研究一下攻擊者如何在真實環境下的網絡攻擊中劫持內核函數。
為了Hook內核函數,必須首先獲得想要鉤住的對象訪問權。例如,它可以是保存所有系統調用函數地址的系統調用表。然后,保存函數的原始地址并覆蓋它。在某些情況下,由于當前位置的內存權限,還需要獲取CPU中控制寄存器的權限。
接下來是TNT團隊使用Diamorphine隱藏加密的活動,這作為他們攻擊的一部分可以很好的解釋這樣的方法:
使用內存邊界技術檢測Syscall鉤子
現在我們已經確定了攻擊者的動機以及他們如何修改內核行為,問題是,我們該如何檢測這種活動? 明確的目標是找到一種方法,以區分內核中的原始內部函數(或與核心內核關聯的syscall)和新的內核模塊代碼(或換句話說,被攻擊后的函數)。
我們可以通過內核的core_text邊界檢測來實現這一點。內核中的內存被分為幾個部分。其中一個是core_text段,它保存內核中的原始函數。此部分注冊在特定的內存映射區域中,該區域不受更改或操作的影響。此外,如果我們加載一個新的內核模塊--也就是說,編寫一個新函數或覆蓋原始函數——這個新函數將寫入另一個專門為新函數保留的內存區域。可以在下面的虛擬內存映射中看到這一點。注意,分配給原始內核代碼的地址范圍(文本部分,又名“核心內核文本”)和分配給新內核模塊的地址范圍是不同的。
因此,當前的目標是獲取一個系統調用地址,然后將其與內核core_text邊界進行比較,正如我們所看到的,core_text邊界表示原始內核源的范圍。
使用Tracee檢測Syscall鉤子
現在,我們已經了解了惡意軟件如何以及為什么以內核函數為目標,以及如何檢測被鉤住的內核函數,接下需要知道如何使用eBPF來提取函數的地址。使用Tracee可以確定函數是否被鉤住,即使鉤子是在Tracee執行之前放置的。
首先創建一個在用戶空間中觸發的BPF程序,并在內核空間中捕獲相應BPF事件。如果內核程序需要來自用戶空間的信息,可以通過BPF映射來進行傳遞。
例如在Tracee中創建一個事件,該事件將從系統調用表中獲取系統調用地址,接下來確認系統調用是否被內核模塊鉤住了。如果它被鉤住了,繼續將創建一個派生事件(由內核另一個事件而創建的事件),它將提示系統調用鉤住的情況,如下:
先使用libbpfgo的helper來獲取系統調用表地址,并將其添加到事件內核符號依賴項中。
注意,detect_hooked_sycalls事件是派生事件。這意味著在我們接收到系統調用的地址并檢查它們之后,我們將創建一個新的detect_hooked_sycalls事件。
然后,我們將它與系統調用號一起傳遞,以便使用BPFMap檢查內核空間。
為了檢查內核空間中的那些系統調用,基于security_file_ioctl上的kprobe創建一個事件,它是ioctl系統調用的一個內部函數。這樣我們就可以通過使用用戶空間的特定參數觸發系統調用來控制程序流,接下來用一個特定的命令觸發ioctl:
此時,在內核空間中開始檢查ioctl命令是否相同,以及調用該系統調用的進程是否為Tracee。這樣就可以驗證只有當用戶要求Tracee檢查時才會發生檢測的需求。
檢測代碼很簡單,遍歷系統調用映射,通過使用READ_KERN()來獲取系統調用表的地址如下:
然后在用戶空間中,我們將這些地址與libbpfgo helpers進行比較:
狩獵時間: 用eBPF檢測Diamorphine rootkit
現在,開始運行Tracee,來看看它將如何檢測出Diamorphine rootkit。
使用insmod函數加載Diamorphine (.ko)的內核對象文件。目標是看看Tracee的探測結果。通常,在加載一個內核模塊的情況下啟動Tracee,如果選擇了detect_hooked_sycall事件,Tracee將發送一個hooked_sycalls事件,以確保系統沒有被破壞:
Tracee檢測到getdents和getdents64這些掛起的系統調用。TNT團隊使用它們來隱藏大量加密活動導致的CPU負載過高,以及通常用于從用戶空間發送命令來殺死進程的kill函數。在這種情況下,rootkit使用kill -63作為用戶空間和內核空間之間的通信通道。同樣,如果再次運行Diamorphine和Tracee使用json輸出,參數將顯示Diamorphine的惡意鉤子:
如果運行Tracee-rules,我們可以看到detect_hooked_sycall事件的新簽名:
結論
現代攻擊者的目標是包括內核層的操作系統各個層級,此外,由于開源項目(如Diamorphine)的流行,攻擊性網絡工具變得越來越容易獲得。因此,安全研究員需要提高自身的防御能力知識,開發出合適的檢測方法。
審核編輯:劉清
-
Linux系統
+關注
關注
4文章
596瀏覽量
27510 -
rootkit
+關注
關注
0文章
8瀏覽量
2720 -
BPF
+關注
關注
0文章
25瀏覽量
4055
原文標題:利用eBPF探測Rootkit漏洞
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
使用STM32F1輸入捕獲功能時,TIM6和TIM7無法實現輸入捕獲是哪里的問題?
是德DSOX4032A示波器波形捕獲率
![是德DSOX4032A示波器波形<b class='flag-5'>捕獲</b>率](https://file1.elecfans.com//web2/M00/04/B5/wKgZombRdvGAPSIjAABg-5e9eS467.jpeg)
OPA857設計一個光脈沖捕獲的前端遇到的疑問求解
工業自動化領域解決方案 利用Profishark工具捕獲EtherCAT報文
![工業自動化領域解決方案 利用Profishark工具<b class='flag-5'>捕獲</b>EtherCAT報文](https://file1.elecfans.com/web2/M00/F8/4B/wKgZomaHi82AdW8sAAGNK9tc8-c075.png)
示波器如何捕獲單次波形?
進行STM32 PWM輸入捕獲遇到的疑問求解
TSN抓包工具解密:數據包捕獲,為什么選Profishark?
![TSN抓包工具解密:數據包<b class='flag-5'>捕獲</b>,為什么選Profishark?](https://file.elecfans.com/web2/M00/3F/D7/poYBAGJqPMKAEXjWAAAOpepuZJ8475.jpg)
評論