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