← Blog

CVE-2026-46333 «ssh-keysign-pwn»: la grieta del kernel Linux que llevaba seis años escondida

Una vulnerabilidad del kernel Linux publicada el 15 de mayo permite a un usuario local robar claves SSH privadas y el /etc/shadow sin necesidad de escalar a root. Te contamos qué es, a quién afecta y qué tienes que hacer hoy mismo en tus servidores.

La llamada del viernes

El viernes pasado, varios clientes nos escribieron con la misma frase: «He visto algo de una CVE crítica del kernel, ¿estamos afectados?». La respuesta corta fue sí, casi todos los servidores Linux del mundo lo están. La buena noticia: el parche está disponible y se aplica en minutos. La mala: hasta que se aplica, un usuario local sin privilegios puede leerse las claves SSH del root y el /etc/shadow sin necesidad de exploit complicado.

Esta es la historia de CVE-2026-46333, bautizada como «ssh-keysign-pwn» por los investigadores que la publicaron. Y de por qué un fallo que entró en el kernel en 2017 ha estado seis años a tiro de cualquiera sin que nadie levantara la mano.

En una frase

Hay una condición de carrera en la ruta de salida (do_exit) del kernel Linux. Durante una ventana muy estrecha mientras un proceso se está cerrando, las comprobaciones de ptrace se relajan más de la cuenta. Un usuario local puede aprovechar ese instante con pidfd_getfd(2) para copiar descriptores de fichero abiertos de un proceso privilegiado — por ejemplo ssh-keysign (que abre claves SSH privadas) o chage (que abre /etc/shadow).

Sin ser root. Sin permisos especiales. Con un binario que ya estaba ahí.

A quién afecta

  • Distribuciones afectadas: Ubuntu, Debian, Arch Linux, CentOS, AlmaLinux, RHEL, CloudLinux, Raspberry Pi OS. Es decir, prácticamente toda la base instalada de servidores.
  • Versiones de kernel: la condición de carrera se introdujo en Linux v4.10-rc1 (enero de 2017, commit bfedb589). Todos los kernels posteriores tienen la grieta. Cualquier servidor con kernel 4.10 o más nuevo está potencialmente expuesto.
  • Quién la puede explotar: cualquier usuario local. No vale para atacar desde fuera por sí sola, pero cualquier escenario con usuarios SSH no privilegiados, hosting compartido, contenedores con privilegios mal acotados o procesos automáticos con cuenta propia entra en el perímetro de riesgo.

El detalle que la hace especialmente desagradable: hay prueba de concepto pública en GitHub desde el mismo día del disclosure. No es teórica.

Por qué seis años sin detectarse

La pregunta razonable: si la introdujeron en 2017, ¿cómo es que ha tardado tanto en aparecer? Tres razones combinadas:

  1. La ventana de carrera es muy estrecha: hay que coincidir con el do_exit de un proceso privilegiado. El PoC publicado necesita entre 100 y 2000 intentos para tener éxito.
  2. La vía de explotación moderna depende de pidfd_getfd(2), que se añadió al kernel en 2020. Antes de esa fecha, la condición de carrera estaba ahí pero no había una primitiva pública cómoda para aprovecharla.
  3. Los binarios con SUID que dan acceso a secretos críticos (ssh-keysign, chage) son pocos y específicos. Hay que conocer el conjunto exacto para saber qué pedir.

Es decir: el fallo lleva ahí desde 2017, pero solo se ha vuelto realmente explotable desde 2020 y nadie había juntado las piezas hasta este mes. Una buena lección sobre por qué auditar el kernel es duro hasta para los buenos.

Versiones parcheadas por distribución

La tabla siguiente la hemos comprobado contra los avisos oficiales de cada distro. Los números pueden subir conforme salgan revisiones menores, pero estos son los hitos mínimos a partir de los cuales el fallo está cerrado:

DistribuciónKernel parcheado
Ubuntu 24.04 LTS6.8.0-58.61 o superior
Ubuntu 22.04 LTS5.15.0-138.149 o superior
Debian 13 (trixie)6.12.27-2 o superior
Debian 12 (bookworm)6.1.140-1 o superior
RHEL 9 / AlmaLinux 9kernel-5.14.0-611.54.6.el9_7
RHEL 8 / AlmaLinux 8kernel-4.18.0-553.124.4.el8
CloudLinux 10kernel-6.12.0-124.56.5.el10_1
CloudLinux 9kernel-5.14.0-611.54.6.el9_7
CloudLinux 8kernel-4.18.0-553.124.4.lve.el8

