Wer kennt es nicht: Es wird ein CVE (Common Vulnerabilities and Exposures) veröffentlicht und man hat nicht die Zeit sich einzuarbeiten. Also liest man zuverlässige Zusammenfassungen zu den Schwachstellen. Im Normalfall gerät es in Vergessenheit, da die Schwachstelle nur einsetzbar ist, wenn man sich beispielsweise erst auf einem Host per SSH einloggen kann. Der SSH-Zugriff ist standardmäßig mit einem Passwort oder auch einem Zertifikat geschützt und in vielen Fällen über externe Verbindungen nicht möglich.
Mit Log4Shell gab es einmal mehr die Möglichkeit, ganz ohne Login oder Zugriff eine Schwachstelle auszunutzen. Solche Schwachstellen werden vom Hersteller in der Regel schnell behoben, sodass Nutzer sich gut aufgehoben fühlen. Weitere und vor allem eigene Maßnahmen werden dabei nicht angegangen. Wenn es einmal länger dauert beim Hersteller, kann es ja auch nicht so schlimm sein, oder? In diesem Beitrag schauen wir uns einmal die Zero-Day-Lücke Log4Shell näher an. Am Ende soll deutlich werden, dass die Optimierung der eigenen Workflows dabei helfen kann, die eigene IT-Landschaft abzusichern.
JNDI und Lookups
Log4Shell ermöglicht es, verschiedene Nutzerdaten auszulesen, zu verändern und damit auch ganze Systeme zu übernehmen. Dafür benötigt man lediglich ein Skript und einen Endpunkt.
Der Grund dafür lag in der standardmäßigen Aktivierung des JNDI-Lookups in der Log4j-Klasse. JNDI steht für “Java Directory and Naming Interface” und dient als API-Schnittstelle für beliebige Directory Services, wie LDAP, DNS, etc. Dabei kann die Anwendung Requests an den Directory Service senden. Dafür nutzt log4j die Funktionsweise von sogenannten Lookups.
Ein einzelner Import in der Anwendung
Mit dem Import
import org.apache.logging.log4j.Logger;
der Instanziierung der Klasse Logger mit
static Logger logger = LogManager.getLogger(CLASSNAME)
und dem Ausführen einer Funktion mit der Klasse im Programm
logger.error(...)
ist es bereits getan.
Mehr brauchte es nicht, um Angreifern sämtliche Türen und Tore zu öffnen. Alles was der Angreifer tun musste, war, beliebige Domains aufzurufen und auf diesen Import zu prüfen. Dabei wurden die URLs mit einem Präfix aufgerufen, also: ${jndi:ldap://example.com}. Der Präfix erlaubte es, sofern der Logger von Log4j auf diesem Pfad aktiviert war, einen direkten Abruf des angegebenen LDAP-Servers. Eine separate Freischaltung des JNDI-Lookups brauchte es dafür nicht.
Sobald eine valide URL damit gezielt angesprochen wird, kann man das Skript anhängen. Dieses Skript beinhaltet nun beliebige Befehle. Die Ausführung erfolgt im Rahmen des Prozessnutzers. Die Rechte dieses Nutzers bei der Ausführung der Java-Anwendung bestimmt natürlich die Anzahl der Möglichkeiten. So kann mit einem Root-Nutzer beispielsweise das Betriebssystem ausgespäht werden, Umgebungsvariablen ausgelesen werden oder Nutzer gelöscht oder erstellt werden.
Ein tiefergehendes Beispiel findet sich übrigens hier: https://news.sophos.com/en-us/2021/12/17/inside-the-code-how-the-log4shell-exploit-works/
Gefahr erkannt – Gefahr gebannt?
Jetzt, wo wir wissen, wie der Angriff funktioniert, kann der Fehler schnell behoben werden.
Eine der Maßnahmen der log4j-Entwickler war es, das standardmäßige Laden der Lookup-Module zu deaktivieren und die URL-Anfragen nicht mehr neu zu interpolieren.
Die genauen Änderungen finden sich einmal in der Release-Beschreibung oder aber in der Dokumentation:
- (Apache Log4j 2.17.1 Release Notes): https://lists.apache.org/thread/s1o5vlo78ypqxnzn6p8zf6t9shtq5143
- (Liste der Sicherheitslücken in Log4j): https://logging.apache.org/log4j/2.x/security.html
Der wohl einfachste Weg ist somit, die Lücke durch ein Update der Log4j-Bibliothek zu schließen. Was kann man aber tun, bis das der Fall ist? Der schnellste Weg ist natürlich, die Anwendung abzuschalten. Wenn es aber geschäftskritische Anwendungen sind, ist das meist nicht möglich.
Hot-Patches, WAFs oder doch Abschalten?
Es bleiben also drei Möglichkeiten:
- Ein Live-Patch, der während des Betriebs Änderungen an der Softwarekomponente durchführt,
- eine Abgrenzung der Pfade, die betroffen sind und
- eine Deaktivierung der Log4j-Lookups.
Im ersten Fall kann mit einem sogenannten “Dynamic Attach”-Mechanismus auf die laufende Java Virtual Machine zugreifen und direkt Änderungen vollziehen. Dafür wurde eigens für log4j von verschiedenen Communities ein HotPatch-Agent erstellt, der z.B. hier zu finden ist.
https://www.lunasec.io/docs/blog/log4shell-live-patch/
1. Live-Patches
Hier gelten aber die gängigen Vor- und Nachteile eines Hot-Patches. Während ein Hot-Patch die geringste Ausfallzeit bietet und Abhängigkeiten außer Acht lässt, ist die Änderung eines Live-Systems meist nicht revisionssicher oder nachvollziehbar genug. Nach dem Patch können auch einzelne Funktionen nicht mehr zur Verfügung stehen und damit einen Ausfall erzeugen. Damit ist diese Art des Vorgehens nur in sehr zeitkritischen Situationen empfehlenswert. Die Nacharbeiten, wie beispielsweise die Dokumentation müssen dabei mit in Betracht gezogen werden.
2. Abgrenzung der Pfade
Das Prinzip der Abgrenzung lässt sich mit Hilfe von IPTables-Regeln oder einer Web Application Firewall lösen. Dabei werden Pfade und Anfragen vor der Ausführung geprüft und geblockt. Hierfür ist es jedoch notwendig, die betroffenen Pfade bzw. Angriffsmuster zu kennen.
3. Deaktivierung von Log4j-Lookups
Wenn es keine konkrete Abhängigkeit der Log4j-Bibliothek zum Anwendungssystem gibt, ist die Deaktivierung der Lookups-Methoden der effizienteste Weg. So kann mit einer geringen Downtime die gesamte Schwachstelle vermieden werden. Das setzt aber voraus, dass die Lookups explizit nicht für die Anwendungslogik benötigt wird. Beim Starten der Java-Anwendung kann dabei mit der Option
-Dlog4j2.formatMsgNoLookups=true
die Deaktivierung erfolgen.
Die optimale Lösung
Meist wird ein Mix aus mehreren Lösungsansätzen das beste Ergebnis liefern, wichtig bleibt nur eins: Wenn man Schwachstellen erkannt hat, muss man sofort reagieren. Eine fehlerfreie Software wird es nie geben. Es ist wichtig, frühzeitig zu reagieren, da nicht klar ist, wann diese Sicherheitslücke großflächig eingesetzt wird.
Der Vorteil einer Configuration Management Database
Wir bei SysEleven konnten mit Hilfe unseres IT-Security-Teams zeitnah unsere Kunden informieren, die verwundbaren Systeme identifizieren und mit der Absicherung noch am Tag der Bekanntmachung des CVE beginnen.
Die CVE-Meldung wurde bereits am Tag der Veröffentlichung, Freitag dem 10.12.2021 intern begutachtet. Daraufhin wurden alle Systeme auf installierte Java-Komponenten geprüft. Da wir als Managed-Service-Anbieter viele verschiedene Systeme betreuen, hätte eine Suchabfrage sämtlicher Dateien nach Java-Komponenten im schlimmsten Fall mehrere Tage in Anspruch genommen. Puppet als Konfigurations-Management-Tool erleichtert die Arbeit dabei. Durch eine angebundene Configuration Management Database ist es möglich, die Installationen anhand sortierter Listen schnell zu identifizieren und beschleunigt die Abfrage:
puppet-query 'package_inventory[certname,version,package_name]{ package_name ~ "openjdk" or package_name ~ "oracle-java" }''
Darauf aufbauend konnte die Suche verfeinert werden und explizit nach den betroffenen JDK- bzw. den genutzten Log4J-Versionen gesucht werden.
Nach der Identifizierung wurden drei separate Maßnahmen getroffen. Zuerst wurden Kunden über den Status ihrer Setups informiert und gebeten, bei selbst verwalteten Komponenten zusätzlich auf die Sicherheitslücke zu prüfen. Parallel wurde in Abstimmung mit den jeweiligen Kunden das Lookup-Feature wie oben beschrieben deaktiviert. Kunden, die unser Zusatzangebot “DDoS-Protection” nutzen, haben außerdem die tagesaktuellen Sicherheitssignaturen eingespielt bekommen. Diese Sicherheitssignaturen prüfen ankommenden Datenverkehr auf die oben beschriebenen Angriffsparameter und blockieren diese Anfragen.
All das passierte am Abend der Bekanntmachung. Noch in derselben Nacht wurden erste Versuche registriert, auf Kundensysteme mit eben dieser Lücke zuzugreifen. Dank der schnellen Vorbereitungen blieb es aber dabei.
Auch unsere internen Systeme haben die Schwachstelle aufgezeigt. Während alle von außen erreichbaren Systeme sofort aktualisiert wurden, schoben wir die Systeme, die in unserem internen Netzwerk über VPN abgesichert waren, in die zweite Aktualisierungswelle. Über Nacht zeigte sich das Ausmaß der Schwachstelle in voller Gänze, als die Erfahrungsberichte zunahmen, sodass die erst für Montag geplanten Arbeiten noch am Samstagmorgen durchgeführt wurden.
So konnten wir innerhalb weniger Stunden alle Sicherheitsmaßnahmen treffen, die es zu diesem Zeitpunkt gab. In der darauffolgenden Woche wurden weitere Schritte diskutiert und umgesetzt, bis wir alle erdenklichen Möglichkeiten ausgereizt hatten und sicher sein konnten, dass die Schwachstelle nicht weiter ausgenutzt wurde.
Wollt ihr mehr erfahren? Gerne unterstützen wir Euch im Bereich IT-Security. Sprecht uns einfach an!