needhelp
← Volver al blog

ssh-keysign-pwn: Leyendo archivos de root mediante un error lógico en ptrace

por xingwangzhe
Linux
Kernel
Seguridad
Qualys
ptrace
CVE

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 a 31e62c2ebbfd está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étricaValor
Reportado porQualys Security Advisory
Reparado porLinus Torvalds
Commit de reparación31e62c2ebbfd
Oculto por~6 años
Detectado primero porJann Horn (Google), octubre 2020
PoC publicado por_SiCk
ImpactoLeer archivos de root como usuario no privilegiado
Complejidad del exploit100–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:

  1. Un proceso llama a do_exit() para terminar
  2. do_exit() ejecuta exit_mm() primero — elimina el descriptor de memoria (mm)
  3. Luego ejecuta exit_files() — pero los descriptores de archivo siguen vivos
  4. Con task->mm == NULL pero 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

FechaEvento
~2020Jann Horn identifica el patrón de robo de FD y propone un parche (no fusionado)
2026-05-14Qualys reporta la vulnerabilidad; Linus Torvalds aplica la reparación (31e62c2ebbfd)
2026-05-14Brad Spengler (@spendergrsec) publica el análisis
2026-05-14_SiCk publica PoCs en GitHub
2026-05-15Qualys 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:

  1. 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.

  2. 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ó.

  3. Los objetivos son antiguos. El patrón de fds abiertos de ssh-keysign data de 2002. La secuencia spw_open + setreuid de chage es 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

Compartir esta página