Przejdź do treści

OpenSSH na Alpine: konto bez hasła przyjmuje każde długie hasło. Poprawka wymaga jednego kroku więcej

Okładka newsa o luce OpenSSH na Alpine: nagłówek gwiazdka otwiera drzwi SSH, karty z zakresem hasła 257-1024 bajtów i wersjami Alpine 3.16-3.24, pieczątka krytyczna luka

Dwa wydania z 5 listopada 2026 domykają lukę, która czekała na odkrycie od 2022 roku, a jej korzenie sięgają 2012. OpenSSH wydało wersję 10.6p2 z obejściem krytycznego bypassu uwierzytelniania hasłem, a równolegle Alpine opublikowało ostrzeżenie dla wydań 3.16 do 3.24 i edge. Na systemach z OpenSSH zbudowanym z biblioteką musl i bez PAM konto, które formalnie nie może przyjąć żadnego hasła, przyjmuje każde hasło liczące od 257 do 1024 bajtów, za jednym połączeniem, bez ponawiania prób. Dotyczy to obrazów kontenerów Alpine, systemów budowanych na buildroot albo yocto i części VPS-ów; Debian, Ubuntu i Fedora są czyste, podobnie jak wszystko, co przechodzi przez PAM, oraz OpenWrt z domyślnym Dropbear. Najciekawszy jest jednak sam zgłaszający: Özgün Kültekin z firmy Wakefield przetestował wszystkie konfiguracje sshd naraz, rzucając ok. 17,6 tys. dziwnych logowań na swarmy agentów AI, a OpenSSH w notkach wydania pisze wprost, że kończy z długimi embargami, bo agenty AI odkrywają te same luki czasem w kilka godzin.

Najważniejsze informacje

CoSzczegóły
WydaniaOpenSSH 10.6p2 i ostrzeżenie Alpine, oba 5.11.2026; zgłoszenie wpłynęło do OpenSSH dzień wcześniej (post Damiena Millera)
ZasięgAlpine 3.16-3.24 i edge, także wydania poza wsparciem; ogólniej: OpenSSH zbudowane z musl i bez PAM (obrazy kontenerów, buildroot, yocto)
Warunek atakuPasswordAuthentication yes (domyślne), konto z polem hasła * w /etc/shadow, przynajmniej jedno konto z hashem $5$ albo $6$, dostęp sieciowy do portu SSH
EfektHasło 257-1024 bajtów loguje konto bez hasła za pierwszym razem, jednym połączeniem
NiepodatneDebian/Ubuntu/Fedora (glibc), systemy z PAM, Dropbear, OpenBSD, kontenery bez sshd, konta zablokowane !
Naprawaapk upgrade + rc-service sshd restart (aktualizacja nie restartuje demona); tymczasowo PasswordAuthentication no
CVEBrak identyfikatora w chwili publikacji (odczyt 5.11.2026)
ZgłoszenieÖzgün Kültekin, Wakefield; testy ok. 17,6 tys. logowań przeprowadzone przez agentów AI

Gwiazdka, która liczyła się jak brak hasła

Mechanizm zaskakuje, kiedy złoży się go w całość, bo każdy element pojawiał się osobno przez dekadę. Znak * w polu hasła to konwencja sprzed 46 lat: w 1980 Bill Joy oznaczył tak w 3BSD konto daemon, do którego nikt nie powinien się logować, a w rubryce z imieniem i nazwiskiem wpisał mu „the devil himself”. Gwiazdka nie jest haszem, więc żadne hasło nie może jej wyprodukować i logowanie hasłem odpada. W sierpniu 2012 twórcy musl zmienili jednak kontrakt funkcji crypt(). Specyfikacja Unix każe zwracać przy błędzie NULL, ale mnóstwo programów NULL-a nie sprawdza, porównuje wynik z polem hasła i wali się. W commicie b3c4cc12 musl postanowił, że zamiast NULL-a crypt() odda gwiazdkę: żadne prawdziwe hasło jej nie wyprodukuje, więc programy przestaną się sypiać, a logowanie i tak odmówi.

Trzy tygodnie później wszedł drugi commit, 88bf5a8a z 29 sierpnia 2012, z praktycznego powodu: sha512crypt robi się wyraźnie wolniejszy, im dłuższe hasło podać, więc jeden gigantyczny ciąg potrafi zająć serwer na długo. musl odmawia liczenia powyżej 256 bajtów klucza. A że ta droga kończy się błędem, funkcja zwraca dokładnie to, na co ją przeprogramowano: gwiazdkę. Ta kombinacja spała w kodzie do 2022 roku bez żadnych skutków.