Si tu servidor no aparece en esta tabla, comprueba la versión del kernel con uname -r y consulta el aviso de seguridad de tu distribución. No te fíes del número de versión "oficial" sin verificar la fecha del paquete: algunas distros mantienen la versión y solo backportean el fix.

Qué tienes que hacer hoy

Sin rodeos. Lo que aplicamos nosotros estos días en las máquinas de clientes:

1. Actualizar el kernel y reiniciar

Es la única solución definitiva. Y sí, requiere reinicio (o kpatch/kexec si tienes contratado live-patching).

# Debian / Ubuntu
sudo apt update && sudo apt install --only-upgrade linux-image-generic
sudo reboot

# RHEL / AlmaLinux / Rocky / CloudLinux
sudo dnf update kernel
sudo reboot

Antes de reiniciar, asegúrate de que el grub apunta al kernel nuevo (grubby --default-kernel en familia RHEL, dpkg --list | grep linux-image en Debian/Ubuntu). Reiniciar a la antigua versión por error es muy fácil cuando se trabaja a las tres de la madrugada.

2. Mitigación temporal mientras no puedes reiniciar

Si el servidor no admite parada inmediata (caja en producción con cliente final, ventana de mantenimiento cerrada), hay dos paliativos:

Bloquear el ptrace de usuario vía sysctl. No requiere reinicio:

sudo sysctl -w kernel.user_ptrace=0

Para hacerlo persistente entre reinicios:

echo "kernel.user_ptrace=0" | sudo tee /etc/sysctl.d/99-cve-2026-46333.conf

Quitar el SUID a los binarios sensibles, si no los necesitas:

sudo chmod u-s /usr/libexec/openssh/ssh-keysign
sudo chmod u-s /usr/bin/chage

Ojo: quitar el SUID a ssh-keysign rompe la autenticación host-based de OpenSSH si la usas. Comprueba primero con lsattr y con tu configuración de SSH si depende de ella.

Estas mitigaciones cierran el vector que el PoC público explota. No te libran de actualizar.

3. Auditar accesos previos

Hay que asumir que cualquier servidor con usuarios locales no confiables puede haber sido tocado entre el día del disclosure y el día del parche. Revisa:

  • /var/log/auth.log (Debian/Ubuntu) o /var/log/secure (RHEL): logins SSH inusuales.
  • journalctl _COMM=ssh-keysign --since="2026-05-14": ejecuciones de ssh-keysign por usuarios que no deberían lanzarlo.
  • auditd si lo tienes activado: llamadas a ptrace o pidfd_getfd desde procesos no privilegiados.

Si encuentras algo raro, asume compromiso y rota credenciales.

4. Rotar claves SSH si tienes dudas

En servidores compartidos, multi-tenant o con muchos usuarios locales, rota las claves SSH del host después de aplicar el parche:

sudo rm /etc/ssh/ssh_host_*
sudo dpkg-reconfigure openssh-server   # Debian/Ubuntu
sudo systemctl restart sshd

Esto invalida cualquier copia de las claves privadas que pudiera haberse exfiltrado. Los clientes verán un aviso de "host key changed" la primera vez que reconecten — avísales antes.

Lo que hemos hecho nosotros estos días

En Atenea Systems empezamos a desplegar el parche el viernes 16 a primera hora, en cuanto los repositorios de Debian y Ubuntu publicaron los kernels firmados. El orden fue el habitual:

  1. Servidores con usuarios externos primero: hosting compartido, jails de clientes y máquinas con SFTP-only.
  2. Servidores de bases de datos: porque un compromiso ahí escala mal.
  3. VPS dedicados: porque suelen tener un único usuario administrador y la superficie de ataque local es menor.

A día de hoy todos los servidores que gestionamos están en kernel parcheado o, donde la ventana de reinicio aún no ha llegado, con kernel.user_ptrace=0 activo.

La lección que se va llevando uno año tras año

Cada doce meses sale una de estas y todos repetimos los mismos cinco gestos:

  • Mirar la versión del kernel.
  • Mirar la fecha del último reinicio.
  • Aplicar apt/dnf update.
  • Reiniciar.
  • Verificar.

El plan de actualizaciones no es algo que se hace «cuando hay tiempo». Es lo que separa los servidores que sobreviven a un mal viernes de los que no. Si tu plan actual consiste en «cuando me acuerde», hablamos.

Referencias

¿Hablamos de tu caso?

Cuéntanos qué necesitas y te respondemos en menos de 24 horas con una propuesta clara.

Pedir presupuesto