愛伊米

GhostEmperor:透過利用核心以及ProxyLogon系列漏洞發起攻擊(下)

GhostEmperor:透過利用核心以及ProxyLogon系列漏洞發起攻擊(下)

IOCTL程式碼說明

0x220180: 透過驗證其大小為 272 位元組來處理使用者模式惡意軟體元件提供的緩衝區,然後透過否定其位元組對其進行解碼,這個 IOCTL 實際上不是由使用者模式程式碼呼叫的。

0x220184: 在核心空間分配緩衝區,鎖定其頁面,建立 MDL 並使用 MmMapLockedPagesSpecifyCache API 將緩衝區對映到使用者模式地址。這本質上等同於來自原始排程程式的 IOCTL_CE_ALLOCATEMEM_NONPAGED 和 IOCTL_CE_MAP_MEMORY 中的功能連結。

在這個呼叫之後,使用者模式程式碼可以訪問核心模式緩衝區,並且可以在使用者模式下使用指標對其進行寫入,就像編寫 shellcode 的情況一樣。然而,這一次,惡意軟體手動將 rootkit 的 PE 映像載入到分配的緩衝區中。

0x2201B4:由於惡意軟體的使用者模式程式碼負責在IOCTL 0x220184中手動載入rootkit的映像,它必須解析核心空間中的一些函式地址,這些地址在映像的匯入地址表中作為依賴項出現。這個IOCTL允許函式名作為字串從使用者空間接收,使用MmGetSystemRoutineAddress API檢索它們的地址,並將其提供給使用者模式程式碼。後者將解析的地址放在載入影象的相應IAT項中。

0x220188:從使用者空間取消核心模式緩衝區的地址對映,以便只能透過核心模式指標訪問它。

0x2201B8 :使用 IoCreateDriver 函式建立一個新的驅動程式物件,將驅動程式初始化函式指標分配給一個與位置無關的存根,該存根與 shellcode 一起提供,一旦被呼叫,就會呼叫載入的 rootkit 的 DriverEntry 函式。

值得一提的是,該惡意軟體的服務在載入 dbk64。sys 驅動程式期間使用了名為 kernelmoduleuloader。exe(MD5:96F5312281777E9CC912D5B2D09E6132)的Cheat Engine實用程式。該驅動程式與實用程式和 。sig 檔案一起被刪除,後者被用作透過傳送與其二進位制相關聯的數字簽名來對呼叫 dbk64。sys 的元件進行身份驗證的一種手段。

由於惡意軟體不是 Cheat Engine 的元件,它將 kernelmoduleunloader。exe 作為一個新程序執行,並向其注入一個小的 shellcode,該 shellcode 僅使用 CreateFileW API 開啟 dbk64。sys 裝置的控制代碼。控制代碼的值被寫入注入緩衝區中的第二個QWORD,由惡意軟體的程序讀取,並使用DuplicateHandle API進行復制。這樣,惡意軟體的服務就可以呼叫驅動程式,就好像它是一個簽名的Cheat Engine元件。

GhostEmperor:透過利用核心以及ProxyLogon系列漏洞發起攻擊(下)

Rootkit 載入階段

Demodex rootkit功能

載入的 rootkit,我們稱之為 Demodex,用於隱藏惡意軟體服務構件。這是透過一組由 rootkit 驅動程式公開的 IOCTL 來實現的,這些 IOCTL 依次由服務的使用者模式程式碼呼叫,每個 IOCTL 都偽裝了一個特定的惡意構件。為了訪問 rootkit 的功能,惡意軟體應該獲得相應裝置物件的控制代碼,在此之後,以下IOCTL 可用於進一步使用:

0x220204:接收帶有執行惡意服務程式碼的 svchost。exe 程序的 PID 引數,並將其儲存在全域性變數中。此變數稍後由其他 IOCTL 使用。

0x220224:初始化稍後用於儲存資料的全域性變數,例如前面提到的 svchost。exe PID、惡意軟體服務的名稱、惡意軟體 DLL 的路徑和網路埠。

0x220300:在services。exe程序地址空間的列表中隱藏惡意軟體的服務。服務的名稱作為引數傳遞給IOCTL,然後在系統維護的連結串列中查詢。相應的條目被解除連結,從而使服務無法被輕易檢測到。

0x220304:這個IOCTL用於透過IoRegisterFSRegistrationChange API註冊一個檔案系統過濾驅動的通知例程。註冊新檔案系統時呼叫的通知例程驗證它是否是基於ntfs的檔案系統,如果是,則為附加到主題檔案系統的裝置堆疊的rootkit建立一個裝置物件。此外,檔案系統的裝置物件和關聯的rootkit裝置物件都被註冊在由rootkit驅動程式維護的全域性列表中。隨後從該檔案中檢索資訊、訪問或修改該檔案的嘗試將會失敗,並生成錯誤程式碼,如STATUS_NO_MORE_FILES或STATUS_NO_SUCH_FILE。

