mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/deserialization/basic-java-deserializati
This commit is contained in:
parent
7d710767c6
commit
85b82e417d
@ -1,15 +1,27 @@
|
||||
# Basic Java Deserialization with ObjectInputStream readObject
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Σε αυτήν την ανάρτηση θα εξηγηθεί ένα παράδειγμα χρησιμοποιώντας `java.io.Serializable`.
|
||||
Σε αυτή την ανάρτηση θα εξηγηθεί ένα παράδειγμα χρησιμοποιώντας `java.io.Serializable` **και γιατί η υπερχείλιση του `readObject()` μπορεί να είναι εξαιρετικά επικίνδυνη αν το εισερχόμενο ρεύμα ελέγχεται από επιτιθέμενο**.
|
||||
|
||||
# Serializable
|
||||
## Serializable
|
||||
|
||||
Η διεπαφή Java `Serializable` (`java.io.Serializable` είναι μια διεπαφή σήμανσης που οι κλάσεις σας πρέπει να υλοποιούν αν θέλουν να **σειριοποιηθούν** και **αποσειριοποιηθούν**. Η σειριοποίηση αντικειμένων Java (γραφή) γίνεται με το [ObjectOutputStream](http://tutorials.jenkov.com/java-io/objectoutputstream.html) και η αποσειριοποίηση (ανάγνωση) γίνεται με το [ObjectInputStream](http://tutorials.jenkov.com/java-io/objectinputstream.html).
|
||||
Η διεπαφή Java `Serializable` (`java.io.Serializable`) είναι μια διεπαφή σήμανσης που οι κλάσεις σας πρέπει να υλοποιούν αν θέλουν να είναι **serializable** και **deserializable**. Η σειριοποίηση αντικειμένων Java (γραφή) γίνεται με το [`ObjectOutputStream`](http://tutorials.jenkov.com/java-io/objectoutputstream.html) και η αποσειριοποίηση (ανάγνωση) γίνεται με το [`ObjectInputStream`](http://tutorials.jenkov.com/java-io/objectinputstream.html).
|
||||
|
||||
Ας δούμε ένα παράδειγμα με μια **κλάση Person** η οποία είναι **σειριοποιήσιμη**. Αυτή η κλάση **υπερκαλύπτει τη συνάρτηση readObject**, έτσι όταν **οποιοδήποτε αντικείμενο** αυτής της **κλάσης** είναι **αποσειριοποιημένο**, αυτή η **συνάρτηση** θα **εκτελείται**.\
|
||||
### Υπενθύμιση: Ποιες μέθοδοι καλούνται έμμεσα κατά την αποσειριοποίηση;
|
||||
|
||||
1. `readObject()` – λογική ανάγνωσης συγκεκριμένης κλάσης (αν έχει υλοποιηθεί και είναι *ιδιωτική*).
|
||||
2. `readResolve()` – μπορεί να αντικαταστήσει το αποσειριοποιημένο αντικείμενο με ένα άλλο.
|
||||
3. `validateObject()` – μέσω callbacks `ObjectInputValidation`.
|
||||
4. `readExternal()` – για κλάσεις που υλοποιούν `Externalizable`.
|
||||
5. Οι κατασκευαστές **δεν** εκτελούνται – επομένως οι αλυσίδες gadget βασίζονται αποκλειστικά στους προηγούμενους callbacks.
|
||||
|
||||
Οποιαδήποτε μέθοδος σε αυτή την αλυσίδα που καταλήγει να καλεί δεδομένα ελεγχόμενα από επιτιθέμενο (εκτέλεση εντολών, αναζητήσεις JNDI, ανακλαστικότητα, κ.λπ.) μετατρέπει τη ρουτίνα αποσειριοποίησης σε gadget RCE.
|
||||
|
||||
Ας δούμε ένα παράδειγμα με μια **κλάση Person** που είναι **serializable**. Αυτή η κλάση **υπερκαλύπτει τη συνάρτηση readObject**, έτσι όταν **οποιοδήποτε αντικείμενο** αυτής της **κλάσης** είναι **deserialized** αυτή η **συνάρτηση** θα **εκτελείται**.\
|
||||
Στο παράδειγμα, η **συνάρτηση readObject** της κλάσης Person καλεί τη συνάρτηση `eat()` του κατοικίδιου του και η συνάρτηση `eat()` ενός Σκύλου (για κάποιο λόγο) καλεί ένα **calc.exe**. **Θα δούμε πώς να σειριοποιήσουμε και να αποσειριοποιήσουμε ένα αντικείμενο Person για να εκτελέσουμε αυτόν τον υπολογιστή:**
|
||||
|
||||
**Το παρακάτω παράδειγμα είναι από [https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649](https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649)**
|
||||
**Το παρακάτω παράδειγμα είναι από <https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649>**
|
||||
```java
|
||||
import java.io.Serializable;
|
||||
import java.io.*;
|
||||
@ -80,8 +92,63 @@ payloadTest("test.ser");
|
||||
}
|
||||
}
|
||||
```
|
||||
## Συμπέρασμα
|
||||
### Συμπέρασμα (κλασικό σενάριο)
|
||||
|
||||
Όπως μπορείτε να δείτε σε αυτό το πολύ βασικό παράδειγμα, η "ευπάθεια" εδώ εμφανίζεται επειδή η **readObject** συνάρτηση **καλεί άλλες ευάλωτες συναρτήσεις**.
|
||||
Όπως μπορείτε να δείτε σε αυτό το πολύ βασικό παράδειγμα, η “ευπάθεια” εδώ εμφανίζεται επειδή η μέθοδος **readObject()** **καλεί άλλον κώδικα που ελέγχεται από τον επιτιθέμενο**. Σε πραγματικές αλυσίδες gadget, χιλιάδες κλάσεις που περιέχονται σε εξωτερικές βιβλιοθήκες (Commons-Collections, Spring, Groovy, Rome, SnakeYAML, κ.λπ.) μπορούν να καταχραστούν – ο επιτιθέμενος χρειάζεται μόνο *μία* προσβάσιμη gadget για να αποκτήσει εκτέλεση κώδικα.
|
||||
|
||||
---
|
||||
|
||||
## 2023-2025: Τι νέο υπάρχει στις επιθέσεις αποσυμπίεσης Java;
|
||||
|
||||
* 2023 – CVE-2023-34040: Η αποσυμπίεση κεφαλίδων σφαλμάτων του Spring-Kafka όταν είναι ενεργοποιημένες οι σημαίες `checkDeserExWhen*` επέτρεψε την αυθαίρετη κατασκευή gadget από θέματα που δημοσιεύθηκαν από τον επιτιθέμενο. Διορθώθηκε στην 3.0.10 / 2.9.11. ¹
|
||||
* 2023 – CVE-2023-36480: Η υπόθεση αξιόπιστου διακομιστή του Aerospike Java client παραβιάστηκε – οι κακόβουλες απαντήσεις του διακομιστή περιείχαν σειριακά payloads που αποσυμπιέστηκαν από τον client → RCE. ²
|
||||
* 2023 – CVE-2023-25581: Η ανάλυση του χαρακτηριστικού προφίλ χρήστη του `pac4j-core` αποδέχθηκε blobs Base64 με πρόθεμα `{#sb64}` και τα αποσυμπίεσε παρά την ύπαρξη ενός `RestrictedObjectInputStream`. Αναβάθμιση ≥ 4.0.0.
|
||||
* 2023 – CVE-2023-4528: Η υπηρεσία JSCAPE MFT Manager (θύρα 10880) αποδέχθηκε Java αντικείμενα κωδικοποιημένα σε XML που οδήγησαν σε RCE ως root/SYSTEM.
|
||||
* 2024 – Προστέθηκαν πολλές νέες αλυσίδες gadget στο ysoserial-plus(mod) συμπεριλαμβανομένων των κλάσεων Hibernate5, TomcatEmbed και SnakeYAML 2.x που παρακάμπτουν ορισμένα παλιά φίλτρα.
|
||||
|
||||
## Σύγχρονες μετρήσεις που πρέπει να εφαρμόσετε
|
||||
|
||||
1. **JEP 290 / Φιλτράρισμα Σειριοποίησης (Java 9+)**
|
||||
*Προσθέστε μια λίστα επιτρεπόμενων ή απαγορευμένων κλάσεων:*
|
||||
```bash
|
||||
# Αποδεχθείτε μόνο τα DTO σας και το java.base, απορρίψτε τα πάντα τα άλλα
|
||||
-Djdk.serialFilter="com.example.dto.*;java.base/*;!*"
|
||||
```
|
||||
Προγραμματιστικό παράδειγμα:
|
||||
```java
|
||||
var filter = ObjectInputFilter.Config.createFilter("com.example.dto.*;java.base/*;!*" );
|
||||
ObjectInputFilter.Config.setSerialFilter(filter);
|
||||
```
|
||||
2. **JEP 415 (Java 17+) Φίλτρα Ειδικών Συγκείμενων** – χρησιμοποιήστε έναν `BinaryOperator<ObjectInputFilter>` για να εφαρμόσετε διαφορετικά φίλτρα ανά εκτελεστικό συγκείμενο (π.χ., ανά κλήση RMI, ανά καταναλωτή ουράς μηνυμάτων).
|
||||
3. **Μην εκθέτετε το raw `ObjectInputStream` μέσω του δικτύου** – προτιμήστε κωδικοποιήσεις JSON/Binary χωρίς σημασιολογία εκτέλεσης κώδικα (Jackson μετά την απενεργοποίηση του `DefaultTyping`, Protobuf, Avro, κ.λπ.).
|
||||
4. **Περιορισμοί Άμυνας σε Βάθος** – Ορίστε μέγιστο μήκος πίνακα, βάθος, αναφορές:
|
||||
```bash
|
||||
-Djdk.serialFilter="maxbytes=16384;maxdepth=5;maxrefs=1000"
|
||||
```
|
||||
5. **Συνεχής σάρωση gadget** – εκτελέστε εργαλεία όπως `gadget-inspector` ή `serialpwn-cli` στο CI σας για να αποτύχει η κατασκευή αν γίνει προσβάσιμο ένα επικίνδυνο gadget.
|
||||
|
||||
## Ενημερωμένο cheat-sheet εργαλείων (2024)
|
||||
|
||||
* `ysoserial-plus.jar` – κοινότητα fork με > 130 αλυσίδες gadget:
|
||||
```bash
|
||||
java -jar ysoserial-plus.jar CommonsCollections6 'calc' | base64 -w0
|
||||
```
|
||||
* `marshalsec` – παραμένει η αναφορά για τη δημιουργία gadget JNDI (LDAP/RMI).
|
||||
* `gadget-probe` – γρήγορη ανακάλυψη gadget black-box κατά των δικτυακών υπηρεσιών.
|
||||
* `SerialSniffer` – JVMTI agent που εκτυπώνει κάθε κλάση που διαβάζεται από το `ObjectInputStream` (χρήσιμο για τη δημιουργία φίλτρων).
|
||||
* **Συμβουλή ανίχνευσης** – ενεργοποιήστε το `-Djdk.serialDebug=true` (JDK 22+) για να καταγράψετε τις αποφάσεις φίλτρου και τις απορριφθείσες κλάσεις.
|
||||
|
||||
## Γρήγορη λίστα ελέγχου για ασφαλείς υλοποιήσεις `readObject()`
|
||||
|
||||
1. Κάντε τη μέθοδο `private` και προσθέστε την αναγνώριση `@Serial` (βοηθά στην στατική ανάλυση).
|
||||
2. Ποτέ μην καλείτε μεθόδους που παρέχονται από τον χρήστη ή μην εκτελείτε I/O στη μέθοδο – μόνο διαβάστε πεδία.
|
||||
3. Εάν απαιτείται επικύρωση, εκτελέστε την **μετά** την αποσυμπίεση, εκτός της `readObject()`.
|
||||
4. Προτιμήστε να υλοποιήσετε το `Externalizable` και να κάνετε ρητές αναγνώσεις πεδίων αντί για προεπιλεγμένη σειριοποίηση.
|
||||
5. Εγγραφείτε σε ένα σκληρυμένο `ObjectInputFilter` ακόμη και για εσωτερικές υπηρεσίες (σχεδίαση ανθεκτική σε παραβιάσεις).
|
||||
|
||||
## Αναφορές
|
||||
|
||||
1. Spring Security Advisory – CVE-2023-34040 Java Deserialization in Spring-Kafka (Αυγ 2023)
|
||||
2. GitHub Security Lab – GHSL-2023-044: Unsafe Deserialization in Aerospike Java Client (Ιουλ 2023)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user