ssh-keysign-pwn:ptrace 逻辑漏洞让普通用户读取 root 文件
ssh-keysign-pwn:内核
__ptrace_may_access()函数中存在六年的逻辑漏洞,由 Qualys 报告,Linus Torvalds 于 2026 年 5 月 14 日修复。非特权用户可读取 root 所有的文件,包括 SSH 主机私钥和/etc/shadow。所有31e62c2ebbfd之前的内核版本均受影响。
又补一个
2026 年 5 月对 Linux 内核来说不太好过。Dirty Frag、Fragnesia,现在又是 ssh-keysign-pwn——Qualys 在 5 月 14 日披露,Linus Torvalds 当天就修了。
这次跟前几个”往页缓存里写东西”的漏洞不太一样。它是一个纯粹的 __ptrace_may_access() 逻辑 bug——这是内核里决定一个进程能否检查另一个进程的函数。
| 指标 | 值 |
|---|---|
| 发现者 | Qualys 安全团队 |
| 修复者 | Linus Torvalds |
| 修复 commit | 31e62c2ebbfd |
| 潜伏时间 | ~6 年 |
| 首次发现 | Jann Horn(Google),2020 年 10 月 |
| PoC 发布者 | _SiCk |
| 影响 | 普通用户读取 root 文件 |
| 利用难度 | 100–2000 次尝试可窃取一次 |
漏洞原理
问题出在 __ptrace_may_access()。这个函数是进程自省的看门人——它检查一个进程是否有权限探查另一个进程的状态。
有一个特殊情况:当 task->mm == NULL 时(目标进程没有内存描述符——线程正在退出时会发生,内核线程也永远没有),函数完全跳过了 dumpable 检查。
可被利用的代码路径:
- 进程调用
do_exit()准备终止 do_exit()先跑exit_mm()——拆除内存描述符(mm)- 然后跑
exit_files()——但此时文件描述符仍然活着 - 此时
task->mm == NULL但 fd 还在,pidfd_getfd(2)就能偷走这些 fd——只要调用者的 uid 匹配
正常情况下,ptrace 访问检查会阻止低权限进程触碰 root 进程的打开文件句柄。但 mm == NULL 这个旁路把 dumpable 检查跳过了,剩下的交给 pidfd_getfd(2)。
这是一个典型的 TOCTOU 竞态,但窗口足够大——PoC 在 100–2000 次尝试内就能 hit。
攻击目标
发布了两个工具:
sshkeysign_pwn——攻击 ssh-keysign,一个签名主机认证挑战的辅助二进制。它会在调用 permanently_set_uid() 降权之前先打开 SSH 主机密钥文件(/etc/ssh/ssh_host_{ecdsa,ed25519,rsa}_key,0600 权限)。然后检查 sshd_config 里是否设置了 EnableSSHKeysign——如果没设,它直接退出,而密钥 fd 还开着。这个设计从 2002 年 起就在 OpenSSH 里了。
chage_pwn——攻击 chage -l <user>。它通过 spw_open(O_RDONLY) 打开 /etc/shadow,然后调用 setreuid(ruid, ruid)——两个参数都是真实 uid,所以完全降权。在降权和关闭文件之间的窗口里,fd 可以被偷走。
时间线
| 日期 | 事件 |
|---|---|
| ~2020 年 | Jann Horn 发现 FD 窃取模式并提出补丁(未合入) |
| 2026-05-14 | Qualys 报告漏洞;Linus Torvalds 提交修复(31e62c2ebbfd) |
| 2026-05-14 | Brad Spengler 发布分析 |
| 2026-05-14 | _SiCk 在 GitHub 发布 PoC |
| 2026-05-15 | Qualys 向 oss-security 发送披露邮件 |
从 2020 年 Jann Horn 的补丁提案到 2026 年 Qualys 的报告,这个 gap 很值得注意。补丁五年前就写好了,但从来没有合入主线。
修复方案
Linus 以 commit 31e62c2ebbfd 提交了修复。他在 commit message 里写道:
“我们有一个特殊的边缘情况:ptrace_may_access() 使用 ‘dumpable’ 来检查各种完全独立于 MM 的东西(典型如使用
PTRACE_MODE_READ_FSCREDS标志),包括那些已经没有 VM 的线程(甚至可能从来没有过,比如大多数内核线程)。这不是这个标志设计时的初衷,但事实就是如此。”
补丁调整了 ptrace 行为以正确处理 mm == NULL 的情况,实际上关闭了这个旁路窗口。
检查你的内核
uname -r
# 修复内核包含 commit 31e62c2ebbfd
# 所有 2026-05-14 之前的内核都受影响
值得注意的点
三件事让我印象深刻:
-
当天报告当天修复。 Linus 几小时内就搞定了。这对内核补丁来说快得不寻常——说明一旦理解了 bug,修起来很直接。
-
Jann Horn 2020 年就发现了。 社区在邮件列表存档里放着五年前的补丁提案。FD 窃取的模式早就知道,但没人推动它合入。
-
攻击目标是远古设计。
ssh-keysign的 fd 遗留模式始于 2002 年。chage的spw_open+setreuid序列也同样历史悠久。这不是 SSH 或 shadow-utils 的 bug——这是内核 bug 把特权二进制中既有的 fd 处理模式武器化了。
这是 2026 年 5 月第三个主要的 Linux 内核漏洞了,排在 Copy Fail 和 Dirty Frag 之后。披露节奏在加速——一方面因为 AI 辅助审计工具在更快地挖出老漏洞,另一方面因为披露生态在碎片化(embargo 被打破、补丁还没出 PoC 就公开了)。
参考
- 内核修复 commit:31e62c2ebbfd
- Phoronix 报道:Linux’s Latest Vulnerability Allows Reading Root-Owned Files
- GitHub PoC:0xdeadbeefnetwork/ssh-keysign-pwn
- 9to5Linux:Six-Year-Old Linux Kernel Flaw Lets Unprivileged Users Read Root-Owned Files
- Qualys oss-security:Logic bug in __ptrace_may_access()
- Jann Horn 2020 年补丁:lore.kernel.org