在2022年2月,卡巴斯基實驗室的研究人員首次觀察到將shellcode放入Windows事件日誌的技術。該技術允許在文件系統中隱藏“無文件”最後stager的木馬。這種對活動中事件日誌的關注不僅限於存儲shellcode。 Dropper 模塊還修復了與事件跟踪(ETW) 和反惡意軟件掃描接口(AMSI) 相關的Windows 原生API 函數,以使感染過程更加隱蔽。
除了事件日誌之外,攻擊者的工具集中還有許多其他技術。其中,開發者在功能中增加了偵察,可以模仿合法域名的C2 Web 域名,以及受害者使用的現有和軟件的名稱。為了使攻擊更加隱蔽,攻擊者使用Linode、Namecheap、DreamVPS 上的虛擬專用服務器。
一種更常見的方法是使用大量的反檢測解密器。攻擊者使用不同的編譯器,從微軟的cl.exe 或MinGW 下的GCC 到最新版本的Go。此外,為避免被檢測到,某些模塊使用數字證書進行簽名。研究人員認為它是由攻擊者發布的,因為遙測數據沒有顯示任何與之簽名的合法軟件,只有這次活動中使用的惡意代碼。
關於最後stager的特洛伊木馬,攻擊者決定使用多個基於HTTP 和命名管道。顯然,除了事件日誌之外,攻擊者還痴迷於內存注入,許多RAT 命令與它相關並且被大量使用。除了上述自定義模塊和技術外,攻擊者還使用了一些商業滲透測試工具,如Cobalt Strike 和SilentBreak 的工具集。
感染鏈研究人員從內存中的最後一個stager開始研究,然後使用遙測技術,重建了幾個感染鏈,該活動的針對性很強,且使用的大量工具還包括商業工具。
該活動包括各種技術和模塊,讓我們把它分成幾類來從技術上描述這個活動,比如商業滲透測試套件、圍繞它們的自定義反檢測包裝器和最後stager的木馬。
商業工具集有:反檢測包裝器——大量使用系統調用庫的Go 解密器,這可以使Cobalt Strike 模塊多次編碼,並使用AES256 CBC 加密blob,這是首次觀察到擁有Cobalt Strike 的Go的使用情況。
反檢測包裝器——一個庫啟動器,在MinGW 環境下使用GCC 編譯。這個stager唯一可能的原因是反檢測。
反檢測包裝器——AES 解密器,使用Visual Studio 編譯器編譯;
最後stagerRAT——基於HTTP 的木馬,可能的原始名稱是ThrowbackDLL.dll 和drxDLL.dll,但代碼比SilentBreak 的Throwback 的舊版本更複雜。
最後stagerRAT——基於管道的命名木馬,可能的原始名稱是monolithDLL.dll 和SlingshotDLL.dll。根據文件名,最後stager模塊可能是商業Slingshot 版本的一部分。
同樣,我們認為定制的一些模塊(如包裝器和最後stager)可能是商業產品的一部分。分類之後,我們準備一個一個地分析模塊。
初始感染我們觀察到的最早攻擊stager發生在2021 年9 月。 Cobalt Strike 模塊的傳播是通過說服目標下載合法站點file.io 上的.rar 鏈接並自行運行來實現的。內部Cobalt Strike 模塊的數字證書如下(在使用相同的活動期間,從wrapper 到last stagers 簽署了15 個不同的stager):
由於所有目標主機的感染情況不同,我們將僅描述觀察到的一種情況。由於能夠使用木馬將代碼注入任何進程,攻擊者可以自由地廣泛使用此功能將下一個模塊注入Windows 系統進程或受信任的應用程序(如DLP)。
記住截斷的進程注入,甚至模仿Web 域註冊,我們可以將攻擊過程描述為非常迭代(quite iterative):對一些模塊進行初始偵察,然後準備額外的攻擊。
商業工具集關於商業工具,這次活動中使用SilentBreak 和Cobalt Strike 工具集的痕跡非常明顯。名為ThrowbackDLL.dll 和SlingshotDLL.dll 的木馬讓我們想起Throwback 和Slingshot,它們都是SilentBreak 框架中的工具,而與dropper (sb.dll) 關聯的“sb”可能是供應商名稱的縮寫。
這裡我們要提一下,二進製文件中的幾個.pdb 路徑包含項目的目錄C:\Users\admin\source\repos\drx\ 以及其他未以Throwback 或Slingshot 命名的模塊,例如drxDLL.dll。但是,加密函數與公開可用的Throwback 代碼中的相同。
反檢測設計對於反檢測包裝器,使用了不同的編譯器。除了MSVC,Go 編譯器1.17.2 和MinGW 下的GCC 都在使用。解密器差異很大,它們包含的功能如下表所示:
幾個編譯器——可以使用Go 和C++ 模塊完成相同的AES256 CBC 解密;
列入白名單的啟動器——WerFault.exe 的自動運行副本將啟動器映射到進程地址空間;
數字證書——15 個文件使用“Fast Invest”證書籤名,我們沒有觀察到任何用它簽名的合法文件
修復ntdll.dll 的日誌記錄導出——為了更加隱蔽,Go dropper 將與日誌記錄相關的API 函數(如EtwEventWriteFull)修復到具有空功能的自地址空間中;
在事件日誌中保留shellcode——這是攻擊者的主要創新,使用next stager 加密的shellcode 被分成8 KB 的block並保存在事件日誌的二進制部分中;
C2 網絡域名模仿——攻擊者在使用標題中,註冊了一個ERP網絡域名;
這層感染鏈解密、映射到內存並啟動代碼。本文我們將僅介紹Cobalt Strike 的Go 解密啟動器。
主包中的函數名稱被混淆了,Main.init 從與事件日誌創建相關的kernel32.dll 和ntdll.dll 庫(WriteProcessMemory 和其他函數)中解碼Windows API 函數名稱。二進製文件中的每個名稱都連續四次使用base64 編碼。使用WriteProcessMemory,擁有“xor rax, rax; ret”的dropper在內存中編碼以下函數:EtwNotificationRegister、EtwEventRegister、EtwEventWriteFull、EtwEventWriteFull、EtwEventWrite。
在Main.start 中,惡意軟件會檢查主機是否在域中,並且只有在它為真時才起作用。然後動態解析上述函數的地址。下一個stager使用AES256(CBC 模式)加密,密鑰和IV 使用base64 編碼。
使用這種方法,研究人員需要編寫一些腳本來收集下一個模塊的加密部分。解密後,要獲得最終的可移植可執行文件,還需進一步轉換數據。
最後stager類型Last stager 有兩種通信機制——使用RC4加密的HTTP通信機制和使用命名管道的非加密通信機制。後一種方式在技術上能夠與任何網絡可見的外部主機通信,但在Windows環境中,命名管道是建立在SMB協議之上的,它幾乎不會對外部網絡開放。所以這些模塊很可能用於橫向移動。
在對惡意軟件集進行了介紹之後,我們現在將描述感染鏈,研究人員使用Cobalt Strike 滲透測試套件進行Dropper注入。
用DLL中的Dropper實現order劫持研究人員從wrapper-dropper 動態庫開始自定義模塊分析。此代碼被注入到諸如explorer.exe 之類的Windows 進程中。在加載到啟動程序進程的虛擬地址空間後,在其單個入口點,dropper 刪除由先前stager或執行創建的文件。
首先,該模塊將原始合法的操作系統錯誤處理程序WerFault.exe 複製到C:\Windows\Tasks。然後,它將一個加密的二進制資源放置到同一目錄中的wer.dll文件中,以進行典型的DLLorder劫持。為了持久化,該模塊將新創建的WerFault.exe設置為自動運行,在Software Microsoft\Windows\CurrentVersion\Run Windows系統註冊分支中創建一個Windows問題報告值。
dropper 不僅將啟動器放在磁盤上進行側載,而且還會將帶有shellcode 的信息消息寫入現有的Windows KMS 事件日誌。
被刪除的wer.dll是一個加載器,如果沒有隱藏在Windows事件日誌中的shellcode,它不會造成任何傷害。 dropper在事件日誌中搜索類別為0x4142(ASCII 中的“AB”)並以密鑰管理服務作為源的記錄。如果沒有找到,則通過ReportEvent() Windows API 函數(lpRawData 參數)將8KB 的shellcode 塊寫入信息記錄消息。從1423 開始,創建的事件ID 會自動遞增。
wer.dll 中的啟動器這個啟動器,被第一個stager放到Tasks 目錄中,它代理所有對wer.dll的調用,並將其導出到原始合法庫。在入口點,一個單獨的線程將所有上述8KB 片段組合成一個完整的shellcode 並運行它。由合法WerFault.exe 的副本創建的相同虛擬地址空間用於所有這些代碼。
為了防止WerFault 繼續其錯誤處理過程,DLL 使用典型的Blackbone trampoline修復啟動器的入口點
阻止合法啟動器執行的方法很新穎。在主線程中,wer.dll 找到它的入口點並用一個簡單的函數對其進行修復。上面屏幕截圖中的WaitAndExit() 只會使用日誌收集線程ID 調用WaitForSingleObject() ,然後退出,這意味著永遠不會執行真正的WerFault.exe 錯誤處理代碼:映射到其地址空間的欺騙性DLL 會阻止它。
Windows 事件日誌中的Shellcode
啟動器將控制傳輸到收集的shellcode 的第一個字節。在本文中,研究人員為下一個函數準備了三個參數:
下一個stager木馬的地址,它也包含在從事件日誌中提取的數據中;
導出函數名稱的標準ROR13 哈希在此木馬中加載(0xE124D840);
字符串“dave”和常量“4”的地址,它們成為導出函數的參數,可以通過哈希找到;
解析下一個Windows 可移植可執行文件以定位其入口點的做法是非常典型的。為了讓下一個stager的木馬不那麼顯眼,攻擊者清除了標題中的“MZ”魔法。在木馬的入口點調用代碼後,shellcode 還會搜索請求導出並調用它。
除了搜索入口點並調用它,shellcode 還通過硬編碼哈希搜索木馬導出,並使用參數“dave”和“4”運行找到的函數
HTTP木馬相比之前的輔助模塊,對於最後一個stager,我們會介紹的更詳細一些。 C++ 模塊顯然使用了SilentBreak(現為NetSPI)的Throwback 公共存儲庫中的代碼:基於XOR 的加密函數,一些示例的原始文件名,例如ThrowbackDLL.dll 等。讓我們從前面提到的Load()導出函數開始。這就像上面的WerFault補丁(函數在主木馬線程上等待),但是它忽略了任何參數,所以“dave”和“4”沒有被使用。這個啟動器可能支持比這個更多的模塊。
目標搜索該模塊使用單字節XOR 密鑰解密C2 域,在此示例中,只有一個域eleed[.]online。該木馬能夠處理其中的許多,以“|”字符分隔並加密。為了進一步通過普通HTTP進行通信,木馬從用戶代理“Mozilla 5.0”的集合中隨機選擇一個C2。
該惡意軟件通過收集以下信息生成一個追踪字符串,也用“|”分隔:
1.SOFTWARE\Microsoft\Cryptography 中MachineGUID 的值;
2.計算機名稱;
3.使用GetAdaptersInfo 獲取的本地IP 地址;
4.架構(x86 或x64);
5.操作系統版本;
6.當前進程是否有SeDebugPrivilege;
追踪識別器還將“1.1”附加到字符串(可能是惡意軟件版本)和當前配置的睡眠時間。
與C2進行加密的HTTP通信
在HTTP通信之前,該模塊使用硬編碼的32字節長的RC4密鑰發送空(但仍然加密)的ICMP數據包來檢查連接。與任何其他字符串一樣,此密鑰使用基於Throwback xor的算法加密。
如果ping端口為80的控制服務器成功,則將上述追踪數據發送到該控制服務器。作為回應,C2共享木馬主循環的加密命令。
木馬命令代碼的命令功能0——再次對目標進行追踪識別;
1——執行命令,木馬在新進程中執行接收到的命令並將結果發送回C2;
2——從URL 下載並保存到給定路徑;
3——設置新的睡眠時間,如果C2 尚未響應要執行的命令,則將此時間(以分鐘為單位)用作超時。隨機化公式為(0,9 - 1,1之間的隨機數)*睡眠時間;
4——在不改變配置的情況下休眠指定的分鐘數。
5——列出具有PID、路徑、所有者、名稱和父數據的進程;
6——將shellcode 注入並運行到目標進程的地址空間。要注入同一個進程,命令參數應該是“local”。與事件日誌中的shellcode 一樣,該代碼將運行提供的PE 的入口點以及通過哈希找到的特定導出。
99——終止木馬和C2之間的會話。
本次活動中使用的另一個木馬是基於管道命名的,這樣命令系統更有意義,包括特權升級、截圖、非活動時間測量等。繼續使用另一種最後stager的木馬類型,發現它被注入到了像edge.exe這樣的進程中。
基於管道命名的木馬木馬的位置是C:\Windows\apds.dll,具有相同名稱的原始合法Microsoft 幫助數據服務模塊庫位於C:\Windows\System32 中。木馬的主要工作週期是在一個單獨的線程。該惡意軟件還導出一個Load()函數,其唯一目的是等待一個工作線程,這是該活動的模塊的典型。
首先,木馬主線程獲取原始apds.dll並導出,並將其保存到內存中木馬映像之後的一個已分配的新堆緩衝區中。然後,木馬會編輯自己導出的函數數據,這樣它就可以通過如下精心製作的存根調用原始的apds.dll導出,其中的地址就是從真正的apds.dll解析出來的地址:
這個trampoline代碼取自Blackbone Windows內存黑客庫(remotemmemory:BuildTrampoline函數)。 DLL劫持並不是什麼新鮮事,我們已經多次看到這種技術被用於代理合法函數,但僅用短存根重新創建自導出來調用原始合法函數卻很不尋常。然後,該模塊創建一個雙工命名的管道“MonolithPipe”,並進入它的主循環。
工作週期在對導出函數進行上述操作後,該模塊會輕微地使用架構和Windows 版本信息對主機進行追踪識別。木馬還使用提到的稀有常量初始化一個隨機的11 字節ASCII 字符串,例如這裡的init_keys 函數。結果用作唯一的會話ID。
惡意軟件連接到端口443 上的硬編碼域(在本例中為https://opswat[.]info:443),並向C2 端的submit.php 發送POST 請求。 HTTPS 連接選項設置為接受服務器端的自簽名證書。在本例中,C2通信使用Dhga(81K1!392-!(43KakjaiPA8$#ja密鑰的RC4算法加密。對於基於管道命名的木馬,常用的命令有:
0——將“continue”標誌設置為False 並停止工作;
1——N/A,保留至今;
2——獲取自上次用戶輸入以來的時間(以分鐘為單位);
3——獲取當前進程信息:PID、架構、用戶、路徑等;
4——獲取主機域和用戶帳戶;
5——使用提供的憑據模擬用戶;
6——獲取當前進程的可用權限;
7——使用cmd.exe 解釋器執行命令;
8——使用與給定主機(地址和端口)的原始TCP 套接字測試的連接;
9——獲取正在運行的進程信息:路徑、所有者、名稱、父進程、PID等;
10——使用提供的ID 的進程令牌模擬用戶;
11——列出目錄中的文件;
12——截取屏幕截圖;
13——將內容寫入文件;
14——讀取文件內容;
15——刪除文件;
16——將提供的代碼注入到具有給定名稱的進程中。
17——在C2上運行shellcode;
研究人員現在已經介紹了該活動的三個層面,有趣的是,研究人員觀察到一個木馬俱有如上表所示的完整命令集,但仍然使用rc4加密的HTTP與C2通信,而不是指定管道。最後一個stager的示例看起來像一個模塊化的平台,攻擊者能夠根據他們當前的需要組合其功能。
基礎設施
研究人員認為這些代碼是自定義的(木馬、包裝器),與以前已知的活動或以前註冊的SilentBreak工具集模塊沒有相似之處。現在研究人員不願意給這個活動命名,而是堅持只用“SilentBreak”。