Trzeci element leży po stronie sshd. W 2016 roku CVE-2016-6210 pozwalało rozpoznawać istniejące konta po czasie odpowiedzi, bo konto z prawdziwym haszem liczy crypt() kilka milisekund dłużej. Poprawka OpenSSH działała tak: dla użytkownika bez realnego hasza pożycz sól innego konta i policz hash tak samo, żeby odmowa zawsze trwała tyle samo. Od tego momentu sshd liczy crypt() także dla kont ze gwiazdką. W 2019 CVE-2019-5021 wyłapało obrazy Alpine z rootem bez żadnego hasła; Alpine zablokowało konto znakiem !, ale bez PAM taka blokada odcięła też logowanie kluczem, a obrazy chmurowe bez kluczy nie wstają. Od wydania 3.16 root dostaje więc gwiazdkę: hasła dalej nie ma, klucze działają. I nikt nie połączył, że ten znak to dokładnie to, czym musl oznacza błąd crypt(). Hasło 257-1024 bajtów przechodzi ścieżkę błędu, crypt() zwraca *, porównanie z polem * zgadza się i sshd loguje atakującego. Zespół OpenSSH podkreśla w notkach, że przyczyna leży poza sshd, ale podatność ujawnia się przez sshd i tam ją załatano.

Pięć warunków, które muszą się złożyć naraz

Z ostrzeżenia Alpine wynika, że punkty poniżej muszą być spełnione jednocześnie. Serwer musi mieć openssh-server zbudowany bez PAM, ewentualnie pakiet openssh-server-pam z ustawieniem UsePAM no; domyślny openssh-server w Alpine PAM-a nie używa. Logowanie hasłem musi być włączone, a jest domyślnie. W systemie musi istnieć konto z polem hasła *: root w obrazach bazowych od 3.16, konta założone adduser bez hasła, użytkownicy tworzeni przez musl-nscd albo użytkownik alpine w obrazach tiny-cloud. Potrzebny jest przynajmniej jeden hash $5$ albo $6$, bo sshd pożycza sól właśnie z takiego konta. Do tego atakujący musi mieć dostęp sieciowy do portu.

Lista niepodatnych jest długa i uspokajająca. Wszystko na glibc (Debian, Ubuntu, Fedora), bo tam crypt() zwraca NULL. Wszystko, co przechodzi przez PAM. Dropbear, czyli domyślny ser SSH OpenWrt. OpenBSD i każdy system spoza Linuksa. Kontenery, w których sshd w ogóle nie działa. Konta zablokowane !, obrazy cloud-init z wyłączonymi hasłami i systemy bez żadnego hasza w formacie $-style, gdzie nie ma skąd pożyczyć soli. Na obrazach AWS i Azure stawka rośnie sama: domyślny użytkownik alpine ma tam pole * i doas bez hasła, więc zdobycie tego konta oznacza w praktyce roota.

Agenty znalazły lukę i przyspieszają poprawki

Opis znaleziska na stronie sshhole.com zawiera zdanie, które trzy lata temu brzmiałoby jak żart. Autor budował sshd w każdej konfiguracji, jaką wymyślił, glibc i musl, z PAM i bez, z shadow i bez, i rzucał w nie ok. 17,6 tys. dziwnych logowań, od psutych hashów po hasła za długie. „Oh did I say 'i’? Sorry. I had agent swarms. A lot of them”, czyli testy robiły swarmy agentów AI, i to spore. Każda konfiguracja zgadzała się co do każdego logowania, oprócz jednej: musl bez PAM odpowiadał „tak” tam, gdzie wszystkie mówiły „nie”.

Notki wydania pokazują szersze tło. Zespół OpenSSH pisze, że napływ zgłoszeń bezpieczeństwa zawiera teraz masę wyników z modeli AI albo powstałych z pomocą AI; część nie ma znaczenia w realistycznym modelu zagrożeń, ale takie zgłoszenia powitali zwłaszcza w połączeniu z ludzką triage, analizą, testami i propozycją poprawki. Dalej stoi zdanie z konsekwencjami: widzieliśmy przypadki, gdy błąd wskazany przez narzędzie AI zostawał niezależnie odkryty przez innego badacza, a to oznacza, że przeciwnicy, którzy nic nie zgłaszają, podążą tą samą drogą. Dlatego OpenSSH zapowiada częstsze wydania zamiast zbierania poprawek na jedną dużą aktualizację.

Miller poszedł krok dalej w poście na Mastodonie: poprawka wychodzi tak szybko, bo o problemie dowiedzieli się dzień wcześniej, a długie embarga uznali za niebezpieczną praktykę, która służy głównie atakującym, bo agenty AI ponownie odkrywają te same luki czasem w kilka godzin. To nie jest pierwszy moment, gdy narzędzia AI pojawiają się w tym samym akapicie co włamanie: w analizie kampanii php2shell znalazły się ślady pracy CLI-asystentów AI, a o bezpieczeństwie samych agentów pisaliśmy osobno. Na poziomie praktyki zostaje jedno: okno między odkryciem luki a jej wykorzystaniem się kurczy, a odkładana aktualizacja serwera kosztuje dziś więcej niż rok temu.

