# ssh-keysign-pwn - Linux 0-day로 비권한 사용자가 root 소유 파일을 읽는 PoC

> Clean Markdown view of GeekNews topic #29544. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=29544](https://news.hada.io/topic?id=29544)
- GeekNews Markdown: [https://news.hada.io/topic/29544.md](https://news.hada.io/topic/29544.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-05-16T09:12:41+09:00
- Updated: 2026-05-16T09:12:41+09:00
- Original source: [github.com/0xdeadbeefnetwork](https://github.com/0xdeadbeefnetwork/ssh-keysign-pwn/)
- Points: 1
- Comments: 1

## Topic Body

- **ssh-keysign-pwn**은 비권한 사용자가 root 소유 파일을 읽을 수 있게 하는 Linux 취약점 PoC로, `31e62c2ebbfd` 이전 커널이 대상이라고 밝힘
- 핵심 버그는 `__ptrace_may_access()`가 `task->mm == NULL`일 때 **dumpable 검사**를 건너뛰고, `do_exit()`가 `exit_mm()`을 `exit_files()`보다 먼저 실행해 파일 디스크립터가 열린 채 남는 창이 생기는 구조임
- 이 창에서 호출자의 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 &lt;user&gt;`가 `spw_open(O_RDONLY)` 후 `setreuid(ruid, ruid)`로 권한을 완전히 내려놓는 흐름에서 종료 레이스를 노림
- 실행은 `make` 후 `./sshkeysign_pwn`으로 호스트 키를, `./chage_pwn root`로 `/etc/shadow` 내용을 표준 출력에 출력하는 방식이며, 100~2000회 스폰 안에 적중한다고 밝힘
- 확인된 환경은 **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 탈취 형태](https://lore.kernel.org/all/20201016230915.1972840-1-jannh@google.com/)를 짚었다고 밝힘
- README는 NVD 항목으로 `https://nvd.nist.gov/vuln/detail/CVE-2026-46333`을 제시함

## Comments



### Comment 57571

- Author: neo
- Created: 2026-05-16T09:12:42+09:00
- Points: 1

###### [Lobste.rs 의견들](https://lobste.rs/s/wskhre/linux_0_day_access_root_owned_files_as) 
- **ptrace 비활성화**만으로는 충분하지 않음. 커밋 메시지와 함수 이름 때문에 오해하기 쉽지만, `ptrace_may_access`는 여러 경로에서 호출되고 이 개념증명(PoC)도 실제로는 ptrace를 쓰지 않음  
  완화책은 마땅치 않고, 지금으로서는 1) 이 특정 PoC에만 약하게 대응하려고 `/usr/lib64/misc/ssh-keysign`의 전체 실행 비트를 제거하거나, 2) eBPF나 systemtap 같은 것으로 **`pidfd_getfd` 차단**을 하는 정도로 보임. 전자는 커널 패치나 종료를 못 하고 당장 자야 할 때나 고려할 수준임  
  PoC는 검토하지 않았고, 인터넷에서 받은 임의 PoC 실행에는 늘 그렇듯 주의가 필요함  
  Qualys 권고문은 아직 공개되지 않았고, Linux 커널 보안 정책 때문에 linux-distros 배포를 매우 유감스럽게 중단하겠다고 한 바 있음. LLM이 수상해 보이는 수정 커밋에서 PoC까지 빠르게 만들어낼 수 있게 되면서 상황이 거칠어졌고, 예전 같으면 며칠 기다리는 것도 가능했을 것임  
  Qualys는 정말 훌륭한 팀인데, 이번 일을 직접 발표할 제대로 된 순간을 갖지 못하게 된 건 아쉬움. 공개되면 분명 훌륭한 권고문일 거라고 봄  
  openssh는 이 공격에 편리한 표적일 뿐 잘못은 없고, 다른 setuid 바이너리도 표적으로 고를 수 있을 것임
  - [Qualys 업데이트](https://www.openwall.com/lists/oss-security/2026/05/15/8)에 따르면 `/proc/sys/kernel/yama/ptrace_scope`를 2(admin-only attach)나 3(no attach)으로 설정하면 알려진 모든 익스플로잇을 막는다고 함. 다만 이론적으로는 다른 악용 방식이 있을 수 있음
  - 빠른 완화책으로 LLM인 Opus에게 **`pidfd_getfd`를 막는 systemtap 스크립트**를 작성하게 했고, 결과는 [여기](https://tomsmeding.com/f/block_pidfd_getfd.stp)에 있음. `stap -g block_pidfd_getfd.stp`로 실행해야 하며, 인터넷에서 받은 모든 것처럼 실행 전에 반드시 스크립트를 검토해야 함
  - linux-distros 발표 링크가 있나? 찾을 수가 없음

- 커널이 메인 브랜치에 수정사항을 공개 커밋하면서 스스로 **0-day 공개**를 하는 일을 멈췄으면 함. [커밋](https://github.com/torvalds/linux/commit/31e62c2ebbfdc3fe3dbdf5e02c92a9dc67087a3a)에 “Reported-by: Qualys”라고까지 적혀 있으니 명백한 보안 수정임
  - 지난주에 이 문제로 [큰 논쟁](https://lobste.rs/s/eeifdc/copy_fail_732_bytes_root)이 있었음  
    [Greg K-H는](https://www.openwall.com/lists/oss-security/2026/05/01/3) 커널 보안팀이 보안 수정의 사전 공개 대상을 선택할 수 없으므로, 결과적으로 아무도 사전 공개를 받지 못한다고 썼음
  - 그럼 대신 어떻게 해야 하나?

- 이건 ssh 문제가 아니라 **Linux 문제**임. 제목도 그렇게 보여야 함
  - 제목이 오해를 부른다는 데 동의하지만, 어떻게 제목을 붙여야 할지 다른 생각이 없었음. 아직 수정할 수 있으니 제안이 있으면 좋겠음
  - 맞지만, 동시에 `ssh-keysign`이 개인 호스트 키를 열기 전에 `EnableSSHKeysign=yes`를 먼저 확인했다면, 기본값처럼 이 옵션이 꺼진 시스템은 **호스트 키 탈취**에 취약하지 않았을 것임. `ssh-keysign`이 가장 먼저 이 옵션을 확인하지 않는다는 점이 놀라움

- [개념증명](https://github.com/0xdeadbeefnetwork/ssh-keysign-pwn/blob/main/chage_pwn.c)이 기분 좋을 정도로 짧고, 내 장비들도 실제로 취약했음  
  특정 조건에서 setuid 실행 파일이 연 **파일 디스크립터**에 접근할 수 있게 해주는 것으로 보임. 이게 읽기에만 한정될 이유가 안 보이고, 해시를 크래킹하지 않아도 되는 **로컬 권한 상승(LPE)** 으로 비틀 수 있을 것 같음  
  이 PoC만은 `chmod -x /usr/lib/openssh/ssh-keysign /usr/bin/chage`로 깨뜨릴 수 있음. `ssh-keysign` 경로는 바꿔야 할 수 있고 [매뉴얼 페이지](https://manpages.debian.org/trixie/openssh-client/ssh-keysign.8.en.html)도 참고할 수 있음. 하지만 핵심 문제는 고치지 못하며 우회도 가능할 것 같음. 아는 한 다른 완화책은 없음  
  이 문제는 [ptrace: slightly saner 'get_dumpable()' logic](https://github.com/torvalds/linux/commit/31e62c2ebbfdc3fe3dbdf5e02c92a9dc67087a3a)에서 수정되었고, 그래서 공개되어 버렸음. 고작 10시간 전임  
  [oss-security에 보낸 Qualys의 공개 발표](https://www.openwall.com/lists/oss-security/2026/05/15/2)도 있음. 배포판과 사용자에게 패치할 시간을 주려고 아직 권고문은 공개하지 않는다고 함. 꽤 흥미로운 내용이 될 것 같고, 그동안은 [grsecurity의 Brad Spengler 해설](https://xcancel.com/spendergrsec/status/2054974174926430322)을 보면 됨. 이 트윗이 이번 PoC 개발을 촉발한 것으로 보임
  - PoC를 실행해 봤지만 경합에서 이기지는 못했음. 대신 `exploit_vuln_target`/`vuln_target` 쌍은 잘 동작했음. 별로 좋지 않음

- 현실적으로는 이미 **비권한 계정**을 가진 사용자가 있는 시스템에 영향을 주는 것 같음. 즉, 유효한 로그인이 없다면 SSH가 인터넷에 노출된 서버에서 이걸로 바로 원격 코드 실행을 달성할 수는 없는 게 맞나?
  - 맞음. 다만 며칠 전 올라온 [nginx 원격 코드 실행](https://lobste.rs/s/xnoqe8/achieving_nginx_remote_code_execution)처럼 다른 서비스로 RCE를 얻을 수 있다면 예외임