0x220308:從列出它們的實用程式(例如 netstat)中隱藏使用給定範圍內埠的 TCP 連線。這是透過一種 known4 方法完成的,其中 NSI 代理驅動程式的 IOCTL 排程例程被掛鉤,並且完成例程被設定為檢查給定連線的埠。如果底層連線的埠在給定範圍內,則其條目將從系統的 TCP 表中刪除。構成範圍的兩個埠作為引數傳遞給 IOCTL。

0x22030C:透過 CmRegisterCallback API 掛鉤多個登錄檔操作來隱藏與惡意軟體相關的登錄檔項。註冊的回撥會檢查操作的型別並按照以下邏輯進行操作:

對於 RegNtPostEnumerateKey 或 RegNtPostEnumerateValueKey(項或子項的列舉)型別的操作,它驗證是否嘗試列舉 HKLM\SYSTEM\ControlSet0**\Services\

對於 SOFTWARE\Microsoft\ 型別的 RegNtPreOpenKeyEx(嘗試開啟項)型別的操作,它會清除驅動程式的所有內部全域性變數,這相當於重置其操作。這是因為該項是由惡意軟體的解除安裝程式 PowerShell 指令碼使用的,在前面的部分中提到過。

對於任何試圖透過RegNtPreSaveKey或更低程式碼的操作在HKLM\MACHINE\SYSTEM下更改項的操作,它會將返回狀態設定為應用程式錯誤 0xC0000043。

有趣的是,傳遞給 CmRegisterCallback 的指標不包含處理上述邏輯的函式的直接地址,而是包含 pci。sys 驅動程式映像的可執行部分末尾的地址,該地址最初用0填充對齊記憶體中的部分。在將回調指標傳遞給 CmRegisterCallback 之前,會在 pci。sys 驅動程式中尋找這樣的部分,並修補其中的相應位元組,以便呼叫對處理上述邏輯的實際回撥的呼叫,如下所述。這允許所有攔截的登錄檔操作看起來好像它們是由源自合法 pci。sys 驅動程式的程式碼處理的。

GhostEmperor:透過利用核心以及ProxyLogon系列漏洞發起攻擊(下)

用於修補記憶體中 pci。sys 映像中的部分的程式碼,以便使用跳轉到登錄檔檢查回撥的短 shellcode 存根編寫它

值得一提的是,Demodex rootkit 在設計上支援 Windows 10,根據我們對 Windows 10 版本的測試,它確實可以正常工作。這在多個地方的驅動程式程式碼中很明顯,其中根據底層作業系統的版本採用不同的程式碼流。在此類檢查中,可以觀察到某些流對應於 Windows 10 的最新版本,如下面的程式碼片段所示。

混淆和反分析方法

GhostEmperor 活動叢集中使用的惡意軟體元件的開發者做出了一些對取證分析過程有影響的設計。為了介紹研究人員所面臨的一些障礙,我們將討論限於兩種常見的分析工具——WinDbg和Volatility。在處理有問題的植入程式時,其他工具可能會遇到類似的障礙。

首先,由於 Demodex 的載入方式,它的驅動程式沒有正確地與其他以文件方式載入的系統模組一起列入 WinDbg。也就是說,仍然可以透過引用其名稱 (\driver\dump_audio_codec0) 來找到 rootkit 的驅動程式物件,從而也可以列出其關聯的裝置物件:

WinDBG 中列出的驅動程式物件名稱

同樣,當嘗試使用 Volatility3 widows。driverscan 模組列出系統模組時,輸出中不存在Demodex驅動程式。但是,該框架確實表明在掃描核心記憶體空間以搜尋驅動程式的過程中檢測到異常:

使用 windows。driverscan Volatility3 模組列出Demodex驅動程式時出現異常

此外,惡意軟體開發者有意選擇從惡意軟體的第三階段和 rootkit 驅動程式的記憶體載入影象中刪除所有 PE 標頭。這是透過引入帶有清零標頭的影象開始(如第三階段的情況)並依靠自定義載入程式來準備執行或透過在載入後替換影象的標頭來完成0x00 值,就像 rootkit 的驅動程式一樣。從取證的角度來看,這會阻礙透過搜尋標標頭檔案來識別載入到記憶體中的 PE 影象的過程。

如上所述,開發人員在 pci。sys 合法驅動程式中實現了一個蹦床( trampoline),以遮蔽為登錄檔相關操作呼叫的回撥源。因此,試圖追蹤此類回撥的分析師可能會忽略一些回撥,因為它們看上去是良性的回撥。如下面 Cm* 回撥的 WinDbg 列表所示,其中一個與符號 pci!ArbLibraryDeinitialize+0xa4 相關聯;然而,如果我們檢視同一地址的程式碼,我們會發現它實際上是 rootkit 發出的一小段 shellcode,目的是跳轉到隱藏惡意軟體登錄檔項的實際惡意回撥。

