Aanvallers kunnen inloggen op accounts zonder wachtwoord, zoals SSH-accounts die alleen met een sleutel werken, op sommige Alpine Linux-servers die het standaard openssh-server-pakket draaien. Ze hebben netwerktoegang tot de server, een accountnaam en een wachtwoord nodig van tussen de 257 en 1.024 bytes lang.
OpenSSH, dat de kwetsbaarheid als kritiek bestempelt, heeft vandaag versie 10.6p2 uitgebracht om dit te blokkeren. Alpine heeft voor alle releases terug tot 3.16 gefixeerde pakketten gepubliceerd.
De aanval werkt wanneer de OpenSSH-server (sshd) wachtwoorden controleert zonder de Pluggable Authentication Module (PAM)-interface, wachtwoordlogins zijn ingeschakeld, en er ten minste één ander account op de machine een wachtwoord heeft. Het openssh-server-pakket van Alpine is zonder PAM gebouwd en wachtwoordlogins staan standaard aan.
De kwetsbaarheid ontstaat door de manier waarop sshd samenwerkt met musl, de C-bibliotheek waarop Alpine is gebouwd. Niet-Linux systemen, Linux-systemen die op glibc zijn gebouwd, en systemen die wachtwoorden via PAM controleren, zijn niet getroffen, zei Damien Miller van het OpenSSH-project.
Hij riep iedereen met een getroffen systeem op om “set PasswordAuthentication=no or disable SSH for these systems IMMEDIATELY.” Tot nu toe zijn er geen aanvallen gemeld die van deze kwetsbaarheid gebruikmaken.
Wie is blootgesteld
Het beveiligingsadvies van Alpine noemt vier voorwaarden. Een server is blootgesteld wanneer alle vier waar zijn:
- Hij draait het
openssh-server-pakket dat zonder PAM is gebouwd, of draaitopenssh-server-pammetUsePAM no. PasswordAuthenticationstaat opyes, wat de OpenSSH-standaard is.- Een account heeft
*in het wachtwoordveld, wat betekent dat er geen wachtwoord is ingesteld. - Ten minste één andere lokale account heeft een wachtwoordhash die begint met
$5$of$6$.
De aanvaller heeft ook de naam nodig van een account zonder wachtwoord. Eén account met een wachtwoord is genoeg om elk account zonder wachtwoord bloot te stellen. Volgens het advies slaagt de aanval bij elke poging met één enkele verbinding.
Op Alpine vallen onder accounts zonder wachtwoord:
- key-only gebruikers die zijn aangemaakt met
adduserzonder wachtwoord, of metusermod -p '*' - gebruikers die via een directorydienst binnenkomen via
musl-nscd, aangezien zij geen shadow-entry hebben root, dat sinds ongeveer Alpine 3.16 in het basisimage is geleverd alsroot:*- de
alpine-gebruiker in de officiële cloud-images die met tiny-cloud zijn gebouwd
Root is afgeschermd door de standaardinstelling PermitRootLogin prohibit-password en is alleen direct bereikbaar als PermitRootLogin yes is ingesteld. Die bescherming helpt echter niet als een blootgesteld account root kan worden, bijvoorbeeld via doas.
De tiny-cloud images van 3.18.11 tot en met 3.24.3 geven de alpine-gebruiker wachtwoordloos doas. Ze zijn bij de eerste keer opstarten veilig, maar worden kwetsbaar zodra er een $6$-hash op de machine staat, bijvoorbeeld nadat een beheerder een console-wachtwoord heeft gezet. Een aanvaller kan dan inloggen als alpine en met doas root worden.
Containers die sshd niet draaien, systemen met PasswordAuthentication no, en cloud-images die via cloud-init zijn opgezet (dat die instelling schrijft) zijn niet getroffen. Accounts die zijn vergrendeld met ! in /etc/shadow zijn ook niet getroffen, en evenmin machines waar geen enkel account een $-stijl wachtwoordhash heeft.
De kwetsbaarheid is niet beperkt tot Alpine. Özgün Kültekin uit Wakefield, die het rapporteerde, noemt in zijn technische uiteenzetting OpenWrt, Buildroot en Yocto als andere musl-gebaseerde systemen om te controleren.
OpenWrt regelt SSH standaard met Dropbear, zoals de Dropbear-documentatie van OpenWrt aangeeft, en Kültekin zegt dat Dropbear niet is getroffen. Op OpenWrt doet de kwetsbaarheid er alleen toe als een beheerder de OpenSSH-server heeft geïnstalleerd.
Hoe te verhelpen
Op Alpine is de fix een pakketupdate gevolgd door een herstart, omdat het upgraden van het pakket de draaiende sshd niet herstart:
- Werk de pakketten bij:
apk upgrade -U -a - Herstart de server:
rc-service sshd restart
Point-releases 3.21.10, 3.22.8, 3.23.8 en 3.24.4 bevatten al het gefixeerde pakket. Branches 3.16 tot 3.21 zijn voorbij hun end-of-support maar kregen ook gefixeerde pakketten.
Cloud-instanties die vanaf tiny-cloud images zijn gestart die ouder zijn dan die point-releases moeten nog steeds de update krijgen, of de hieronder genoemde instelling toepassen.
Als u OpenSSH zelf bouwt, bevat versie 10.6p2 de wijziging, zoals in de release-opmerkingen staat beschreven.
Als u nog niet kunt updaten, stopt het uitschakelen van wachtwoordlogins ook de aanval. Zorg er eerst voor dat uw SSH-sleutel-login werkt en houd uw huidige sessie open totdat een nieuwe login slaagt. Zet daarna PasswordAuthentication no, controleer de configuratie met sshd -t en herstart sshd.
Het advies geeft commando’s die de instelling toevoegen in een drop-in bestand in /etc/ssh/sshd_config.d, dat vanaf 3.19 door de standaardconfiguratie van Alpine wordt gelezen. Ze veranderen ook elke PasswordAuthentication-regel in /etc/ssh/sshd_config van yes naar no, inclusief regels binnen een Match-blok. Daarna zou sshd -T | grep -i passwordauthentication passwordauthentication no moeten tonen.
Het advies raadt aan in /var/log/messages te zoeken naar sshd-regels die beginnen met Accepted password for gevolgd door een account dat geen wachtwoord heeft, zoals alpine, root of een key-only gebruiker. Op blootgestelde machines verdient het aanbeveling ook gebruik van doas, recent aangemaakte gebruikers, bestanden en authorised_keys te controleren.
“Als u een login niet kunt uitsluiten, behandel de machine dan als gecompromitteerd,” zegt het advies.
Waarom lange wachtwoorden werken
Zonder PAM controleert sshd zelf een wachtwoord. Het hasht de poging met crypt(), de C-bibliotheekfunctie die een wachtwoord omzet naar de opgeslagen vorm, en vergelijkt het resultaat met het opgeslagen veld.
Een account zonder wachtwoord heeft alleen * in dat veld. Dat is te kort om een salt te bevatten, het willekeurige voorvoegsel van een hash, dus sshd leent de salt van een ander account dat een echte hash heeft.
Voor de hash-typen $5$ en $6$ weigert musl’s crypt() wachtwoorden langer dan 256 bytes en retourneert * om de fout aan te geven. Dat * komt overeen met het opgeslagen *, waardoor sshd de login accepteert. Het bovenste eind van het bereik is de eigen limiet van sshd van 1.024 bytes per wachtwoord.
Dit gedrag komt door een wijziging in musl op 9 augustus 2012, die ervoor zorgde dat een mislukte crypt()-aanroep “een niet-overeenkomende hash in plaats van NULL” teruggeeft, omdat veel programma’s geen controle op falen deden. De 256-byte limiet volgde op 29 augustus 2012 om servers te beschermen tegen denial-of-service-aanvallen.
Het lenen van de salt komt van een OpenSSH-wijziging op 15 juli 2016 die CVE-2016-6210 aanpakte, een kwetsbaarheid waarmee aanvallers konden achterhalen welke gebruikersnamen bestaan. Kültekin zegt dat het probleem sindsdien bestaat.
De codewijziging in 10.6p2 zorgt ervoor dat sshd een match weigert wanneer het opgeslagen veld korter is dan vier tekens. OpenSSH noemt het een workaround en zegt dat de hoofdoorzaak buiten sshd ligt. Stabiele Alpine-pakketten bevatten een patch voor hetzelfde probleem.
Waarom de fix de volgende dag kwam
Het team van Miller hoorde eerder deze week van de kwetsbaarheid en heeft de fix zo snel mogelijk uitgebracht. In de release-aankondiging zei hij dat het team lange embargo’s nu als gevaarlijk en vooral nuttig voor aanvallers beschouwt, omdat zij recent AI-agents heeft gezien die dezelfde bugs opnieuw vonden, soms binnen uren.
Er was op het moment van publiceren nog geen CVE-nummer toegewezen aan de kwetsbaarheid.
