ssh-keysign-pwn - Linux 0-dayで非特権ユーザーがroot所有ファイルを読み取るPoC
(github.com/0xdeadbeefnetwork)- ssh-keysign-pwn は、非特権ユーザーが root 所有ファイルを読み取れるようにする Linux 脆弱性の PoC で、
31e62c2ebbfdより前のカーネルが対象だとされている - 中核となるバグは、
__ptrace_may_access()がtask->mm == NULLのときに dumpable チェック をスキップし、do_exit()がexit_files()より先にexit_mm()を実行することで、ファイルディスクリプタが開いたまま残る窓が生まれる構造にある - この窓の間に、呼び出し元の uid が対象プロセスと一致していれば
pidfd_getfd(2)が成功し、終了中のプロセスが開いているファイルディスクリプタを取得できる sshkeysign_pwnは/etc/ssh/ssh_host_{ecdsa,ed25519,rsa}_keyを取得し、ssh-keysign.cが 0600 権限の鍵を開いた後、permanently_set_uid()の前にEnableSSHKeysign=noで終了して、開いた fd を残す流れを利用するchage_pwnは/etc/shadowを取得し、chage -l <user>がspw_open(O_RDONLY)の後にsetreuid(ruid, ruid)で権限を完全に落とす流れで、終了レースを狙う- 実行は
makeの後に./sshkeysign_pwnでホスト鍵を、./chage_pwn rootで/etc/shadowの内容を標準出力に出力する方式で、100〜2000 回の spawn のうちに成功するとしている - 確認済みの環境は Raspberry Pi OS Bookworm 6.12.75、Debian 13、Ubuntu 22.04 / 24.04 / 26.04、Arch、CentOS 9
- 制御された対象 PoC として、
vuln_target.cは/etc/shadowを開いた後に権限を落とし、exploit_vuln_target.cは生存中のEPERMとSIGKILL後の fd 奪取を示す - 脆弱性は Qualys が報告し、Linus が 2026-05-14 に修正した。また Jann Horn は 2020 年 10 月に FD 奪取の形態 を指摘していたとされる
- README は NVD 項目として
https://nvd.nist.gov/vuln/detail/CVE-2026-46333を示している
1件のコメント
Lobste.rsの意見
ptraceを無効化するだけでは不十分。コミットメッセージと関数名のせいで誤解しやすいが、
ptrace_may_accessは複数の経路から呼ばれており、この概念実証(PoC)も実際にはptraceを使っていない緩和策はこれといってなく、現時点では 1) この特定のPoCにだけ弱く対処するために
/usr/lib64/misc/ssh-keysignの実行ビットをすべて外す、または 2) eBPF や systemtap などでpidfd_getfdをブロックする、といった程度に見える。前者はカーネルのパッチ適用や停止ができず、とにかく今すぐ寝なければならないときにだけ検討するレベルPoCは確認しておらず、ネット上で入手した任意のPoCの実行には、いつものことだが注意が必要
Qualysのアドバイザリはまだ公開されておらず、Linuxカーネルのセキュリティポリシーのため、linux-distros への配布をやむなく中止すると述べていた。怪しげな修正コミットからPoCまでLLMが素早く作れるようになり、状況は荒れてきており、以前なら数日待つこともできただろう
Qualysは本当に優れたチームだが、今回の件を自ら適切に発表する機会を持てなかったのは残念。公開されれば、間違いなく優れたアドバイザリになると思う
openssh はこの攻撃にとって都合のよい標的にすぎず、悪いのはそこではない。他の setuid バイナリも標的に選べるはず
/proc/sys/kernel/yama/ptrace_scopeを 2(admin-only attach) または 3(no attach) に設定すれば、既知のすべてのエクスプロイトを防げるという。ただし理論上は別の悪用手法があり得るpidfd_getfdを止める systemtap スクリプトを書かせたところ、結果は ここ にある。stap -g block_pidfd_getfd.stpで実行する必要があり、ネットで入手したものは何でもそうだが、実行前に必ずスクリプトを確認すべきカーネルがメインブランチに修正を公開コミットすることで、自ら 0-dayを公開してしまうのはやめてほしい。コミット に "Reported-by: Qualys" とまで書かれているので、明らかなセキュリティ修正だ
Greg K-Hは、カーネルセキュリティチームはセキュリティ修正の事前公開先を選べないため、結果として誰も事前公開を受けられないのだと書いていた
これは ssh の問題ではなく Linux の問題だ。タイトルもそう見えるべき
ssh-keysignが秘密ホストキーを開く前にEnableSSHKeysign=yesを先に確認していれば、デフォルトのようにこのオプションが無効なシステムは ホストキー窃取 に対して脆弱ではなかったはずだ。ssh-keysignが最初にこのオプションを確認しないのは驚き概念実証が気持ちいいほど短く、私の環境でも実際に脆弱だった
特定の条件下で、setuid 実行ファイルが開いた ファイルディスクリプタ にアクセスできるようにするものらしい。これが読み取りだけに限られる理由は見当たらず、ハッシュをクラックしなくても済む ローカル権限昇格(LPE) にひねることができそうだ
このPoCだけなら、
chmod -x /usr/lib/openssh/ssh-keysign /usr/bin/chageで壊せる。ssh-keysignのパスは変更が必要かもしれず、マニュアルページも参照できる。ただし根本原因は直らず、回避も可能そうだ。私の知る限り他の緩和策はないこの問題は ptrace: slightly saner 'get_dumpable()' logic で修正され、だから公開されてしまった。わずか10時間前のことだ
oss-security に送られた Qualys の公開告知もある。ディストリビューションとユーザーにパッチを当てる時間を与えるため、まだアドバイザリは公開しないとのこと。かなり興味深い内容になりそうで、それまでは grsecurity の Brad Spengler による解説 を見るとよい。このツイートが今回のPoC開発のきっかけになったようだ
exploit_vuln_target/vuln_targetの組はちゃんと動いた。あまりよくない現実的には、すでに 非特権アカウント を持つユーザーがいるシステムに影響するように見える。つまり、有効なログインがなければ、SSH がインターネットに公開されているサーバーでも、これだけで直接リモートコード実行を達成できるわけではない、という理解で合っている?