Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book

Podatności MITM i DoS w kliencie OpenSSH

20 lutego 2025, 16:04 | W biegu | 0 komentarzy

OpenSSH to jedno z tych narzędzi, bez którego życie administratorów i pentesterów byłoby ciężkie. Stanowi jeden z kluczowych elementów bezpiecznej konfiguracji hostów, oferując nie tylko szyfrowane połączenie ze zdalnym systemem, ale także pozwalając na skorzystanie z bardziej zaawansowanych funkcji jak forwardowanie portów czy X-ów (środowiska graficznego). Dlatego każda podatność wzbudza emocje. Ostatnio opisywaliśmy ciekawą podatność wprowadzoną ponownie do najpopularniejszej implementacji protokołów rodziny SSH – OpenSSH. 

TLDR:

  • Badacze przedstawili dwie podatności – MITM przy specyficznej i nie domyślnej (dla większości systemów) konfiguracji (CVE-2025-26465) oraz DoS bez uwierzytelnienia (CVE-2025-26466)
  • Qualys Threat Research Unit (TRU) zaprezentował błąd logiczny w kliencie OpenSSH (wersje od 6.8p1 do 9.9p1 włącznie) skutkujący możliwością przeprowadzenia ataku man-in-the-middle, w momencie gdy ustawiona jest opcja VerifyHostKeyDNS  
  • W nowszych klientach od wersji 9.5p1 do 9.9p1 odnotowano natomiast podatność typu denial of service, która nie wymaga uwierzytelnienia (tzn. preauth)

Dzisiaj przedstawiamy dwie podatności, o których znów poinformowali badacze z Qualys TUR (dodatkowe punkty za styl za formę prezentacji advisory w normalnej, łatwej do przyswojenia formie, którą da się przeczytać bez JS, po prostu w vimie – tak jak w redakcji lubimy najbardziej). 

CVE-2025-26465 – MiTM

Podatność sklasyfikowana jako High (8.1 CVSSv3) pozwala atakującemu przeprowadzić atak typu MITM, w momencie gdy wartość VerifyHostKeyDNS jest ustawiona na ask lub yes. Domyślnie ta opcja jest wyłączona (z wyjątkiem np. FreeBSD w okresie wrzesień 2013-marzec 2023). Opcja ta w zamyśle pozwala na zaakceptowanie odcisków kluczy, które zapisane są w rekordach DNS. 

The authenticity of host 'example.com (192.168.1.10)' can't be established.
ECDSA key fingerprint is SHA256:3sFxUeGJMb8gXfP+UPsD1rZJs6Xm6D/TcH3x2jvLWSc.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Listing 1. Domyślny komunikat w przypadku wyłączenia (bezpiecznej konfiguracji) opcji VerifyHostKeyDNS.

W przypadku skorzystania z tej funkcji (wartość konfiguracji yes), SSH sprawdzi rekordy SSHFP w DNSSEC i potwierdzi autentyczność hosta. Jeśli skonfigurowana została opcja ask – użytkownik zostanie zapytany o akceptację klucza hosta uzyskanego z rekordu DNS. 

Podatność wynika z błędu logicznego – pomyłki programistów, którzy w dużym projekcie nie uwzględnili wszystkich przypadków – zdarza się. 

Normalnie obsługa błędów wygląda jak na przytoczonym przez Qualysa fragmencie kodu źródłowego:

1387 int
1388 sshkey_to_base64(const struct sshkey *key, char **b64p)
1389 {
1390         int r = SSH_ERR_INTERNAL_ERROR;
....
1398         if ((r = sshkey_putb(key, b)) != 0)
1399                 goto out;
1400         if ((uu = sshbuf_dtob64_string(b, 0)) == NULL) {
1401                 r = SSH_ERR_ALLOC_FAIL;
1402                 goto out;
1403         }
....
1409         r = 0;
1410  out:
....
1413         return r;
1414 }

Listing 3. Podatny fragment kodu obsługującego sytuację, w której opcja VerifyHostKeyDNS jest włączona (źródło: qualys/OpenSSH)

Funkcja callback traktuje zwrócenie przez wywoływaną funkcję verify_host_key wartości -1 jako błąd. W innym przypadku (tj. np w sytuacji zwrócenia kodu błędu –14) callback zwraca wartość 0 oznaczającą sukces całej operacji weryfikacji hosta.

W czasie audytu kodu badaczom udało się znaleźć błąd SSH_ERR_ALLOC_FAIL o kodzie -2. Aby go wyzwolić musi dojść do błędu z alokacją pamięci. W tym celu przeanalizowano program pod kątem wycieków pamięci przed uwierzytelnieniem – z racji wysokiej jakości kodu OpenSSH tego “gadżetu” nie udało się odnaleźć. Ale znaleziono inny, przydatny fragment, pozwalający na wielokrotne alokacje pamięci. Po stronie klienta nie ma żadnych zabezpieczeń przed tego typu zajęciem zasobów, co pozwala wykorzystać tę technikę do “wyczerpania” pamięci hosta, przez co błąd SSH_ERR_ALLOC_FAIL zostanie przyrównany przez verify_host_key_callback do wartości -1, co w efekcie zwróci sukces, a to z kolei pozwoli na akceptację niezaufanego klucza i podszycie się pod zdalny serwer. 

CVE-2025-26466 – DoS

Informacje odkryte podczas eksploracji poprzedniej podatności pozwoliły na odnalezienie innego rodzaju błędu – okazało się, że sposób, w jaki pakiety PONG (wykorzystywane na poziomie warstwy transportowej protokołu SSH) są buforowane ponownie po zakończeniu procedury wymiany klucz (KEX) daje kwadratową złożoność czasową (O(n2)). Wysłanie 128MB wiadomości PING, będzie skutkowało tym, że operacja kopiowania odpowiedzi PONG “przeniesie” niemal 32TB danych. Wysłanie 16MB pakietów PING i rozłączenie z serwerem pozwala na zajęcie 100% czasu procesora na dwie minuty. Wykorzystując wiele równoległych połączeń atakujący może doprowadzić do wyczerpania zasobów serwera.

Badacze zaprezentowali PoC (proof-of-concept) na znalezione błędy. Od czasu zgłoszenia błędu (które miało miejsce 31.01.2025) do publikacji (18.02.2025) nie minęło dużo czasu, co po raz kolejny pokazuje, że osoby odpowiedzialne za OpenSSH podchodzą do swojej misji poważnie.

Qualysowi jak zwykle gratulujemy świetnych odkryć błędów, a programistom OpenSSH reakcji na zgłoszenie oraz, co było podkreślane wielokrotnie przez badaczy bezpieczeństwa, jakości kodu, w którym coraz trudniej znaleźć nawet złożone podatności. 

Użytkownicy powinni jak najszybciej wgrać łatki, a jeśli nie jest to możliwe, to powinni zrezygnować z opcji VerifyHostKeyDNS (co ustrzeże przed atakiem MiTM, jednak wciąż pozostawi instancję podatną na atak DoS). 

~fc

Spodobał Ci się wpis? Podziel się nim ze znajomymi:



Komentarze

Odpowiedz