1. 摘要

這份研究報告提供了對 Common Unix Printing System (CUPS) 中發現的關鍵漏洞鏈的完整技術分析,特別聚焦於 CVE-2026-34980 與 CVE-2026-34990 [1] 。該漏洞鏈允許未經身分驗證的遠端攻擊者以非特權的 lp 使用者身分達成遠端程式碼執行 (RCE),隨後可進一步提升至 root 層級的檔案覆蓋能力。本研究剖析了 PostScript 佇列管理中的底層解析缺陷,以及本機認證機制遭利用的過程。這些發現凸顯了處理舊版協定所帶來的持續風險,以及在系統層級 spooling 服務中實施嚴謹輸入驗證的重要性。

印表機竟成駭客跳板?Newline Smuggling 搭配 PPD 注入,無需帳密即可透過 IPP 遠端執行任意程式碼 | 資訊安全新聞

2. CUPS 架構與攻擊面簡介

CUPS 是類 Unix 作業系統主要的列印中介軟體,透過 Internet Printing Protocol (IPP) 管理列印請求。其架構包含一個中央排程器 ( cupsd )、多個用於文件轉換的 filter,以及用於將資料傳輸到實體或虛擬印表機的 backend [1] 。雖然排程器通常以 root 權限執行,但 filter 與 backend 多半在 lp 服務帳號下執行,以降低潛在入侵帶來的影響。然而,CUPS 的複雜性(特別是對舊版 PostScript Printer Description (PPD) 檔案以及多樣 URI scheme 的支援)構成了顯著的攻擊面。

