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
91c08365b6
commit
1f1403503e
@ -1,15 +1,27 @@
|
||||
# Basic Java Deserialization with ObjectInputStream readObject
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
In questo POST verrà spiegato un esempio utilizzando `java.io.Serializable`.
|
||||
In questo POST verrà spiegato un esempio utilizzando `java.io.Serializable` **e perché sovrascrivere `readObject()` può essere estremamente pericoloso se il flusso in arrivo è controllato dall'attaccante**.
|
||||
|
||||
# Serializable
|
||||
## Serializable
|
||||
|
||||
L'interfaccia Java `Serializable` (`java.io.Serializable` è un'interfaccia marker che le tue classi devono implementare se devono essere **serializzate** e **deserializzate**. La serializzazione degli oggetti Java (scrittura) viene eseguita con l'[ObjectOutputStream](http://tutorials.jenkov.com/java-io/objectoutputstream.html) e la deserializzazione (lettura) viene eseguita con l'[ObjectInputStream](http://tutorials.jenkov.com/java-io/objectinputstream.html).
|
||||
L'interfaccia Java `Serializable` (`java.io.Serializable`) è un'interfaccia marker che le tue classi devono implementare se devono essere **serializzate** e **deserializzate**. La serializzazione degli oggetti Java (scrittura) viene eseguita con [`ObjectOutputStream`](http://tutorials.jenkov.com/java-io/objectoutputstream.html) e la deserializzazione (lettura) viene eseguita con [`ObjectInputStream`](http://tutorials.jenkov.com/java-io/objectinputstream.html).
|
||||
|
||||
Vediamo un esempio con una **classe Person** che è **serializzabile**. Questa classe **sovrascrive la funzione readObject**, quindi quando **qualunque oggetto** di questa **classe** viene **deserializzato**, questa **funzione** verrà **eseguita**.\
|
||||
### Promemoria: Quali metodi vengono invocati implicitamente durante la deserializzazione?
|
||||
|
||||
1. `readObject()` – logica di lettura specifica della classe (se implementata e *privata*).
|
||||
2. `readResolve()` – può sostituire l'oggetto deserializzato con un altro.
|
||||
3. `validateObject()` – tramite callback `ObjectInputValidation`.
|
||||
4. `readExternal()` – per classi che implementano `Externalizable`.
|
||||
5. I costruttori **non** vengono eseguiti – pertanto le catene di gadget si basano esclusivamente sui callback precedenti.
|
||||
|
||||
Qualsiasi metodo in quella catena che finisce per invocare dati controllati dall'attaccante (esecuzione di comandi, ricerche JNDI, riflessione, ecc.) trasforma la routine di deserializzazione in un gadget RCE.
|
||||
|
||||
Vediamo un esempio con una **classe Person** che è **serializzabile**. Questa classe **sovrascrive la funzione readObject**, quindi quando **qualsiasi oggetto** di questa **classe** viene **deserializzato**, questa **funzione** verrà **eseguita**.\
|
||||
Nell'esempio, la **funzione readObject** della classe Person chiama la funzione `eat()` del suo animale domestico e la funzione `eat()` di un Cane (per qualche motivo) chiama un **calc.exe**. **Vedremo come serializzare e deserializzare un oggetto Person per eseguire questa calcolatrice:**
|
||||
|
||||
**Il seguente esempio è tratto da [https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649](https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649)**
|
||||
**Il seguente esempio è tratto da <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");
|
||||
}
|
||||
}
|
||||
```
|
||||
## Conclusione
|
||||
### Conclusione (scenario classico)
|
||||
|
||||
Come puoi vedere in questo esempio molto basilare, la "vulnerabilità" qui appare perché la funzione **readObject** sta **chiamando altre funzioni vulnerabili**.
|
||||
Come puoi vedere in questo esempio molto basilare, la “vulnerabilità” qui appare perché il metodo **readObject()** sta **chiamando altro codice controllato dall'attaccante**. Nelle catene di gadget del mondo reale, migliaia di classi contenute in librerie esterne (Commons-Collections, Spring, Groovy, Rome, SnakeYAML, ecc.) possono essere abusate – l'attaccante ha bisogno solo di *uno* gadget raggiungibile per ottenere l'esecuzione del codice.
|
||||
|
||||
---
|
||||
|
||||
## 2023-2025: Novità negli attacchi di deserializzazione Java?
|
||||
|
||||
* 2023 – CVE-2023-34040: La deserializzazione degli header dei record di errore di Spring-Kafka quando i flag `checkDeserExWhen*` sono abilitati ha permesso la costruzione arbitraria di gadget da argomenti pubblicati dall'attaccante. Risolto in 3.0.10 / 2.9.11. ¹
|
||||
* 2023 – CVE-2023-36480: Assunzione di server fidati del client Java Aerospike rotta – le risposte del server malevole contenevano payload serializzati che sono stati deserializzati dal client → RCE. ²
|
||||
* 2023 – CVE-2023-25581: L'analisi degli attributi del profilo utente di `pac4j-core` accettava blob Base64 con prefisso `{#sb64}` e li deserializzava nonostante un `RestrictedObjectInputStream`. Aggiorna ≥ 4.0.0.
|
||||
* 2023 – CVE-2023-4528: Il servizio JSCAPE MFT Manager (porta 10880) accettava oggetti Java codificati in XML portando a RCE come root/SYSTEM.
|
||||
* 2024 – Sono state aggiunte nuove catene di gadget a ysoserial-plus(mod) inclusi Hibernate5, TomcatEmbed e classi SnakeYAML 2.x che bypassano alcuni vecchi filtri.
|
||||
|
||||
## Mitigazioni moderne che dovresti implementare
|
||||
|
||||
1. **JEP 290 / Filtro di Serializzazione (Java 9+)**
|
||||
*Aggiungi una lista di autorizzazione o di negazione delle classi:*
|
||||
```bash
|
||||
# Accetta solo i tuoi DTO e java.base, rifiuta tutto il resto
|
||||
-Djdk.serialFilter="com.example.dto.*;java.base/*;!*"
|
||||
```
|
||||
Esempio programmatico:
|
||||
```java
|
||||
var filter = ObjectInputFilter.Config.createFilter("com.example.dto.*;java.base/*;!*" );
|
||||
ObjectInputFilter.Config.setSerialFilter(filter);
|
||||
```
|
||||
2. **JEP 415 (Java 17+) Fabbriche di Filtri Specifici per Contesto** – usa un `BinaryOperator<ObjectInputFilter>` per applicare filtri diversi per contesto di esecuzione (ad esempio, per chiamata RMI, per consumatore di coda di messaggi).
|
||||
3. **Non esporre `ObjectInputStream` grezzo sulla rete** – preferisci codifiche JSON/Binary senza semantiche di esecuzione del codice (Jackson dopo aver disabilitato `DefaultTyping`, Protobuf, Avro, ecc.).
|
||||
4. **Limiti di Difesa in Profondità** – Imposta lunghezza massima degli array, profondità, riferimenti:
|
||||
```bash
|
||||
-Djdk.serialFilter="maxbytes=16384;maxdepth=5;maxrefs=1000"
|
||||
```
|
||||
5. **Scansione continua dei gadget** – esegui strumenti come `gadget-inspector` o `serialpwn-cli` nel tuo CI per far fallire la build se un gadget pericoloso diventa raggiungibile.
|
||||
|
||||
## Scheda di riferimento degli strumenti aggiornata (2024)
|
||||
|
||||
* `ysoserial-plus.jar` – fork della comunità con > 130 catene di gadget:
|
||||
```bash
|
||||
java -jar ysoserial-plus.jar CommonsCollections6 'calc' | base64 -w0
|
||||
```
|
||||
* `marshalsec` – rimane il riferimento per la generazione di gadget JNDI (LDAP/RMI).
|
||||
* `gadget-probe` – scoperta rapida di gadget black-box contro servizi di rete.
|
||||
* `SerialSniffer` – agente JVMTI che stampa ogni classe letta da `ObjectInputStream` (utile per creare filtri).
|
||||
* **Suggerimento per la rilevazione** – abilita `-Djdk.serialDebug=true` (JDK 22+) per registrare le decisioni del filtro e le classi rifiutate.
|
||||
|
||||
## Checklist rapida per implementazioni sicure di `readObject()`
|
||||
|
||||
1. Rendi il metodo `private` e aggiungi l'annotazione `@Serial` (aiuta l'analisi statica).
|
||||
2. Non chiamare metodi forniti dall'utente o eseguire I/O nel metodo – leggi solo i campi.
|
||||
3. Se è necessaria la validazione, eseguila **dopo** la deserializzazione, al di fuori di `readObject()`.
|
||||
4. Preferisci implementare `Externalizable` e fare letture esplicite dei campi invece della serializzazione predefinita.
|
||||
5. Registra un `ObjectInputFilter` rinforzato anche per i servizi interni (design resistente ai compromessi).
|
||||
|
||||
## Riferimenti
|
||||
|
||||
1. Avviso di Sicurezza di Spring – CVE-2023-34040 Deserializzazione Java in Spring-Kafka (Ago 2023)
|
||||
2. GitHub Security Lab – GHSL-2023-044: Deserializzazione non sicura nel client Java Aerospike (Lug 2023)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user