Jump to content

如何發現信標(一)

我們在上一篇文章介紹了對C2 框架執行威脅追踪的通用方法以及針對Cobalt Strike 的實際示例。接下來,我們將分析由Dark Vortex 開發的命令和控制框架Brute Ratel。其C2如下所示:

1.png

在過去的幾個月裡,該框架受到了密切關注,據稱最近被APT29 和勒索軟件組織BlackCat 濫用。因此,了解如何在基礎設施中普遍地檢測這個新興的C2對於防御者來說是有用的。

最初,所有分析都是在Brute Ratel v1.0.7上執行的,但是,我們進行了粗略的更新,討論了與v1.1 相關的發現,該發現是在我們最初的x33fcon 演示後不久發布的。 Brute Ratel 應該注意的一件事是,badger 的擴展性有限,主要從c2 通道的角度來看,除了v1.1 ,它增加了休眠混淆技術的擴展性。因此,它可以為工具創建非常具體的檢測。

Brute Ratel 的加載器Brute Ratel 的badger有多種形式,包括exe、DLL 和shellcode。當badger 被注入時,它的反射加載器將立即加載badger 所需的所有依賴項。由於badger 捆綁了大量的後利用功能,這導致在初始化時加載大量DLL:

2.png

如上所示,突出顯示的DLL 是注入badger 時加載的所有DLL。此列表包括winhttp.dll 和wininet.dll 的加載,它們不一定是惡意的,而是輸出信標的傳統加載。然而,還有一些不太常見的dll被加載,比如dbghelp.dll、credui.dll samcli.dll和logoncli.dll等。

這種行為允許我們為圖像加載創建一個簽名,並產生一個高信號指示器,可以通過圖像加載檢測來尋找。

例如,使用彈性查詢語言,我們可以搜索credui.dll、dbghelp.dll和winhttp.dll在一個進程中相互間隔60秒內發生的加載事件序列:

3.png

使用EQL 工具或Elastic 的雲,我們可以搜索我們的事件數據,例如從sysmon 日誌中提取的以下內容。請注意,我們明確排除了badger 可執行文件本身,因此我們只能識別注入的badger:

4.png

這將導致以下顯示檢測到被注入notepad.exe 的badger:

5.png

這個查詢特別強大,因為它允許我們在網絡中追溯尋找Brute Ratel badger的指標,而無需直接在終端上運行代碼。

內存中的Brute Ratel由於大多數信標仍然駐留在內存中,因此了解留下的足跡以尋找它們非常重要。查看1.0 版本的Brute Ratel 文檔,它詳細介紹了它自己的混淆和休眠實現:

6.png

這個查詢特別強大,因為它允許我們在網絡中追溯尋找Brute Ratel badger的指標,而無需直接在終端上運行代碼。

由於大多數信標仍然駐留在內存中,因此為了尋找它們,了解留下的足跡是很重要的。回顧一下Brute Ratel 1.0版本的文檔,它詳細介紹了它自己的混淆和休眠實現:

7.png

一旦badger進入休眠狀態,我們就可以使用Process Hacker 從進程中恢復字符串。有趣的是,當badger休眠時,我們可以看到如下字符串:

8.png

鑑於前面提到的在Brute Ratel 博客上描述的所謂的休眠和混淆策略,這最初是相當令人驚訝的。

深入挖掘後,我們可以發現一些有趣的設計決策,其中顯示在操作員UI 中的許多字符串都是從badger本身填充的。例如,我們可以在badger休眠時的內存中看到以下內容:

9.png

然後這些字符串返回到UI,如下所示:

10.png

深入研究badger,很快就發現只有.text 部分在休眠時被混淆,使得badger容易受到針對字符串和數據的各種簽名的影響。

為了說明這一點,反轉badger,我們可以將加載程序的入口點視為“bruteloader”:

11.png

在badger休眠時在內存中搜索這個字符串,我們可以在記事本進程中快速找到它:

12.png

這些字符串為內存掃描的Yara 規則提供了一個很好的基礎。例如,以下規則將在進程的內存中搜索bruteloader 或bhttp_x64.dll 字符串:

13.png

我們可以在badger休眠時針對我們的記事本進程測試這些以證明其有效性:

14.png

字符串不太可能存在於其他進程中,使用簡單的一行代碼就可以快速找到測試系統中所有被注入的badger:

15.png

使用Yara 規則,我們可以快速找到其他樣本,例如:

16.png

頁面權限通過對Brute Ratel混淆和睡眠策略的分析,可以觀察到badger在休眠期間對badger的頁面權限進行調整,以試圖逃避badger休眠時延長的可執行權限。

下面,我們可以看到badger 在sleep 0 上運行,badger 的頁面權限在未映射的頁面上為PAGE_EXECUTE_READ,這對於執行任務是必要的。

17.png

讓badger進入休眠狀態,我們可以看到混淆和休眠策略混淆了.text 部分並將badger的頁面權限重置為PAGE_READWRITE:

18.png

有趣的是,我們注意到在執行SMB 數據透視時不會復制此行為,即當兩個badger被關聯時。在這裡,我們可以看到我們的兩個badger相互關聯,並且都處於60 秒的休眠狀態:

19.png

對兩個badger 關聯時的頁面權限分析表明,無論休眠時間如何,兩者都保持PAGE_EXECUTE_READ:

20.png

結論是混淆和休眠策略僅適用於.text 部分。