GhostEmperor:透過利用核心以及ProxyLogon系列漏洞發起攻擊(下)

在從 pci。sys 驅動程式呼叫的看似良性程式碼中發現的 Cm* 回撥和 shellcode 列表

除了上述方法之外,開發人員還引入了更多標準的混淆方法,這些方法通常會減慢程式碼的靜態分析速度,並且在多個惡意軟體元件中都很明顯。這方面的一個例子是字串混淆模式,即使用一組預定義的算術和邏輯操作對每個字串進行解碼,以便為每個字串選擇不同的運算元(例如移位偏移量)。這表明在編譯期間每個字串都是模糊的,並且開發者建立了一種 SDK 形式,有助於在構建期間對每個樣本進行獨特的混淆。

用於透過一組算術和邏輯運算從硬編碼 blob 中獲取明文字串的字串解碼邏輯

同樣,可以在程式碼中觀察到 API 呼叫混淆的多個例項。這是透過用其他存根函式替換對 API 函式的內聯呼叫來完成的,這些存根函式將請求的 API 名稱構建為堆疊字串,使用 GetProcAddress 解析它並在將特殊結構中提供的引數傳遞給存根函式的同時呼叫它。結構體的大小比傳遞引數資料所需的要大,並且其中大部分都充滿了垃圾,因此只有特定的欄位才有有意義的資料,這些資料在傳遞給存根之前會被編碼。這些欄位在存根函式中被解碼,然後傳遞給 API 函式。

GhostEmperor:透過利用核心以及ProxyLogon系列漏洞發起攻擊(下)

用於 API 呼叫混淆的存根示例

值得注意的是,在字串混淆的情況下,每個存根都是唯一構建的,並使用一個不同大小的引數結構,其中被實際引數資料佔用的欄位是隨機選擇的。堆疊字串的初始化順序也是隨機的,並且每個存根函式只用於替換單個內聯API函式呼叫一次。換句話說,在程式碼中不同地方使用的相同 API 函式將在每個地方有不同的存根,具有不同的引數結構。這強化了開發者使用指定混淆 SDK 的觀察結果,其中 API 呼叫混淆是另一個功能。

最後,可以看到一些變體以混淆和非混淆形式出現。例如,我們設法以兩種形式檢視第二階段載入程式的 C++ 版本,有一種形式根本沒有混淆,另一種形式嚴重混淆(MD5:18BE25AB5592329858965BEDFCC105AF)。在下圖中,我們可以在兩個變體中看到相同的函式:一個是編譯器生成的原始程式碼流,沒有經過混淆,而另一種是將控制流簡化到無法跟蹤操作順序的程度。

GhostEmperor:透過利用核心以及ProxyLogon系列漏洞發起攻擊(下)

在第二階段載入程式的兩個變體中使用的相同函式的示例;一個是非混淆的,另一個的控制流被簡化

Post-exploitation工具集

一旦攻擊者透過前面提到的感染鏈獲得了對被攻擊系統的訪問許可權,他們就會使用合法和開源的攻擊工具集來獲取使用者憑證,並轉向網路中的其他系統。這包括Sysinternals套件中用於控制程序的常用工具(例如,PsExec, PsList和ProcDump),以及其他工具,如WinRAR, CertUtil和BITSAdmin。至於開源工具,攻擊者使用如mimkat_ssp、Get-PassHashes。ps1、Token。exe、Ladon等工具。內部網路偵察和通訊通常由 NBTscan 和 Powercat 進行。

網路基礎設施

對於 C2 通訊,攻擊者註冊的域名似乎是隨機生成的,可能不會引起對惡意流量的任何關注。GhostEmperor 主要使用基於香港和韓國的託管服務,例如 Daou Technology 或 Anchent Asia Limited。

GhostEmperor:透過利用核心以及ProxyLogon系列漏洞發起攻擊(下)

我們還觀察到用於下載一些惡意樣本或記憶體植入程式的 C2 通訊的其他 IP 地址:

攻擊目標

GhostEmperor 的大多數受害者是東南亞的政府和電信公司,其中不乏馬來西亞、泰國、越南和印度尼西亞。我們還觀察到來自埃及、衣索比亞和阿富汗等國家受害者。儘管後一組受害者與我們看到 GhostEmperor 高度活躍的地區屬於不同的地區,但我們注意到其中的一些組織與東南亞國家有著密切的聯絡。

參考及來源:https://securelist。com/ghostemperor-from-proxylogon-to-kernel-mode/104407/