本次分析的漏洞凸顯了兩種不同的失敗模式:第一,在序列化與重新解析過程中對 job 屬性的清理失敗;第二,在建立暫時印表機物件時,本機管理 token 處理邏輯上的缺陷。與其他 URI 相關的漏洞(例如 CVE-2025-3155,其中不當處理 ghelp:// scheme 導致本機檔案讀取漏洞)類似 [2] ,CUPS 漏洞也利用了排程器與其內部設定資料之間的信任關係。

3. CVE-2026-34980 技術分析:遠端程式碼執行

3.1. 屬性序列化與換行字元走私

CVE-2026-34980 的核心在於序列化列印 job 屬性時,對特殊字元處理不一致。當 CUPS 處理 Print-Job 請求時,會在換行字元前加上反斜線來跳脫。然而,後續的解析邏輯在資料被記錄或由像 pstops 這類 filter 重新解析時,並未維持這層隔離 [1]

攻擊者可將換行字元走私到列印選項中(例如 page-border )。當 pstops 遇到無效值時,會記錄一則錯誤訊息。如果該值包含走私的換行字元,則記錄輸出的第二行可被偽造成一個受信任的控制記錄。

  1. /*
  2. * Smuggled Newline in Attribute Serialization
  3. * The attacker provides a value like: "none\nPPD:cupsFilter2 \"text/plain 0 - /usr/bin/vim\""
  4. */
  5. if (strchr(" \t\n\\\'\"", *valptr))
  6. *optptr++ = '\\'; // Escaping newline with backslash
  7. /*
  8. * Later, during reparsing, the backslash is stripped,
  9. * but the newline remains as a structural delimiter.
  10. */
  11. if (*ptr == '\\' && ptr[1])
  12. _cups_strcpy(ptr, ptr + 1); // Stripping the backslash

3.2. PPD 注入與 Filter 挾持

cupsd 排程器會將 filter 的 stderr 中以 PPD: 開頭的行視為受信任的設定更新。透過上述的換行字元注入手法將此前綴走私進去,攻擊者就能將任意選項注入佇列的 PPD 檔案。最重要的注入目標是 cupsFilter2 指令,它定義了針對特定 MIME 類型要執行的二進位程式。

graph TD A[Remote Attacker] -->|Malicious Print-Job| B[CUPS Scheduler] B -->|Serialize Attributes| C[pstops Filter] C -->|Log Error
with Smuggled Newline| D[stderr: PPD:cupsFilter2...] D -->|Reparse as Trusted| B B -->|Update PPD| E[Queue Configuration] A -->|Second Raw Job| B B -->|Execute Malicious Filter| F[RCE as lp user]

4. CVE-2026-34990 技術分析:權限提升至 Root

4.1. 本機認證 Token 洩漏

一旦以 lp 使用者身分達成 RCE,攻擊者就能利用 CVE-2026-34990 取得 root 存取權。此漏洞利用了 CUPS 在 loopback 介面上用於管理任務的 Local 認證機制。攻擊者可以在本機埠號上建立一個假的印表機監聽程式,並觸發 CUPS 連線到它。藉由回應一個帶有 WWW-Authenticate: Local trc="y" 標頭的 401 Unauthorized ,攻擊者就能騙取 cupsd 提供它自己的管理 token [1]

  1. /*
  2. * Attacker's Fake Printer Response
  3. * Triggers CUPS to send the local admin token from /var/run/cups/certs/0
  4. */
  5. HTTP/1.1 401 Unauthorized
  6. WWW-Authenticate: Local trc="y"

4.2. Race Condition 與檔案 URI 濫用

利用偷來的 token,攻擊者可以下達管理指令。雖然 CUPS 通常會基於安全考量限制 file:/// URI,但在處理暫時印表機時存在一個邏輯缺陷。如果一台印表機被標記為 shared, temporary 旗標會被清除,但不會重新驗證 URI scheme [1] 。這造成了一個 race condition:攻擊者必須在排程器的背景驗證移除危險佇列之前,設定好 printer-is-shared 屬性。

  1. /*
  2. * Vulnerable Logic in cupsd
  3. * Clearing the temporary flag bypasses URI re-validation
  4. */
  5. printer->shared = ippGetBoolean(attr, 0);
  6. if (printer->shared && printer->temporary)
  7. printer->temporary = 0; // Flag cleared, URI file:/// persists
  8. /*
  9. * Final Root Write Primitive
  10. * The scheduler opens the file URI as root
  11. */
  12. else if (!strncmp(job->printer->device_uri, "file:///", 8))
  13. job->print_pipes[1] = open(job->printer->device_uri + 7,
  14. O_WRONLY | O_CREAT | O_TRUNC, 0600);

5. 與 URI 處理漏洞之比較

CUPS 中 URI scheme 的漏洞利用,與 Yelp 應用程式中的 ghelp:// 漏洞有驚人的相似之處 [2] 。在這兩個案例中,應用程式都作為特定 URI scheme 的 handler,且未能充分隔離透過該 scheme 存取的資源。Yelp 的漏洞導致透過 XInclude 與 SVG 指令碼注入來任意讀取檔案,而 CUPS 漏洞鏈則產生了更嚴重的寫入低階操作。

特性 CUPS (CVE-2026-34980/90) Yelp (CVE-2025-3155)
主要向量 IPP Print-Job / PPD 注入 ghelp:// URI Scheme
漏洞類型 解析缺陷 / 邏輯錯誤 本機檔案讀取漏洞 (LFI)
影響 從遠端 RCE 到 Root 寫入 任意檔案讀取
緩解措施 停用共用佇列 / AppArmor 清理 URI Handler

6. 結論與緩解策略

CUPS 漏洞鏈證明了,即使是成熟的系統服務,在處理舊版設定與本機信任邊界時,仍可能藏有嚴重的缺陷。從一個未經身分驗證的網路請求,逐步發展到 root 層級的檔案覆蓋,是靠一連串微小且被忽略的解析與邏輯錯誤才得以實現。

為了降低這些風險,系統管理員應確保 CUPS 不暴露於不受信任的網路環境,尤其是當啟用了共用的 PostScript 佇列時。此外,使用強制存取控制 (MAC) 系統(如 SELinux 或 AppArmor)對於限制 cupsd 程序的活動至關重要,即使漏洞被成功利用,也能防止它寫入像是 /etc/sudoers.d/ 這類敏感的系統目錄 [1]