出於對模糊處理和睡眠功能如何工作的好奇,我們開始對其進行逆向工程。通過windbg 中的sleep 例程,我們可以初步了解正在發生的事情,badger正在使用WaitForSingleObjectEx 在一系列異步過程調用(APC) 期間延遲執行,並利用間接系統調用來執行NtTestAlert 並在線程上強制發出警報:

21.png

深入了解IDA,我們可以更好地了解正在發生的事情。首先,它創建一個新線程,其起始地址被欺騙到TpReleaseCleanupGroupMembers+550 的固定位置:

22.png

然後為NtWaitForSingleObject、NtProtectVirtualMemory、SystemFunction032、NtGetContextThread 和SetThreadContext 的多個函數調用創建一系列上下文結構:

23.png

接下來,許多APC 排隊等待NtContinue,目的是使用它來代理對上述上下文結構的調用,這種技術是ROP的基本形式:

24.png

在對睡眠技術進行逆向工程後,我們很快意識到它與@ilove2pwn_的Foliage項目非常相似,只是硬編碼的線程起始地址不同。

儘管對badger進行了大量的調試和逆向工程,但我們無法揭示v1.0 博客文章中引用的“Windows 事件創建、等待對象和計時器”技術的任何實證,事實上,這些技術所需的API 似乎並沒有通過badger 的哈希導入來輸入。

Brute Ratel線程為了分析Brute Ratel 線程在內存中的外觀,我們將badger 注入到記事本的新副本中。隨即,我們可以看到休眠的badger使用的線程中有一些可疑的指標。

首先,我們注意到有一個看起來可疑的線程,其起始地址為0x0,並且在調用堆棧中有一個調用WaitForSingleObjectEx 的單獨的幀:

25.png

根據對線程調用堆棧的分析,我們可以推測該線程用於HTTP 通信,而badger現在正在休眠:

26.png

根據我們從對混淆和休眠策略進行逆向工程獲得的信息,我們注意到新線程是使用硬編碼的欺騙起始地址ntdll!TpReleaseCleanupGroupMembers+0x550 創建的:

27.png

我們無法找到任何作為起始地址自然發生的實例,因此導致了一個用於尋找Brute Ratel 線程的微不足道的指標。實際上,我們注入的記事本進程如下所示:

28.png

線程的調用堆棧也略有不規則,因為它不僅包含延遲執行的調用,而且第一幀指向ntdll.dll!NtTerminateJobObject+0x1f。深入了解為什麼使用NtNerminateJobObject 會突出顯示這只是NtTestAlert 的ROP 小工具,用於在線程上執行掛起的APC:

29.png

內存掛鉤在第一篇文章中,我們詳細介紹了兩種基於內存掛鉤檢測內存信標的潛在方法,通過查找已知補丁的簽名(例如ret to ntdll.dll!EtwEventWrite)並通過檢測寫入操作的副本。

將這些概念應用到Brute Ratel中,我們注意到,在操作員使用其開發後功能之前,badger不會應用任何內存掛鉤。一個例子是Sharpinline 命令,它在當前進程中運行一個.NET 程序集:

30.png

一旦組裝完成並且信標重新進入休眠狀態,我們可以通過附加調試器並反彙編ntdll.dll!EtwEventWrite 和amsi.dll!AmsiScanBuffer 的值來更好地了解發生了什麼:

31.png

如上所示,這些是禁用.NET ETW 數據和禁止AMSI 的簡單且持久的補丁。由於補丁是持久的,我們可以通過上述任何一種技術來檢測它們,因為我們不僅會因為EtwEventWrite 的第一條指令是ret 而收到高信號檢測,而且還會因為EtwEventWrite所在的頁面由於共享位的清除而被修改。

使用BeaconHunter,我們可以通過解析修改頁面上的導出信息,快速檢測出這些掛鉤,為惡意篡改提供了強有力的指示:

32.png

Brute Ratel C2 服務器遠離終端,作為防御者,我們也有興趣檢測命令和控制基礎設施,因為這可能有助於為我們提供足夠的智能來檢測基於網絡檢測的信標。

Brute Ratel的C2服務器是用golang開發的,默認情況下只允許操作員修改C2的默認登錄頁面。為了識別C2服務器,我們發現在向任何URI發送包含base64的POST請求時,都可能生成未處理的異常。例如,考慮下面base64 POST數據與明文數據的比較:

33.png

這很可能是因為base64 解碼POST 數據的預期輸入應符合C2 通信格式。一個簡單的Nuclei 規則可能會幫助我們掃描這種基礎設施:

34.png

除了與C2 的直接交互之外,還可以檢測C2 基礎設施,其中操作員沒有根據HTML 的哈希(http.html_hash=-1957161625) 手動重新定義默認登錄頁面。

使用一個簡單的Shodan查詢,我們可以快速找到暴露在互聯網上的實時基礎設施:

35.png

雖然只確定了大約40 個組織服務器,但根據地理分佈,我們可以更好地了解這些服務器的位置:

36.png

其中一些技術很可能已經為人所知,因為根據針對我們測試基礎設施的報告,防御者正在積極尋找這些C2 服務器:

37.png

蠻橫的Ratel 配置對Badger 的分析表明,Brute Ratel 在內存中維護了一個加密的配置結構,其中包括C2 終端的詳細信息。能夠從工件或正在運行的進程中提取這一點對防御者很有幫助。我們的分析表明,此配置保存在base64 和RC4 加密的blob 中,使用badger的工件中的固定密鑰“bYXJm/3#M?XyMBF”,而配置以明文形式存儲在內存中供休眠的badger使用。

我們開發了以下配置提取器,可用於

0 Comments

Recommended Comments

There are no comments to display.

Guest
Add a comment...