From cc50833391951feff6b1e3e457edcb3b1979b8a4 Mon Sep 17 00:00:00 2001 From: Translator Date: Mon, 28 Jul 2025 18:12:41 +0000 Subject: [PATCH] Translated ['src/pentesting-web/deserialization/basic-java-deserializati --- ...ialization-objectinputstream-readobject.md | 81 +++++++++++++++++-- 1 file changed, 74 insertions(+), 7 deletions(-) diff --git a/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md b/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md index c4e13e942..7c236a1ed 100644 --- a/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md +++ b/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md @@ -1,15 +1,27 @@ +# Grundlegende Java-Deserialisierung mit ObjectInputStream readObject + {{#include ../../banners/hacktricks-training.md}} -In diesem POST wird ein Beispiel mit `java.io.Serializable` erklärt. +In diesem POST wird ein Beispiel erklärt, das `java.io.Serializable` verwendet **und warum das Überschreiben von `readObject()` extrem gefährlich sein kann, wenn der eingehende Stream vom Angreifer kontrolliert wird**. -# Serializable +## Serializable -Das Java `Serializable`-Interface (`java.io.Serializable`) ist ein Marker-Interface, das Ihre Klassen implementieren müssen, wenn sie **serialisiert** und **deserialisiert** werden sollen. Die Java-Objektserialisierung (Schreiben) erfolgt mit dem [ObjectOutputStream](http://tutorials.jenkov.com/java-io/objectoutputstream.html) und die Deserialisierung (Lesen) erfolgt mit dem [ObjectInputStream](http://tutorials.jenkov.com/java-io/objectinputstream.html). +Das Java `Serializable`-Interface (`java.io.Serializable`) ist ein Marker-Interface, das Ihre Klassen implementieren müssen, wenn sie **serialisiert** und **deserialisiert** werden sollen. Die Java-Objektserialisierung (Schreiben) erfolgt mit dem [`ObjectOutputStream`](http://tutorials.jenkov.com/java-io/objectoutputstream.html) und die Deserialisierung (Lesen) erfolgt mit dem [`ObjectInputStream`](http://tutorials.jenkov.com/java-io/objectinputstream.html). + +### Erinnerung: Welche Methoden werden während der Deserialisierung implizit aufgerufen? + +1. `readObject()` – klassen-spezifische Lese-Logik (wenn implementiert und *privat*). +2. `readResolve()` – kann das deserialisierte Objekt durch ein anderes ersetzen. +3. `validateObject()` – über `ObjectInputValidation`-Callbacks. +4. `readExternal()` – für Klassen, die `Externalizable` implementieren. +5. Konstruktoren werden **nicht** ausgeführt – daher verlassen sich Gadget-Ketten ausschließlich auf die vorherigen Callbacks. + +Jede Methode in dieser Kette, die letztendlich Angreifer-kontrollierte Daten aufruft (Befehlsausführung, JNDI-Abfragen, Reflection usw.), verwandelt die Deserialisierungsroutine in ein RCE-Gadget. Lassen Sie uns ein Beispiel mit einer **Klasse Person** ansehen, die **serialisierbar** ist. Diese Klasse **überschreibt die readObject**-Funktion, sodass, wenn **irgendein Objekt** dieser **Klasse** **deserialisiert** wird, diese **Funktion** **ausgeführt** wird.\ -Im Beispiel ruft die **readObject-Funktion** der Klasse Person die Funktion `eat()` seines Haustiers auf, und die Funktion `eat()` eines Hundes (aus irgendeinem Grund) ruft eine **calc.exe** auf. **Wir werden sehen, wie man ein Person-Objekt serialisiert und deserialisiert, um diesen Rechner auszuführen:** +Im Beispiel ruft die **readObject**-Funktion der Klasse Person die Funktion `eat()` seines Haustiers auf, und die Funktion `eat()` eines Hundes (aus irgendeinem Grund) ruft eine **calc.exe** auf. **Wir werden sehen, wie man ein Person-Objekt serialisiert und deserialisiert, um diesen Rechner auszuführen:** -**Das folgende Beispiel stammt von [https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649](https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649)** +**Das folgende Beispiel stammt von ** ```java import java.io.Serializable; import java.io.*; @@ -80,8 +92,63 @@ payloadTest("test.ser"); } } ``` -## Fazit +### Fazit (klassisches Szenario) -Wie Sie in diesem sehr einfachen Beispiel sehen können, tritt die "Schwachstelle" hier auf, weil die **readObject**-Funktion **andere anfällige Funktionen aufruft**. +Wie Sie in diesem sehr einfachen Beispiel sehen können, tritt die „Schwachstelle“ hier auf, weil die **readObject()**-Methode **anderen vom Angreifer kontrollierten Code aufruft**. In realen Gadget-Ketten können Tausende von Klassen, die in externen Bibliotheken (Commons-Collections, Spring, Groovy, Rome, SnakeYAML usw.) enthalten sind, missbraucht werden – der Angreifer benötigt nur *ein* erreichbares Gadget, um Codeausführung zu erlangen. + +--- + +## 2023-2025: Was gibt es Neues bei Java-Deserialisierungsangriffen? + +* 2023 – CVE-2023-34040: Spring-Kafka-Deserialisierung von Fehlerdatensatz-Headern, wenn `checkDeserExWhen*`-Flags aktiviert sind, erlaubte die willkürliche Gadget-Konstruktion aus von Angreifern veröffentlichten Themen. In 3.0.10 / 2.9.11 behoben. ¹ +* 2023 – CVE-2023-36480: Aerospike Java-Client vertrauenswürdige Serverannahme gebrochen – bösartige Serverantworten enthielten serialisierte Payloads, die vom Client deserialisiert wurden → RCE. ² +* 2023 – CVE-2023-25581: `pac4j-core` Benutzerprofilattribut-Parsing akzeptierte `{#sb64}`-präfixierte Base64-Blobs und deserialisierte sie trotz eines `RestrictedObjectInputStream`. Upgrade ≥ 4.0.0. +* 2023 – CVE-2023-4528: JSCAPE MFT Manager Service (Port 10880) akzeptierte XML-kodierte Java-Objekte, was zu RCE als root/SYSTEM führte. +* 2024 – Mehrere neue Gadget-Ketten wurden zu ysoserial-plus(mod) hinzugefügt, einschließlich Hibernate5, TomcatEmbed und SnakeYAML 2.x-Klassen, die einige alte Filter umgehen. + +## Moderne Abhilfemaßnahmen, die Sie implementieren sollten + +1. **JEP 290 / Serialisierungsfilterung (Java 9+)** +*Fügen Sie eine Erlauben- oder Verweigern-Liste von Klassen hinzu:* +```bash +# Akzeptieren Sie nur Ihre DTOs und java.base, lehnen Sie alles andere ab +-Djdk.serialFilter="com.example.dto.*;java.base/*;!*" +``` +Programmierbeispiel: +```java +var filter = ObjectInputFilter.Config.createFilter("com.example.dto.*;java.base/*;!*" ); +ObjectInputFilter.Config.setSerialFilter(filter); +``` +2. **JEP 415 (Java 17+) Kontext-spezifische Filterfabriken** – verwenden Sie einen `BinaryOperator`, um unterschiedliche Filter pro Ausführungskontext anzuwenden (z. B. pro RMI-Aufruf, pro Nachrichtenwarteschlangenverbraucher). +3. **Keine rohen `ObjectInputStream` über das Netzwerk exponieren** – bevorzugen Sie JSON/Binärkodierungen ohne Codeausführungssemantik (Jackson nach Deaktivierung von `DefaultTyping`, Protobuf, Avro usw.). +4. **Defense-in-Depth-Limits** – Setzen Sie maximale Array-Längen, Tiefen, Referenzen: +```bash +-Djdk.serialFilter="maxbytes=16384;maxdepth=5;maxrefs=1000" +``` +5. **Kontinuierliches Gadget-Scannen** – führen Sie Tools wie `gadget-inspector` oder `serialpwn-cli` in Ihrer CI aus, um den Build zu fehlschlagen, wenn ein gefährliches Gadget erreichbar wird. + +## Aktualisierte Tooling-Checkliste (2024) + +* `ysoserial-plus.jar` – Community-Fork mit > 130 Gadget-Ketten: +```bash +java -jar ysoserial-plus.jar CommonsCollections6 'calc' | base64 -w0 +``` +* `marshalsec` – immer noch das Referenzwerkzeug zur JNDI-Gadget-Generierung (LDAP/RMI). +* `gadget-probe` – schnelle Black-Box-Gadget-Entdeckung gegen Netzwerkdienste. +* `SerialSniffer` – JVMTI-Agent, der jede Klasse druckt, die von `ObjectInputStream` gelesen wird (nützlich zum Erstellen von Filtern). +* **Erkennungstipp** – aktivieren Sie `-Djdk.serialDebug=true` (JDK 22+), um Filterentscheidungen und abgelehnte Klassen zu protokollieren. + +## Schnelle Checkliste für sichere `readObject()`-Implementierungen + +1. Machen Sie die Methode `private` und fügen Sie die `@Serial`-Annotation hinzu (hilft bei der statischen Analyse). +2. Rufen Sie niemals benutzereingereichte Methoden auf oder führen Sie I/O in der Methode aus – lesen Sie nur Felder. +3. Wenn eine Validierung erforderlich ist, führen Sie diese **nach** der Deserialisierung außerhalb von `readObject()` durch. +4. Bevorzugen Sie die Implementierung von `Externalizable` und führen Sie explizite Feldlesungen anstelle der Standardserialisierung durch. +5. Registrieren Sie einen gehärteten `ObjectInputFilter`, auch für interne Dienste (kompromissresistentes Design). + +## Referenzen + +1. Spring Security Advisory – CVE-2023-34040 Java-Deserialisierung in Spring-Kafka (Aug 2023) +2. GitHub Security Lab – GHSL-2023-044: Unsichere Deserialisierung im Aerospike Java-Client (Jul 2023) {{#include ../../banners/hacktricks-training.md}}