NFsec Logo

Bunt maszyn

Today w Bezpieczeństwo Brak komentarzy.  (artykuł nr 956, ilość słów: 1765)

Z

aczniemy od podatności CVE-2026-123158, która była w „ukryciu” przez ponad 10 lat. Sprawdzanie haseł w systemach *nix jest w założeniu bardzo proste. Każde konto ma zapisany hasz hasła (najlepiej w wariancie, który zapewnia dobrą ochronę), który jest przechowywany w pliku /etc/shadow. Podczas logowania system haszuje to, co wpisaliśmy, przy użyciu tej samej soli i sprawdza, czy wynik jest zgodny. Konta, które nigdy nie powinny akceptować hasła – takie jak użytkownik do uruchamiania daemonów (nobody, www-data) lub wdrażania kodu – korzystający wyłącznie z kluczy SSH (w tym root) na wielu obrazach chmurowych – otrzymują znak „*” (gwiazdki) zamiast haszu. Ponieważ znak „*” nie jest prawidłowym haszem, żadnego hasło nie może do niego pasować. Ta konwencja sięga czasów systemu Unix BSD z 1980 roku. Autor podatności – Özgün Kültekin – o nazwie sshole szczegółowo wyjaśnia, jak trzy rozsądne decyzje podjęte na przestrzeni lat skumulowały się w taki sposób, że powstała luka bezpieczeństwa.

Wynika z niej, że OpenSSH oparte na bibliotece musl libc (mniejszej, lżejszej bibliotece C używanej przez dystrybucje Alpine, OpenWrt, Yocto i wiele obrazów kontenerów) akceptowało dowolne hasło o długości od 257 do 1024 znaków dla kont zablokowanych znakiem *. W 2012 roku musl zmienił swoją funkcję crypt(), tak aby zwracała znak * zamiast NULL w przypadku niepowodzenia operacji porównywania haszy – zapobiegało to awariom niestarannie napisanych programów. Kilka tygodni później musl wprowadził limit długości dla haszowania haseł SHA-512 na poziomie 256 bajtów (bardzo długie hasła potrafią przeciążyć obliczenia procesora), więc wszystko, co dłuższe, kończyło się błędem. Następnie w 2016 roku, aby naprawić błąd ataków czasowych (ang. timing attack) umożliwiających ustalenie prawidłowych nazw użytkowników poprzez pomiar czasu odpowiedzi serwera (CVE-2016-6210) sshd zaczął haszować hasło przy użyciu soli innego konta, gdy dane konto nie miało prawidłowego haszu – wyłącznie po to, by operacja zajmowała tyle samo czasu, co dla innych kont. Jeśli połączymy to wszystko w całość: zbyt długie hasło powoduje niepowodzenie funkcji crypt() zwracając znak *, który pasuje do znaku zapisanego dla konta mającego blokadę na hasło.

Podatność dotyczy nas, jeśli uruchamiany usługę SSH opartą o bibliotekę musl bez wsparcia modułów PAM (domyślna konfiguracja w Alpine), logowanie hasłem jest włączone (również domyślna), a w systemie istnieje konto zablokowane znakiem * oraz przynajmniej jedno inne konto posiada ustawione prawdziwe hasło, z którego sshd może pożyczyć sól do oszukania enumeracji kont. Powiązania bibliotek oraz ustawionych opcji w serwerze OpenSSH możemy sprawdzić za pomocą poleceń:

ldd $(command -v sshd) | grep -E 'musl|libpam'
sshd -T | grep -iE '^(passwordauthentication|usepam)'

Dystrybucja Alpine „przełączyła” konto root na * w 2022 roku po wcześniejszej poprawce błędu braku hasła na koncie root w oficjalnych obrazach dla kontenerów Docker (CVE-2019-5021). Z kolei na oficjalnych obrazach Alpine dla rozwiązań chmurowych od AWS i Azure domyślny użytkownik alpine jest zablokowany w ten sposób i ma skonfigurowane bezhasłowe uprawnienia doas (lekki i bezpieczny zamiennik tradycyjnego sudo), co w praktyce daje pełny dostęp do konta administratora. Na szczęście systemy używające glibc, PAM, Dropbear czy OpenBSD nie są dotknięte tym błędem. Badacz, który odkrył tę lukę kompilował sshd na każdy możliwy sposób (z glibc, musl, pam, bez pam itd.), jaki przyszedł mu do głowy i uderzał w nią na 17.600 dziwnych sposobów logowania (zepsutymi haszami, kontami, za długimi hasłami) za pomocą „roju agentów AI” (ang. agent swarms). Wszystkie kompilacje dały ten sam wynik z wyjątkiem kombinacji musl bez PAM. Błąd naprawia wersja OpenSSH 10.6p2.

