Noticias

*sshole: una contraseña demasiado larga abre cuentas sin contraseña en Alpine y otros Linux con musl

4 min de lectura

Cómo una contraseña de más de 256 bytes termina en el mismo asterisco que marca una cuenta sin contraseña, y cómo lo cierra OpenSSH 10.6p2. Esquema: decodigo.com.

Un asterisco bastó para abrir servidores. El fallo CVE-2026-123158, que su descubridor bautizó como «*sshole», permite entrar por SSH a cuentas que no tienen contraseña en Alpine Linux y otros sistemas que usan la biblioteca musl: el atacante solo tiene que mandar una contraseña de más de 256 bytes. OpenSSH lo corrigió en la versión 10.6p2 y Alpine publicó paquetes parchados el 5 de noviembre para todas sus ramas desde la 3.16.

El investigador Özgün Kültekin, de la firma Wakefield, encontró que el fallo no está en una sola pieza, sino en la suma de tres decisiones razonables tomadas por separado. En Unix, una cuenta cuyo campo de contraseña dice solo «*» es una cuenta en la que ninguna contraseña puede coincidir: así se crean los usuarios que solo entran con clave SSH, y así viene root en Alpine desde hace años. En 2012, musl decidió que su función crypt(), la que cifra contraseñas, devolviera un «*» en lugar de un error cuando algo sale mal, y le puso un límite de 256 bytes a la contraseña para evitar ataques de denegación de servicio. Y en 2016, OpenSSH empezó a cifrar las contraseñas de las cuentas sin hash con una «sal» prestada de otra cuenta, para que un atacante no pudiera adivinar por el tiempo de respuesta qué usuarios existen.

Juntas, esas tres piezas producen el fallo: el sistema guarda «*» para la cuenta, la contraseña larga hace que crypt() falle y devuelva «*», y sshd compara uno con otro, los ve iguales y deja pasar. Los equipos con glibc, la biblioteca de Debian, Ubuntu y Fedora, no tienen el problema, y tampoco los que validan contraseñas con PAM.

Cómo un asterisco abre la puerta Inicio de sesión en un Alpine sin parchar LO QUE GUARDA EL SISTEMA La cuenta root no tiene contraseña: su campo dice solo un asterisco. root:* LO QUE MANDA EL ATACANTE Una contraseña de 257 a 1024 bytes, por ejemplo, 300 letras A. AAAAAAAA…AAAA LO QUE HACE SSHD La cifra con crypt() y una sal prestada de otra cuenta que sí tiene contraseña. crypt(AAAA…, $6$sal) LO QUE RESPONDE MUSL Pasa de 256 bytes: crypt() falla y, en vez de un error, devuelve un asterisco. * LA COMPARACIÓN * = * son iguales: sshd deja entrar El asterisco que significaba ninguna contraseña coincide ahora con cualquier contraseña larga. Con glibc, crypt() no da ese asterisco y la comparación falla. OpenSSH 10.6p2 agrega en sshd una protección que evita la coincidencia. Esquema simplificado. Datos: Alpine Linux, OpenSSH y Özgün Kültekin (Wakefield). Gráfica: decodigo.com.
La cuenta sin contraseña y la contraseña demasiado larga terminan en el mismo asterisco. Gráfica: decodigo.com con datos de Alpine Linux, OpenSSH y Özgün Kültekin.

Claves de *sshole

  • Qué hace falta. Un Linux con musl, como Alpine, OpenWrt, Buildroot o Yocto, y muchas imágenes de Docker basadas en ellos; un sshd sin parche y sin PAM, como el paquete openssh-server de Alpine; la entrada con contraseña permitida; una cuenta con «*» que SSH acepte; y otra cuenta con contraseña real que aporte la sal.
  • La contraseña mágica. Cualquiera de 257 a 1024 bytes, según el aviso de Alpine. No hay que adivinar nada: basta con que sea larga.
  • Qué cuentas corren peligro. Los usuarios que solo entran con clave y se crearon sin contraseña, los usuarios de servicios de directorio como sssd o winbind, y el usuario alpine de las imágenes tiny-cloud de la 3.18.11 a la 3.24.3, que además puede usar doas sin contraseña. Root está protegido por la configuración de fábrica, PermitRootLogin prohibit-password, salvo que alguien la haya cambiado.
  • Gravedad. 8.1 sobre 10 en la escala CVSS. El número de CVE se asignó después de que Alpine y OpenSSH publicaran sus avisos, por eso esos textos no lo mencionan.
  • ¿Ya hay ataques? Según Help Net Security, la empresa Previdian registró el primer intento a menos de nueve horas de la publicación y vio a un atacante obtener root en un equipo trampa con Alpine: ocho intentos desde una sola dirección en Japón. Otras fuentes no reportaban ataques confirmados al 6 de noviembre, pero el código de prueba ya es público.
  • Quién lo corrigió. Damien Miller y Darren Tucker, de OpenSSH, con el análisis de Timo Teräs. OpenSSH considera que la causa está fuera de sshd, pero que ahí se puede evitar, y por eso lo corrigió en su código.
¿Está expuesto tu servidor? Hace falta que se cumpla todo esto a la vez Linux con musl Alpine, OpenWrt, Buildroot, Yocto sshd sin PAM y sin parche como el openssh-server de Alpine PasswordAuthentication yes entrar con contraseña permitido Una cuenta con asterisco sin contraseña y que SSH acepte Otra cuenta con contraseña que preste su sal $5$ o $6$ NO ESTÁN AFECTADOS Debian, Ubuntu, Fedora y demás con glibc Alpine con openssh-server-pam y UsePAM yes PasswordAuthentication no (cloud-init lo pone) Cuentas bloqueadas con !, no con * root con PermitRootLogin prohibit-password Dropbear y OpenBSD Datos: aviso de Alpine Linux y notas de OpenSSH 10.6p2. Gráfica: decodigo.com.
Las condiciones que deben cumplirse a la vez y lo que no está afectado. Gráfica: decodigo.com con datos de Alpine Linux y OpenSSH.

Qué hacer si administras un Alpine

Lo primero es actualizar con apk upgrade -U -a y reiniciar sshd, porque el programa que ya está corriendo sigue siendo el viejo hasta que se reinicia. Alpine aplica la corrección sin cambiar la versión de OpenSSH en algunas ramas, así que conviene revisar el paquete con apk info -v openssh-server en lugar de fiarse de sshd -V. Si no se puede actualizar de inmediato, desactivar la entrada con contraseña (PasswordAuthentication no) cierra la puerta, siempre que antes se compruebe que el acceso con clave funciona. Y como el fallo se pudo usar sin dejar más rastro que un inicio de sesión normal, Alpine recomienda buscar líneas «Accepted password for» de cuentas que no tienen contraseña en /var/log/messages, revisar usuarios y claves nuevas, y tratar como comprometido cualquier equipo en el que no se pueda descartar un acceso.

El caso es un buen ejemplo de por qué las convenciones viejas son peligrosas. Un asterisco que desde los primeros Unix quiere decir «aquí no entra nadie» acabó significando lo mismo que un error, y ningún componente estaba mal por sí solo. Lo que falló fue el supuesto de que una función que cifra contraseñas nunca devolvería exactamente lo que el sistema guarda para decir que no hay contraseña.

Fuente: Alpine Linux; notas de OpenSSH 10.6p2; sshhole.com (Özgün Kültekin); Help Net Security; StepSecurity. Imagen de portada: OpenSSH.