本文會分析野外發現的兩個rootkit示例:Husky rootkit和Mingloa/CopperStealer rootkit。
驅動入口函數DriverEntry讓我們從二進制的驅動入口函數DriverEntry開始,在Windows內核驅動程序中,它是DriverEntry。
DriverEntry通常包括以下代碼塊:
調用IoCreateDevice和IoCreateSymbolicLink;
初始化主要函數數組,其中包含指向各種處理函數的函數指針;
為DriverUnload例程分配一個指向處理程序函數的函數指針。
以下片段(代碼段1)展示瞭如何用C語言實現簡單Windows內核驅動程序的DriverEntry。
C語言中DriverEntry實現的一個示例
下一個代碼段(代碼段2)展示了同一個DriverEntry的反彙編過程。
代碼段2:DriverEntry的反彙編
DriverUnload函數DriverUnload是一個在卸載驅動程序時調用的函數。
此處理程序函數的目的是清除驅動程序在初始化和執行過程中創建的任何資源,例如,刪除在DriverEntry中創建的設備和符號鏈接。
調用ExFreePoolWithTag來取消分配在DriverEntry函數中分配的任何池內存也是一個很好的策略函數。
代碼段3:C語言中DriverUnload實現的一個示例
Windows內核結構為了充分理解Windows內核驅動程序的反彙編,我們還應該熟悉對像管理器和內核中其他組件使用的一些內核結構。
例如,以下結構是DRIVER_OBECT(代碼段4)。
代碼段4:分解DRIVER_OBECT結構
當對IRP進行逆向工程時,繪製出驅動程序使用的IRP主要函數是很有用的。例如,通過查看結構偏移(代碼段4)和反彙編(代碼段2),我們可以確定sub_1400014B0是DriverUnload。
我們還可以使用wdm.h/ntddk.h中描述的IRP主要函數代碼值,通過檢查代碼的主要函數,得出sub_140001280(在Snippet 2中)是IRP_MJ_CREATE的函數處理程序的結論,該代碼將從DRIVER_OBECT結構中的MajorFunction(0x70)的偏移量得出0x70的結果。這顯然是0x00*PointerSize(x64體系結構中為8);因此,正在處理的是IRP_MJ_CREATE。
可以用同樣的方式,確定IRP_J_CLOSE、IRP_J_READ、IRP_MJ_WRITE和IRP_J_DEVICE_CONTROL的函數處理程序是什麼。
代碼段5:摘自wdm.h,它定義了所有IRP主要函數的常數值
在進行分析時,我們熟悉的其他一些內核結構是IRP和IO_STACK_LOCATION結構。
IRP,也稱為I/O請求包,是一種在創建I/O請求期間,在設備堆棧中的不同驅動程序之間移動,直到請求完成的結構。
當在用戶獲取的設備對象的句柄上從用戶模式調用具有特定IOCTL操作的DeviceIoControl時,會創建IRP。
代碼段6:IRP結構的分解
此外,IO_STACK_LOCATION表示IRP在設備堆棧中的當前位置(因此IRP結構中的CurrentLocation字段是指向IO_STACK-LOCATION的指針)。
IO_STACK_LOCATION結構包含一個聯合類型的參數字段,該字段指定驅動程序中不同主函數要使用的不同參數。
例如,如果當前操作是IRP_MJ_DEVICE_CONTROL,則將使用DeviceIoControl類型的參數,包括OutputBufferLength、InputBufferLength、IoControlCode和Type3InputBuffer。
代碼段7:IO_STACK_LOCATION結構的分解
有了我們對Windows內核驅動程序的新理解,以及如何在Windows驅動程序中找到關鍵函數,讓我們看看一些真實的示例。
示例1:Brute Ratel C4(BRC4)攻擊釋放“Husky” Rootkit這項研究來源於Palo Alto Networks Unit 42在一篇關於Brute Ratel C4的博客https://unit42.paloaltonetworks.com/brute-ratel-c4-tool/中提到的與活動相關的示例。不過,他們沒有提供這個示例的技術分析。
示例詳細信息
示例概述該示例是一個內核驅動程序,使用LAP$US組織竊取的NVIDIA證書進行簽名。它使用zerosum0x0(圖1)找到的Heresy's Gate方法https://zerosum0x0.blogspot.com/2020/06/heresys-gate-kernel-zwntdll-scraping.html,這是一種用於從內核模式驅動程序繞過SMEP向用戶模式註入代碼的技術。
通過zerosum0x0使用Heresy‘s Gate方法對簽名驅動程序進行分解
注入的shellcode使用經典技術,如遍歷InLoadOrderModuleList以查找庫句柄,以及解析API函數(如LoadLibraryA和GetProcAddress),這些函數可用於解析任何其他API。
注入的shellcode分析起來也很長(圖2),看起來與前面提到的Unit 42博客中描述的shellcode非常相似,因為它使用多個推送指令在堆棧上存儲數據。存儲在堆棧中的數據包括:
Brute Ratel C4的Base64編碼配置數據;
Brute Ratel C4有效負載;
可移植可執行文件(PE)64二進製文件,是VMProtect打包的內核驅動程序,稍後加載。
圖2:摘自shellcode,將許多值推送到堆棧並形成Base64 blob
Brute Ratel C4配置可以使用以下短腳本(代碼段8)進行解密:
代碼段8:用於解碼和解密從堆棧中提取的Base64 blob的配置的代碼段
解密配置後,我們得到以下輸出:
代碼段9:解密配置的示例
解密的配置數據(Snippet 9)包括Brute Ratel C4有效負載的一些基本配置,包括C2服務器地址和開始通信的端口,對C2的請求應該是什麼樣子的Base64編碼模板,以及C2上用於各種功能和選項的不同路徑。
攻擊場景
我們發現x64 rootkit與Brute Ratel C4示例一起安裝在受攻擊的設備上更有趣,因為它被覆蓋相同示例的其他供應商完全忽略了。
Husky Rootkitx64 rootkit,我們稱之為Husky Rootkit,與Brute Ratel有效負載一起被釋放。
內核驅動程序由VMProtect打包,並使用頒發給“SHANGMAO CHEN”的證書進行簽名(圖4)。
rootkit使用的證書
驅動入口函數DriverEntry由於這個DriverEntry(圖5)函數被打包並混淆了,因此很難從中收集任何信息。它從一系列無條件分支指令(jmp)開始,基本上指向VMProtect解包存根。
VMProtected DriverEntry顯示了一個無條件分支指令作為它的第一條指令
但是在解包之後,我們發現像GsDriverEntry這樣的函數包含了更多的信息,以及我們可以在分析中使用的重要字符串(圖6)。
從GsDriverEntry中反彙編一個分支,該分支包含以thpt(HTTP的混合版本)作為其URL協議的URL字符串
C2通信rootkit直接與\\Device\Tcp進行交互以進行通信。因此,在受攻擊的設備上運行的用戶模式工具(如netstat和tcpview)會隱藏連接。
另一種方法是在VM主機上使用Wireshark進入客戶機的共享網絡接口,以監控受攻擊虛擬機的所有通信流量(圖7和圖8)。
Wireshark網絡捕獲的由rootkit啟動的流量
該惡意軟件與多個域以及每個域的相對路徑進行通信。
從服務器到URL中的/xccdd路徑的Web請求和響應顯示了響應有效負載
隱寫術引起我們注意的特定HTTP流量是從以下URL下載的一些圖像(JPEG–JFIF標頭):http://pic.rmb.bdstatic.com//bjh/.jpeg.
JPEG文件(圖9)是一張看起來很無辜的狗的圖片,因此研究人員將這些圖片命名rootkit為“Husky”。
該圖片含有有效負載
每個JPEG也有一個隱寫有效負載,其形式是在多個0的分隔符之後,將數據連接到偏移量為0x1769的圖片末尾(圖10)。
jpg文件中帶有狗的圖片末尾和負載的開始之間的分隔符的Hexview
通過查看數據,我們可以看到前32個字節與前一個請求對hxxp://rxeva6w.com:10100/xccdd的十六進制格式的服務器響應相同(代碼段10)。
代碼段10:有效負載的前32個字節在不同的有效負載中相似
諷刺是,域rxeva6w.com在88次檢測中一次也未被檢測到(圖11)。
VirusTotal顯示了在rveva6w.com域上的檢測結果
加密HTTP有效負載使用的加密/解密算法是一種稍微修改過的DES算法,密鑰為“j_k*a-vb”。
將解密密鑰傳遞給DES解密函數
附加功能除了通過HTTP進行通信和隱藏連接外,這個rootkit還能夠加載從不同URL下載的新模塊。
顯然,這個rootkit包含了本文未提及的額外功能。
示例2:Mingloa(CopperStealer)Rootkit2019年,ESET首次發現並命名了Mingloa惡意軟件。該惡意軟件後來也被Proofpoint發現了,也被稱為CopperStealer。
正如Proofpoint研究中所指出的,該惡意軟件具有查找和竊取保存的瀏覽器密碼的能力。除了保存的瀏覽器密碼外,該惡意軟件還使用存儲的cookie從Facebook檢索用戶訪問令牌。
這是CyberArk Endpoint Privilege Manager中包含的一系列憑據和安全令牌保護技術,這可以顯著限制CopperStealer等憑據竊取程序的影響。如果使用這些技術,CopperStealer將無法從受攻擊的設備中抓取數據。
示例概述
此惡意內核模塊是針對x86和x64體系結構編譯的。
惡意軟件攻擊場景的分解
該驅動程序使用頒發給“大連龍夢網絡技術有限公司”或“大連晨星網絡技術”的證書進行簽名。此證書可能是從受攻擊的設備上竊取的,或者是由員工洩露的。
頒發給“大連龍夢網絡科技”的證書,用於簽名驅動程序
通過用戶模式安裝讓我們首先看看應該部署驅動程序的用戶模式惡意軟件攻擊例程。
分解用戶模式組件執行流以安裝驅動程序
通過查看這個片段,我們可以看到InstallDriver函數接收到一個參數,並且首次調用時參數值為0。第二次調用時,參數值為1。
如果我們仔細觀察InstallDriver,會發現它首先嘗試創建一個semaphore,然後檢查Windows版本。如果這些調用中的任何一個失敗,它將退出而不執行任何操作。
二進製文件中InstallDriver函數開頭的反彙編,它調用CreateSemaphoreWrapper
如果之前的檢查成功,則惡意軟件將繼續,停止並刪除任何具有相同名稱的服務,最後將shouldInstallDriver參數與0進行比較。
CreateSemphoreWrapper函數的反彙編
如果shouldInstallDriver的值等於0,則函數將返回,不再執行任何指令。否則,它將根據系統架構,繼續安裝嵌入二進製文件中的適當驅動程序。
對InstallDriver函數的分解,它描述在系統上安裝驅動程序的流程
這部分代碼還包含一個邏輯錯誤,它會阻止加載此驅動程序。
第一次調用InstallDriver(應該只刪除任何現有的驅動程序)也會創建一個信號量。第二個調用也應該安裝驅動程序,但在安裝驅動程序之前會提前退出,因為semaphore已經存在。
這個邏輯錯誤有些神秘,因為惡意軟件通常會針對這些類型的錯誤進行測試。在這種情況下,它要么是在沒有任何測試的情況下匆忙部署的,要么還不打算部署到任何受攻擊的設備上。
驅動入口函數DriverEntry該惡意軟件的內核模式組件是傳統文件系統過濾器驅動程序,與更現代的迷你過濾器驅動程序不同,它可以在不使用回調過濾函數(如操作前回調例程或操作後回調例程)的情況下修改系統行為。
傳統的文件系統過濾器驅動程序可以直接修改文件系統行為,並且在每個I/O操作(如CREATE, READ和WRITE)中都被調用。
通過查看DriverEntry,我們可以看到兩個主要的函數例程被分配了IRP_MJ_READ和IRP_MJ_SET_INFORMATION。此外,它還註冊了兩個回調函數——一個使用CmRegisterCallback,另一個使用IoRegisterFsRegistrationChange。