Remote RCE w TCP

Błędy w jądrze Linuksa, które można wywołać zdalnie, bez konieczności logowania, zdarzają się bardzo rzadko. Większość luk w jądrze wymaga, aby atakujący wykonywał swój kod eksploita na lokalnej maszynie. Luka CVE-2026-98432 jest jedną z nich. Opiera się ona na błędzie typu use-after-free, czyli pomyłce w zarządzaniu pamięcią występującej w językach bez automatycznego czyszczenia pamięci (takich jak C czy C++). Dochodzi do niego w momencie, gdy program zwalnia obszar pamięci (np. za pomocą funkcji free()), ale w kodzie nadal pozostaje wskaźnik (tzw. dangling pointer), który odwołuje się do tego zwolnionego adresu i jest później używany do odczytu lub zapisu danych. Jeśli atakujący zdoła umieścić własne dane w tej zwolnionej pamięci, zanim zostanie ona ponownie użyta to może mieć wpływ na dalsze działanie jądra. Wykryto go w kodzie obsługi uścisku dłoni (ang. handshake IPv4 TCP – gdy serwer akceptuje połączenie, którego pakiet SYN zawiera opcje nagłówka IPv4 (rzadko używana funkcja), jądro przekazuje te opcje z połączenia częściowo otwartego do pełnego połączenia bez ich kopiowania, a następnie zwalnia je, podczas gdy inny rdzeń procesora może nadal je odczytać. Poprawka polega na czterowierszowej zmianie z kfree() na kfree_rcu(), co powoduje odczekanie ze zwolnieniem pamięci, aż wszyscy „czytelnicy” zakończą pracę. Przegrany wyścig (ang. race condition) po prostu unieważnia uścisk dłoni, więc atakujący może próbować wielokrotnie. Podatność została oceniona na 9.8 w skali CVSS. Występuje ona w kodzie od wersji 4.4 jądra Linux – bardzo szczegółowo opisała ją firma Atlas.

Błąd zgłosił Xinyang Ge z Anthropic, a firma poinformowała, że jej model Claude napisał działający dowód koncepcji (ang. PoC, Proof-of-Concept), który uzyskuje uprawnienia administratora (root) na serwerach Linux z nasłuchującym gniazdem sieciowym typu Multipath TCP. MPTCP pozwala pojedynczemu połączeniu korzystać z kilku ścieżek sieciowych jednocześnie, np. Wi-Fi i Ethernet. Można by założyć, że raczej mało jest instalacji, która uruchamia tego typu zestawienie na serwerach. Niestety, jak zauważa Marcus Hutchins, jądro dystrybucji Debian (Ubuntu również) domyślnie włącza MPTCP, a programy napisane w języku Go od wersji 1.24 domyślnie otwierają gniazda sieciowe tego typu, jeśli jądro systemu na to zezwala. Oznacza to, że wszystkie usługi sieciowe zbudowane na tym języku są potencjalnie narażone. Skanowanie internetu przeprowadzone przez Hutchinsa wykazało około 2,1 miliona serwerów dostępnych przez MPTCP na porcie HTTPS (443), a on sam obserwuje już skanowanie z serwerów proxy w sieciach domowych i rosyjskich VPN-ów, co wygląda na celowe poszukiwanie tego błędu.

Oficjalne, stabilne jądra (z głównej gałęzi) zostały naprawione w połowie października, ale według stanu na dzisiaj (08.11.2026) RedHat uporał się z luką parę dni temu, a Ubuntu nadal figuruje jako podatne, z poprawkami w trakcie przygotowania. Jeśli nie możemy jeszcze zainstalować łaty, obecność gniazd nasłuchujących typu Multipath możemy sprawdzić poleceniem: ss -Mlnp, a samo MPTCP wyłączyć za pomocą polecenia: sudo sysctl -w net.mptcp.enabled=0 ; trwała zmiana:

echo "net.mptcp.enabled=0" | sudo tee /etc/sysctl.d/99-mptcp.conf
sudo sysctl --system

Musimy pamiętać jednak, że nie wpływa to na gniazda już otwarte, więc musimy zrestartować korzystające z nich usługi. Red Hat i AWS opublikowały również reguły zapory sieciowej (firewalla), które odrzucają pakiety TCP zawierające opcje IPv4, z których legalny ruch praktycznie nie korzysta, np.:

iptables -I INPUT 1 -m u32 --u32 '0>>24&0x0f=6:15' -j DROP

Jak dotąd nie zaobserwowano masowego wykorzystania tej podatności, co może sugerować (podobnie jak w przypadku PHP2SHELL), że wywołanie jest trudniejsze, niż wskazywałaby na to punktacja zagrożenia. Jednak nie możemy z tego powodu pominąć procesu aktualizacji i mitygacji zagrożeń. Sformułowanie „jeszcze masowo niewykorzystana” ma dzisiaj przykrą tendencję do zmieniania się w „każdy podatny serwer przejęty w jeden dzień”.

Podatnopokalipsa

Bardzo wiele znaków w internecie wskazuje, że czeka nas podatnopokalipsa (ang. vulnpocalypse) – a jej nadejście już jest powoli obwieszczane przez różnych jeźdźców podatności. OpenAI opublikowało wyniki badań, w których skierowali na jądro automatyczne narzędzie zbudowane na podstawie niewydanego jeszcze modelu ukierunkowanego na cyberbezpieczeństwo. Podczas przebiegu w połowie października system znalazł 2300 potencjalnych błędów; odtworzył 1700 z nich i stworzył 948 działających lokalnych sploitów podnoszących uprawnienia (ang. local privilege escalation – LPE) na standardowej dystrybucji Linuksa. Lokalna eskalacja uprawnień to krok wykonywany po tym, jak atakujący uzyska już punkt oparcia w systemie: przekształcenie zwykłego konta użytkownika, przejętego serwisu internetowego lub procesu (również odizolowanego w piaskownicy / sandboksie) w pełną kontrolę nad maszyną. W połączeniu z chociażby podstawową podatnością w innym kodzie pozwala to atakującemu przejąć kontrolę nad systemem i znacznie skuteczniej ukryć swoją obecność i rozpocząć proces rekonesansu. Jak piszę OpenAI, cały przebieg zużył środki na API o wartości około 1,2 miliona dolarów, czyli około 1279 $ za jeden exploit dający uprawnienia administratora. Nie jest to mała kwota, ale dla porównania program Pwn2Own i TyphoonPWN⁠ oferowały nagrody za eksploity LPE w jądrze Linuksa w wysokości odpowiednio 20K i 70K dolarów.

OpenAI twierdzi, że w ramach projektu Patch The Planet współpracuje ze społecznością jądra nad zgłaszaniem błędów i dostarczaniem poprawek, zaczynając od tych najbardziej krytycznych (i oby wszystkich…). W ciągu dziesięciu dni działania skanera poand 100 innych błędów pozwalających na eskalację uprawnień zostało naprawionych przez innych twórców open source. Najbardziej dające do myślenia zdanie w raporcie głosi, że obecnie nisko uprzywilejowane konto w niezaktualizowanym systemie „należy uznać za funkcjonalnie równoważne z dostępem do uprawnień administratora dla dobrze zaopatrzonego w zasoby obliczeniowe podmiotu stanowiącego zagrożenie” (ang. threat actor). Ostatnie tygodnie były wyjątkowo intensywne dla inżynierów programowania (w wielu językach), systemów i bezpieczeństwa. Na razie nic nie wskazuje na to, by tempo miało w najbliższym czasie spaść. Fala podatności odkrywanych przez modele AI wydaje się nie słabnąć i łatwo ulec wrażeniu, że jesteśmy przez nie ciągle atakowani. Warto jednak wziąć pod uwagę, jak często w przeszłości społeczność projektów open source apelowała do firm wykorzystujących ich otwarte narzędzia i biblioteki jako kluczowe elementy swojego biznesu o różnego rodzaju wsparcie. Niestety w wielu przypadkach nadal jest to prawda z mema gdzie jeden programista swoim projektem utrzymuje działanie całego internetu. Dziś na naszych oczach spełniania się Prawo Linusa, gdzie coraz większa liczba „wirtualnych oczu” zaczyna przeglądać ten kod od nowa i dostrzegać w nim „przeoczone” błędy. Kluczowe wyzwanie przesunęło się z liczebności społeczności na filtrację szumu wywoływanego przez AI. Część pracy przy weryfikacji jest jednak zdejmowana z opiekunów projektu dzięki modelom, które wraz z luką automatycznie dostarczają działający kod PoC. Przyjmując, że te same modele asystują już przy procesach przeglądu kodu (ang. code review) i analizują nadsyłane nowe bloki instrukcji – wyłapując regresje wydajnościowe, bezpieczeństwa i logiczne, zanim kod trafi do akceptacji przez ludzi – dynamika „nowo-starych” błędów powinna powoli słabnąć. Niestety nieokreślonym na tej osi czasu pozostaje apogeum tego zjawiska oraz fakt, czy w przyszłości modele nowszych generacji nie będą powtarzały tego procesu od nowa (np. wynajdując nowe klasy podatności lub łącząc już znane w łańcuchy).

Kategorie K a t e g o r i e : Bezpieczeństwo

Tagi T a g i : , , ,

Brak nowszych postów

Komentowanie tego wpisu jest zablokowane.