對Exchange服務(wù)器的攻擊活動之所以引人注目,是因為它使用了一個以前不為人知的Windows內(nèi)核模式rootkit(我們稱之為Demodex),以及一個復(fù)雜的多階段惡意軟件框架,旨在提供對被攻擊服務(wù)器的遠程控制。該攻擊還涉及一個名為Cheat Engine的開源項目的內(nèi)核模式組件,以繞過 Windows 驅(qū)動程序簽名強制機制。早在2020年7月針對Exchange 服務(wù)器的攻擊就開始了。
技術(shù)分析
大多數(shù)GhostEmperor(研究人員暫定的名稱)感染是部署在面向公共的服務(wù)器上,因為許多惡意工件是由Apache服務(wù)器進程“httpd.exe”、IIS Windows服務(wù)器進程“w3wp.exe”或Oracle服務(wù)器進程“oc4j.jar”安裝的。這意味著攻擊者可能會濫用在這些系統(tǒng)上運行的web應(yīng)用程序中的漏洞,允許他們刪除和執(zhí)行他們的文件。
值得一提的是,其中一次 GhostEmperor 感染影響了 Exchange 服務(wù)器,發(fā)生在 2021 年 3 月 4 日。這距離微軟發(fā)布 ProxyLogon 漏洞補丁僅兩天,攻擊者可能利用了這一點漏洞,以允許他們在易受攻擊的 Exchange 服務(wù)器上實現(xiàn)遠程代碼執(zhí)行。
雖然GhostEmperor的感染通常始于一個BAT文件,但在某些情況下,已知的感染鏈之前還會有一個階段,一個由wdichost.exe加載的惡意DLL, wdichost.exe是微軟最初稱為mpcmrun .exe的合法命令行實用程序。然后,側(cè)加載DLL解碼并加載一個名為license.rtf的附加可執(zhí)行文件。不幸的是,我們無法檢索這個可執(zhí)行文件,但是我們看到加載它的連續(xù)操作包括通過wdichost.exe創(chuàng)建和執(zhí)行GhostEmperor腳本。
攻擊從PowerShell滴管開始發(fā)起,它會創(chuàng)建幾個注冊表項,并將加密數(shù)據(jù)分配給它們。腳本本身是以打包形式傳播的,因此它的完整執(zhí)行依賴于一個命令行參數(shù),該參數(shù)被用作解密其大量邏輯和數(shù)據(jù)的密鑰。沒有這個密鑰,這個階段之后的流量是不可能恢復(fù)的。
初始階段由加密的PowerShell代碼組成,這些代碼在運行時根據(jù)攻擊者提供的AES密鑰解密
下一階段由前者作為服務(wù)執(zhí)行,目的是作為下一階段的先前階段。它用于從先前寫入的注冊表項中讀取加密的數(shù)據(jù),并對其進行解密,以啟動內(nèi)存植入的執(zhí)行。我們確定了該組件的兩種變體,一種是用 C++ 開發(fā)的,另一種是用 .NET 開發(fā)的。后者最早在2021年3月就出現(xiàn)了,它使用受感染計算機的GUID來獲得解密密鑰,可以在特定的系統(tǒng)上執(zhí)行。另一方面,c++變體依賴硬編碼的AES 256加密密鑰。
第三個階段是核心植入,它被上述加載程序部署后在內(nèi)存中運行,并被注入到新創(chuàng)建的svchost.exe進程的地址空間中。它的主要目標是為與C2服務(wù)器的流量通道提供便利,在此基礎(chǔ)上,基于嵌入在其配置中的可擴展C2配置文件,惡意流量將被偽裝成與良性服務(wù)的流量。需要注意的是,最初在 Cobalt Strike 框架中提供的 Malleable C2 功能的實現(xiàn)是根據(jù) Cobalt Strike 代碼的逆向工程進行自定義和重寫的。
最后一個階段是由上述植入程序注入 winlogon.exe 進程的有效載荷,用于向攻擊者提供遠程控制功能。此類功能包括啟動遠程控制臺或桌面會話,后者支持在目標計算機上執(zhí)行發(fā)送的鼠標點擊和擊鍵,以及檢索反映這些操作輸出的定期屏幕截圖。此階段還允許攻擊者加載任意 .NET 程序集或執(zhí)行 PowerShell 命令,以及完全控制受害者的文件系統(tǒng)以搜索、檢索或推送文件。
除了最后階段有效載荷之外,核心組件還能夠在系統(tǒng)上部署Windows內(nèi)核模式驅(qū)動程序。該驅(qū)動程序的目的是作為一個rootkit,隱藏惡意軟件的工件,如文件,注冊表鍵和網(wǎng)絡(luò)流量,從而獲得隱蔽性和避免被安全產(chǎn)品和取證調(diào)查人員檢測到的能力。接下來的章節(jié)會詳細介紹這個驅(qū)動程序是如何部署的(即它是如何繞過Windows緩解的,假設(shè)它不是數(shù)字簽名的),以及它為用戶模式惡意植入提供了哪些特殊功能。
在64位Windows操作系統(tǒng)上,由于Microsoft引入的驅(qū)動程序簽名強制機制,通常不可能以文檔化的方式加載未簽名的驅(qū)動程序。由于這個原因,攻擊者利用有符號驅(qū)動程序中的漏洞,允許在內(nèi)核空間中執(zhí)行無符號代碼。到目前為止,許多攻擊者所采取的一種典型的方法,主要是在舊版本的Windows中,是通過切換nt!g_CiEnabled標志,在通過易受攻擊的簽名驅(qū)動程序獲得寫入和執(zhí)行原語之后駐留在CI.DLL內(nèi)核模塊中。在關(guān)閉代碼完整性機制之后,可以加載一個未簽名的驅(qū)動程序。
這個rootkit的開發(fā)人員所使用的方法允許加載一個未簽名的驅(qū)動程序,而無需修改代碼完整性圖像和處理潛在的崩潰。它濫用了名為dbk64.sys 的合法開源簽名驅(qū)動程序的功能,該驅(qū)動程序隨 Cheat Engine 一起提供,Cheat Engine 是一個應(yīng)用程序,旨在繞過視頻游戲保護并將作弊功能引入其中。該驅(qū)動程序通過設(shè)計提供了在內(nèi)核空間中編寫和執(zhí)行代碼的能力,從而允許它在內(nèi)核模式下運行任意代碼。
在將帶有隨機生成文件名的 dbk64.sys 驅(qū)動程序放到磁盤并加載它之后,惡意軟件會向驅(qū)動程序發(fā)出記錄的 IOCTL。
值得一提的是,該惡意軟件的服務(wù)在加載 dbk64.sys 驅(qū)動程序期間使用了名為 kernelmoduleuloader.exe(MD5:96F5312281777E9CC912D5B2D09E6132)的作弊引擎實用程序。該驅(qū)動程序與實用程序和 .sig 文件一起被釋放,后者被用作通過傳送與其二進制文件關(guān)聯(lián)的數(shù)字簽名來驗證調(diào)用 dbk64.sys 的組件的手段。
由于惡意軟件不是Cheat Engine的組件,它以一個新進程的形式運行kernelmoduleunload .exe,并向它注入一個小型shellcode,該 shellcode 僅使用 CreateFileW API 打開 dbk64.sys 設(shè)備的句柄。
Rootkit 加載介紹
將加載的rootkit命名為Demodex,其目的是隱藏該惡意軟件服務(wù)的多個工件。這是通過rootkit的驅(qū)動程序暴露的一組 IOCTL實現(xiàn)的,這些 IOCTL 依次由服務(wù)的用戶模式代碼調(diào)用,每個IOCTL都隱藏了一個特定的惡意工件。要訪問rootkit的功能,惡意軟件應(yīng)該獲得相應(yīng)的設(shè)備對象的句柄。
有趣的是,傳遞給 CmRegisterCallback 的指針不包含處理上述邏輯的函數(shù)的直接地址,而是包含 pci.sys 驅(qū)動程序映像的可執(zhí)行部分末尾的地址,該地址最初用零填充對齊內(nèi)存中的部分。在將回調(diào)指針傳遞給 CmRegisterCallback 之前,會在 pci.sys 驅(qū)動程序中尋找這樣的部分,并修補其中的相應(yīng)字節(jié),以便調(diào)用對處理上述邏輯的實際回調(diào)的調(diào)用,如下所述。這允許所有攔截的注冊表操作看起來好像它們是由源自合法 pci.sys 驅(qū)動程序的代碼處理的。
用于修復(fù)內(nèi)存中 pci.sys 映像中的部分的代碼,以便使用跳轉(zhuǎn)到注冊表檢查回調(diào)的短 shellcode 存根編寫它
值得一提的是,Demodex rootkit在設(shè)計上支持Windows 10,根據(jù)我們在Windows 10構(gòu)建上的測試,它確實似乎可以工作。這在多個位置的驅(qū)動程序代碼中很明顯,其中根據(jù)底層操作系統(tǒng)的版本采用不同的代碼流程。在此類檢查中,可以觀察到某些流程對應(yīng)于 Windows 10 的最新版本,如下面的代碼片段所述。
網(wǎng)絡(luò)基礎(chǔ)設(shè)施
對于C2通信,攻擊者注冊的域名似乎是隨機生成的,可能不會引起對惡意流量的任何關(guān)注。
用于下載一些惡意樣本或內(nèi)存植入程序的 C2 通信的其他 IP 地址如下:
反混淆分析方法
已經(jīng)發(fā)現(xiàn)的GhostEmperor活動樣本中使用的惡意軟件組件的開發(fā)者已經(jīng)做出了一些對取證分析過程有影響的應(yīng)對策略。首先,由于 Demodex 的加載方式,它的驅(qū)動程序沒有正確地與其他系統(tǒng)模塊一起以文檔化的方式加載到 WinDbg 中。也就是說,仍然可以通過引用其名稱 (\driver\dump_audio_codec0) 來找到 rootkit 的驅(qū)動程序?qū)ο?,從而也可以列出其關(guān)聯(lián)的設(shè)備對象:
WinDBG中列出的驅(qū)動程序?qū)ο竺Q
類似地,當嘗試使用 Volatility3 widows.driverscan 模塊列出系統(tǒng)模塊時,輸出中不存在Demodex驅(qū)動程序。然而,框架確實表明在掃描內(nèi)核內(nèi)存空間尋找驅(qū)動程序的過程中檢測到異常:
使用 windows.driverscan Volatility3 模塊列出Demodex驅(qū)動程序時出現(xiàn)異常
此外,惡意軟件開發(fā)者有意選擇從惡意軟件的第三階段和 rootkit 驅(qū)動程序的內(nèi)存加載圖像中刪除所有 PE 標頭。這是通過引入帶有清零標頭的圖像開始(如第三階段的情況)并依靠自定義加載器來準備執(zhí)行或通過在加載后替換圖像的標頭來完成0x00 值,就像 rootkit 的驅(qū)動程序一樣。從取證的角度來看,這會阻礙通過搜索標頭文件來識別加載到內(nèi)存中的 PE 圖像的過程。
如上所述,開發(fā)人員在 pci.sys 合法驅(qū)動程序中實現(xiàn)了一個跳轉(zhuǎn)操作,以屏蔽為注冊表相關(guān)操作調(diào)用的回調(diào)源。因此,試圖追蹤此類回調(diào)的分析師可能會錯過一些回調(diào),因為它們似乎是良性回調(diào)。
值得注意的是,在字符串混淆的情況下,每個存根都是唯一構(gòu)建的,并使用不同大小的參數(shù)結(jié)構(gòu),其中實際參數(shù)數(shù)據(jù)占用的字段是隨機選擇的。堆棧字符串初始化的順序也是隨機的,每個存根函數(shù)只被使用一次,作為單個內(nèi)聯(lián)API函數(shù)調(diào)用的替換。換句話說,在代碼中不同位置使用的相同API函數(shù)對于每個位置都有不同的存根,并具有不同的參數(shù)結(jié)構(gòu)。這證明開發(fā)者使用了一個指定的混淆SDK,其中API調(diào)用混淆是另一個特性。
除此之外,開發(fā)人員還引入了更多標準的混淆方法,這些方法通常會減慢代碼的靜態(tài)分析速度,并且在多個惡意軟件組件中都表現(xiàn)得很明顯。這方面的一個示例是字符串混淆模式,其中每個字符串都使用一組預(yù)定義的算術(shù)和邏輯運算進行解碼,以便為每個字符串選擇不同的操作數(shù)(例如,移位偏移)。這表明在編譯期間對每個字符串進行了混淆,并且開發(fā)者已經(jīng)建立了一種 SDK 形式,有助于在構(gòu)建期間對每個樣本進行唯一的混淆。
最后,可以看到一些變體以混淆和非混淆的形式同時出現(xiàn)。例如,我們以兩種形式查看c++版本的第二階段加載器——一種完全沒有混淆,另一種嚴重混淆(MD5: 18BE25AB5592329858965BEDFCC105AF)。在下圖中,我們可以看到兩個變體中的相同函數(shù):一個是編譯器生成的原始代碼流,沒有經(jīng)過混淆,而另一個的控制流程混淆到不可能跟蹤操作順序的程度。
Post-exploitation工具集
一旦攻擊者通過上述感染鏈獲得對受感染系統(tǒng)的訪問權(quán)限,他們就會混合使用合法和開源攻擊工具集來獲取用戶憑據(jù)并轉(zhuǎn)向網(wǎng)絡(luò)中的其他系統(tǒng)。這包括 Sysinternals 套件中用于控制進程的常用實用程序(例如 PsExec、PsList 和 ProcDump),以及其他工具,如 WinRAR、CertUtil 和 BITSAdmin。對于開源工具,攻擊者使用了mimkat_ssp、Get-PassHashes.ps1、Token.exe、Ladon等工具,內(nèi)部網(wǎng)絡(luò)偵察和流量通常由NBTscan和Powercat執(zhí)行。Sysinternals 之前為Winternals公司提供的免費工具,Winternals原本是一間主力產(chǎn)品為系統(tǒng)復(fù)原與資料保護的公司,為了解決工程師平常在工作上遇到的各種問題,便開發(fā)出許多小工具。