Naprawa: aktualizacja plus restart

Z ostrzeżenia Alpine:

apk upgrade -U -a
rc-service sshd restart

Restart to ten drugi, łatwy do pominięcia krok. Aktualizacja pakietu nie restartuje działającego demona, więc po samym apk upgrade w pamięci siedzi stary sshd i dalej przyjmuje połączenia. Ostrzeżenie podkreśla to wprost i poleca restart jako obowiązkowy.

Jeśli aktualizacja musi poczekać, wyłącza się logowanie hasłem:

echo "PasswordAuthentication no" > /etc/ssh/sshd_config.d/00-no-passwords.conf
sshd -t && rc-service sshd restart
sshd -T | grep -i passwordauthentication

Ścieżka z advisory: wpis do pliku w katalogu sshd_config.d, test składni sshd -t, restart i weryfikacja przez sshd -T, bo to pokazuje efektywną konfigurację, a nie tę spisaną w plikach. Miller formułuje to krócej: jeśli operujesz systemem z musl bez PAM, natychmiast ustaw PasswordAuthentication=no. Logowanie samymi kluczami to i tak dobra praktyka niezależnie od tej luki; w dyskusji pod wątkiem pada też wariant AuthenticationMethods publickey, który jednym ustawieniem blokuje wszystko poza kluczem.

Jeśli ktoś wszedł wcześniej

Ostrzeżenie podaje listę śladów. W /var/log/messages szuka się linii „Accepted password” dotyczących kont, które hasła nie powinny mieć; to dokładny zapis opisanej wyżej dziury, tylko w wykonaniu kogoś innego. Do tego przegląd użycia doas i weryfikacja, czy w systemie nie przybyło nowych kont albo kluczy. Zalecenie ostatnie brzmi twardo: jeśli nie da się wykluczyć, że ktoś wszedł tą drogą, maszynę traktuje się jako skompromitowaną.

Jak to wygląda po polsku

Alpine siedzi pod spodem obrazów kontenerów, które buduje się codziennie, więc pytanie „czy mnie to dotyczy” pojawi się u nas szybko. W samych kontenerach sshd zwykle nie działa, co ogranicza praktyczny promień luki do maszyn z Alpine jako systemem operacyjnym, VPS-ów na takim obrazie i urządzeń budowanych na buildroot albo yocto. Poprawki są już w repozytoriach Alpine dla wydań od 3.16 do 3.24 i edge, więc nie trzeba czekać na przyznanie CVE. W moich odczytach z 5 listopada Google News po frazach z advisory nie zwraca żadnego artykułu, a polski autocomplet zna rodzinę „openssh alpine” tylko w pytaniach instalacyjnych, typu „install openssh alpine” albo „alpine openssh docker”; frazy bezpieczeństwa odmawiają podpowiedzi. Ten tekst opisuje stan z 5 listopada 2026.

Najczęstsze pytania

Czy luka dotyczy Debiana i Ubuntu?

Nie. Debian, Ubuntu i Fedora używają glibc, a crypt() w glibc zwraca przy błędzie NULL, nie gwiazdkę, więc porównanie nie przechodzi. Systemy, które do logowania używają PAM, też są niepodatne. Podatna jest kombinacja OpenSSH z musl bez PAM, w praktyce Alpine 3.16-3.24 i edge oraz systemy zbudowane na buildroot albo yocto.

Czy dotyczy to OpenWrt?

Domyślny ser SSH OpenWrt to Dropbear i on jest niepodatny; potwierdzają to też dyskusje po wydaniu poprawki. Jeśli na OpenWrt doinstalowano pakiet openssh zbudowany z musl i uruchomiony bez PAM, warunki podatności mogą się złożyć.

Czy wystarczy wykonać apk upgrade?

Nie. Aktualizacja nie restartuje działającego demona, więc stary sshd pozostaje w pamięci i nadal przyjmuje połączenia. Po aktualizacji trzeba uruchomić rc-service sshd restart, a przy zmianie konfiguracji dodatkowo test sshd -t i weryfikację sshd -T.

Czy luka ma numer CVE?

Na 5 listopada 2026 nie. Szczegóły leżą w notkach wydania OpenSSH 10.6p2 i w ostrzeżeniu Alpine. Od zgłoszenia do wydań obu stron minął jeden dzień, co jest częścią tej historii: zespół OpenSSH celowo zerwał z dłuższymi oknami embarga.

Źródła

Powiązane artykuły