Zaledwie kilka dni temu światem bezpieczeństwa Linuksa wstrząsnęła informacja o nowej podatności w OpenSSH. Luka, odkryta przez Özgüna Kültekina i ochrzczona wymowną nazwą *sshole (CVE-2026-123158), pozwala napastnikom na logowanie się do kont, które z założenia miały całkowicie zablokowaną autoryzację opartą na haśle. Do przejęcia serwera z uprawnieniami root wystarczy podanie dowolnego ciągu znaków dłuższego niż 256 bajtów.

Choć błąd znajduje się w kodzie OpenSSH od 2016 roku, jego wektor ataku uaktywnia się tylko w bardzo specyficznym, ale popularnym w świecie kontenerów i IoT ekosystemie: na lekkich dystrybucjach wykorzystujących bibliotekę musl libc, takich jak Alpine Linux czy OpenWrt.
Anatomia podatności: Śmiertelne zderzenie dwóch mechanizmów
Zrozumienie działania luki *sshole wymaga spojrzenia na to, jak systemy linuksowe przechowują poświadczenia i w jaki sposób OpenSSH chroni przed tzw. wyliczaniem użytkowników (username enumeration).
W pliku /etc/shadow hasła przechowywane są w formie skrótów (hashów). Jeśli konto ma wyłączone logowanie hasłem (np. użytkownicy logujący się tylko kluczem SSH, konta usługowe lub domyślnie zablokowany root w Alpine), w miejscu hasha widnieje pojedynczy znak gwiazdki (*).
W 2016 roku deweloperzy OpenSSH wprowadzili mechanizm zapobiegający atakom timingowym. Aby atakujący nie mógł odgadnąć, czy dany użytkownik istnieje na podstawie analizy czasu odpowiedzi serwera, OpenSSH wykonuje pełną operację hashowania nawet dla kont, które nie mają ustawionego hasła. Pobiera do tego parametry konfiguracyjne z innego, istniejącego w systemie konta z ważnym hasłem.
W tym miejscu na scenę wkracza biblioteka musl libc, która posiada wbudowany limit długości weryfikowanego poświadczenia. Jeśli do funkcji crypt() przekażemy hasło dłuższe niż 256 bajtów, biblioteka zgłosi błąd i zwróci w odpowiedzi… dokładnie ten sam znak gwiazdki (*).
Przebieg ataku wygląda następująco:
- Atakujący próbuje zalogować się na konto z zablokowanym hasłem (które w
/etc/shadowma wpisane*) i podaje hasło składające się z ponad 256 znaków - Funkcja
crypt()z bibliotekimuslodrzuca zbyt długie hasło i zwraca znak* - OpenSSH porównuje zwrócony wynik (
*) z hashem zapisanym w pliku shadow (również*) - Ciągi naturalnie się zgadzają, więc serwer wpuszcza atakującego, nierzadko dając mu natychmiastowy dostęp do powłoki roota
Kto jest narażony (i dlaczego Debian śpi spokojnie)?
Zagrożenie jest krytyczne, ale na szczęście ograniczone specyfiką środowiska. Serwer jest podatny tylko wtedy, gdy spełnia wszystkie poniższe warunki:
- Działa na dystrybucji używającej
musl libc(np. Alpine Linux, OpenWrt, Buildroot, Yocto) - Serwer SSH nie używa modułów PAM (co jest domyślną konfiguracją m.in. dla pakietu
openssh-serverw Alpine) - Logowanie hasłem jest globalnie włączone (
PasswordAuthentication yes) - Przynajmniej jedno konto (np. root) ma hasło ustawione na
*, a jednocześnie w systemie istnieje przynajmniej jedno inne konto z normalnym hasłem
Dystrybucje oparte na standardowej bibliotece glibc (Debian, Ubuntu, RHEL, Fedora) są w 100% odporne na ten wektor ataku. Podobnie bezpieczne są systemy z wymuszoną autoryzacją PAM lub poprawnie wyłączonym logowaniem hasłem.
Jak zabezpieczyć infrastrukturę?
Autor odkrycia udostępnił w repozytorium oz9un/sshole na GitHubie dokumentację, Proof of Concept oraz specjalny skrypt check.sh, który pozwala szybko zweryfikować, czy infrastruktura jest podatna na atak.
Kroki naprawcze dla administratorów:
- Natychmiastowa aktualizacja: Zarówno projekt OpenSSH (od wersji 10.6p2), jak i twórcy Alpine Linux wydali już stosowne łatki. W Alpine proces ten sprowadza się do wykonania
apk upgrade -U -a. - Restart demona sshd: Sama aktualizacja pakietu nie rozwiązuje problemu dla trwających procesów. Należy bezwzględnie zrestartować działającą w pamięci usługę (
rc-service sshd restartna Alpine). - Zablokowanie haseł (Workaround): Jeśli środowisko nie pozwala na natychmiastową aktualizację, jedynym pewnym ratunkiem jest ustawienie
PasswordAuthentication now konfiguracji serwera SSH, o ile aplikacje nie wymagają haseł. - Przebudowa obrazów kontenerów: Podatne, bazujące na Alpine obrazy kontenerów chmurowych z zainstalowanym serwerem SSH muszą zostać zbudowane i wdrożone na nowo, ponieważ uruchomiony kontener zachowuje binarki z momentu startu.
- Audyt logów: Należy przejrzeć logi systemowe pod kątem linii zawierających „Accepted password” dla kont, które nie powinny mieć hasła. Obecność takich wpisów oznacza, że maszyna została już skompromitowana.
Luka *sshole to fascynujący i jednocześnie przerażający przykład tego, jak nałożenie się na siebie dwóch całkowicie oddzielnych, z pozoru bezpiecznych zachowań (ograniczenie długości na poziomie biblioteki C i ochrona przed enumeracją w OpenSSH) może po wielu latach połączyć się w krytyczną podatność.