ssh-keysign-pwn: Leyendo archivos de root mediante un error lógico en ptrace
ssh-keysign-pwn: Un error lógico de seis años en
__ptrace_may_access(), reportado por Qualys y reparado por Linus Torvalds el 14 de mayo de 2026. Usuarios no privilegiados pueden leer archivos de root, incluyendo claves privadas SSH de host y/etc/shadow. Todos los kernels anteriores a31e62c2ebbfdestán afectados.
Otra Más
Mayo de 2026 no ha sido bondadoso con el kernel de Linux. Dirty Frag, Fragnesia, y ahora—ssh-keysign-pwn—divulgado por Qualys el 14 de mayo y reparado por Linus Torvalds el mismo día.
Esta es diferente de la familia “copiar algo en el page cache”. Es un error lógico puro en __ptrace_may_access(), la función del kernel que decide si un proceso puede inspeccionar a otro.
| Métrica | Valor |
|---|---|
| Reportado por | Qualys Security Advisory |
| Reparado por | Linus Torvalds |
| Commit de reparación | 31e62c2ebbfd |
| Oculto por | ~6 años |
| Detectado primero por | Jann Horn (Google), octubre 2020 |
| PoC publicado por | _SiCk |
| Impacto | Leer archivos de root como usuario no privilegiado |
| Complejidad del exploit | 100–2000 intentos por robo exitoso |
Cómo Funciona
El error está en __ptrace_may_access(). Esta función es la guardiana de la introspección de procesos—verifica si un proceso puede hurgar en el estado de otro.
Hay un caso especial: cuando task->mm == NULL (el proceso objetivo no tiene descriptor de memoria — ocurre cuando un hilo está saliendo, o para hilos del kernel), la función omite completamente la verificación de dumpable.
El camino de código que hace esto explotable:
- Un proceso llama a
do_exit()para terminar do_exit()ejecutaexit_mm()primero — elimina el descriptor de memoria (mm)- Luego ejecuta
exit_files()— pero los descriptores de archivo siguen vivos - Con
task->mm == NULLpero los fds aún abiertos,pidfd_getfd(2)puede robarlos si el uid del llamante coincide
Normalmente, las comprobaciones de acceso ptrace bloquearían a un proceso con menos privilegios de alcanzar los archivos abiertos de un proceso root. Pero la omisión de mm == NULL salta la verificación de dumpable, y pidfd_getfd(2) hace el resto.
Esto es un clásico TOCTOU, pero la ventana es suficientemente amplia—el PoC acierta en 100–2000 intentos.
Objetivos del Exploit
Se publicaron dos herramientas:
sshkeysign_pwn — ataca ssh-keysign, un binario auxiliar que firma desafíos de autenticación de host. Abre los archivos de clave SSH de host (/etc/ssh/ssh_host_{ecdsa,ed25519,rsa}_key, modo 0600) antes de llamar a permanently_set_uid() para bajar privilegios. Luego verifica si EnableSSHKeysign está configurado en sshd_config — si no, sale con los fds de las claves aún abiertos. Este diseño está en OpenSSH desde 2002.
chage_pwn — ataca chage -l <user>. Abre /etc/shadow mediante spw_open(O_RDONLY), luego llama a setreuid(ruid, ruid) — bajando todos los privilegios. En la ventana entre la bajada de privilegios y el cierre del archivo, el fd es robable.
Línea de Tiempo
| Fecha | Evento |
|---|---|
| ~2020 | Jann Horn identifica el patrón de robo de FD y propone un parche (no fusionado) |
| 2026-05-14 | Qualys reporta la vulnerabilidad; Linus Torvalds aplica la reparación (31e62c2ebbfd) |
| 2026-05-14 | Brad Spengler (@spendergrsec) publica el análisis |
| 2026-05-14 | _SiCk publica PoCs en GitHub |
| 2026-05-15 | Qualys envía la divulgación a oss-security |
La brecha entre la propuesta de parche de Jann Horn en 2020 y el reporte de Qualys en 2026 es notable. La reparación había sido redactada hace cinco años pero nunca llegó a fusionarse.
La Reparación
Linus aplicó la reparación como el commit 31e62c2ebbfd. Su mensaje de commit señaló:
“tenemos un caso especial extraño: ptrace_may_access() usa ‘dumpable’ para verificar varias cosas completamente independientes de MM (típicamente usando banderas como
PTRACE_MODE_READ_FSCREDS), incluyendo hilos que ya no tienen VM (y quizás nunca la tuvieron, como la mayoría de los hilos del kernel). No es para lo que esta bandera fue diseñada, pero es lo que es.”
El parche ajusta el comportamiento de ptrace para manejar correctamente el caso mm == NULL. Cierra efectivamente la ventana de omisión.
Verifica tu Kernel
uname -r
# Los kernels reparados incluyen el commit 31e62c2ebbfd
# Todos los kernels anteriores al 2026-05-14 son vulnerables
Qué Hace Esto Interesante
Tres cosas destacan:
-
Se reparó el mismo día que se reportó. Linos lo resolvió en horas. Es inusualmente rápido para una reparación del kernel, sugiriendo que el parche era directo una vez entendido el error.
-
Jann Horn lo encontró en 2020. La comunidad tenía una propuesta de parche en los archivos de la lista de correo por cinco años. El patrón de robo de FD era conocido, pero nadie lo impulsó.
-
Los objetivos son antiguos. El patrón de fds abiertos de
ssh-keysigndata de 2002. La secuenciaspw_open+setreuiddechagees igualmente longeva. Esto no es un error en SSH o shadow-utils — es un error del kernel que weaponiza patrones existentes de manejo de fds en binarios privilegiados.
Esta es también la tercera vulnerabilidad importante del kernel de Linux en mayo de 2026, después de Copy Fail y Dirty Frag. El ritmo de divulgación se acelera — en parte porque las herramientas de auditoría asistidas por IA encuentran errores antiguos más rápido, y en parte porque el ecosistema de divulgación se está fragmentando.
Referencias
- Commit de reparación: 31e62c2ebbfd
- Phoronix: Vulnerabilidad de Linux permite leer archivos de root
- PoC en GitHub: 0xdeadbeefnetwork/ssh-keysign-pwn
- 9to5Linux: Fallo de seis años permite leer archivos de root
- Qualys oss-security: Error lógico en __ptrace_may_access()
- Parche de Jann Horn 2020: lore.kernel.org