hacktricks/pentesting-web/file-inclusion/lfi2rce-via-eternal-waiting.md

123 lines
9.4 KiB
Markdown

# LFI2RCE via Attente éternelle
<details>
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Autres moyens de soutenir HackTricks :
* Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)!
* Obtenez le [**merchandising officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* Découvrez [**La Famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection d'[**NFTs**](https://opensea.io/collection/the-peass-family) exclusifs
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez-moi** sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Partagez vos astuces de piratage en soumettant des PR aux dépôts github** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
## Informations de base
Par défaut, lorsqu'un fichier est téléversé sur PHP (même s'il ne l'attend pas), il générera un fichier temporaire dans `/tmp` avec un nom tel que **`php[a-zA-Z0-9]{6}`**, bien que j'aie vu des images docker où les fichiers générés ne contiennent pas de chiffres.
Dans une inclusion de fichier local, **si vous parvenez à inclure ce fichier téléversé, vous obtiendrez un RCE**.
Notez que par défaut **PHP ne permet de téléverser que 20 fichiers dans une seule requête** (défini dans `/etc/php/<version>/apache2/php.ini`) :
```
; Maximum number of files that can be uploaded via a single request
max_file_uploads = 20
```
Aussi, **le nombre de noms de fichiers potentiels est de 62\*62\*62\*62\*62\*62 = 56800235584**
### Autres techniques
D'autres techniques reposent sur l'attaque de protocoles PHP (vous ne pourrez pas si vous contrôlez uniquement la dernière partie du chemin), la divulgation du chemin du fichier, l'exploitation de fichiers attendus, ou **faire en sorte que PHP subisse une faute de segmentation pour que les fichiers temporaires téléchargés ne soient pas supprimés**.\
Cette technique est **très similaire à la précédente mais sans avoir besoin de trouver un zero day**.
### Technique de l'attente éternelle
Dans cette technique, **nous avons seulement besoin de contrôler un chemin relatif**. Si nous parvenons à télécharger des fichiers et à faire en sorte que **l'inclusion LFI ne se termine jamais**, nous aurons "suffisamment de temps" pour **forcer le passage des fichiers téléchargés** et **trouver** l'un des fichiers téléchargés.
**Avantages de cette technique** :
* Vous avez juste besoin de contrôler un chemin relatif dans une inclusion
* Ne nécessite pas nginx ou un niveau d'accès inattendu aux fichiers journaux
* Ne nécessite pas un zero day pour provoquer une faute de segmentation
* Ne nécessite pas une divulgation de chemin
Les **principaux problèmes** de cette technique sont :
* Nécessité qu'un fichier spécifique soit présent (il pourrait y en avoir d'autres)
* Le nombre **insensé** de noms de fichiers potentiels : **56800235584**
* Si le serveur **n'utilise pas de chiffres** le nombre total potentiel est de : **19770609664**
* Par défaut, **seulement 20 fichiers** peuvent être téléchargés dans une **seule requête**.
* Le **nombre maximum de travailleurs parallèles** du serveur utilisé.
* Cette limite avec les précédentes peut rendre cette attaque trop longue
* **Délai d'attente pour une requête PHP**. Idéalement, cela devrait être éternel ou devrait tuer le processus PHP sans supprimer les fichiers temporairement téléchargés, sinon, cela sera également un problème
Alors, comment pouvez-vous **faire en sorte qu'une inclusion PHP ne se termine jamais** ? Tout simplement en incluant le fichier **`/sys/kernel/security/apparmor/revision`** (**malheureusement non disponible dans les conteneurs Docker**).
Essayez-le en appelant :
```bash
php -a # open php cli
include("/sys/kernel/security/apparmor/revision");
```
## Apache2
Par défaut, Apache supporte **150 connexions simultanées**, en suivant [https://ubiq.co/tech-blog/increase-max-connections-apache/](https://ubiq.co/tech-blog/increase-max-connections-apache/) il est possible d'augmenter ce nombre jusqu'à 8000. Suivez ceci pour utiliser PHP avec ce module : [https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04](https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04).
Par défaut, (comme je peux le voir dans mes tests), un **processus PHP peut durer éternellement**.
Faisons quelques calculs :
* Nous pouvons utiliser **149 connexions** pour générer **149 \* 20 = 2980 fichiers temporaires** avec notre webshell.
* Ensuite, utiliser la **dernière connexion** pour **forcer brutalement** les fichiers potentiels.
* À une vitesse de **10 requêtes/s**, les temps sont :
* 56800235584 / 2980 / 10 / 3600 ≈ **530 heures** (50% de chance en 265h)
* (sans chiffres) 19770609664 / 2980 / 10 / 3600 ≈ 185h (50% de chance en 93h)
{% hint style="warning" %}
Notez que dans l'exemple précédent, nous sommes en train de **DoS complètement les autres clients** !
{% endhint %}
Si le serveur Apache est amélioré et que nous pouvions abuser de **4000 connexions** (à mi-chemin du maximum). Nous pourrions créer `3999*20 = 79980` **fichiers** et le **nombre** serait **réduit** à environ **19.7h** ou **6.9h** (10h, 3.5h 50% de chance).
## PHP-FMP
Si au lieu d'utiliser le module php régulier pour apache pour exécuter des scripts PHP, **la page web utilise** **PHP-FMP** (cela améliore l'efficacité de la page web, donc il est courant de le trouver), il y a autre chose qui peut être fait pour améliorer la technique.
PHP-FMP permet de **configurer** le **paramètre** **`request_terminate_timeout`** dans **`/etc/php/<version-php>/fpm/pool.d/www.conf`**.\
Ce paramètre indique le nombre maximum de secondes **quand** **la requête à PHP doit se terminer** (infini par défaut, mais **30s si le paramètre est décommenté**). Lorsqu'une requête est traitée par PHP pendant le nombre de secondes indiqué, elle est **tuée**. Cela signifie que si la requête était en train de télécharger des fichiers temporaires, parce que le **traitement php a été arrêté**, ces **fichiers ne seront pas supprimés**. Par conséquent, si vous pouvez faire durer une requête ce temps, vous pouvez **générer des milliers de fichiers temporaires** qui ne seront pas supprimés, ce qui **accélérera le processus de les trouver** et réduit la probabilité d'un DoS sur la plateforme en consommant toutes les connexions.
Donc, pour **éviter le DoS**, supposons qu'un **attaquant utilisera seulement 100 connexions** en même temps et le temps de traitement maximum par **php-fmp** (`request_terminate_timeout`**) est de **30s**. Par conséquent, le nombre de **fichiers temporaires** qui peuvent être générés **par seconde** est `100*20/30 = 66.67`.
Ensuite, pour générer **10000 fichiers**, un attaquant aurait besoin : **`10000/66.67 = 150s`** (pour générer **100000 fichiers**, le temps serait de **25min**).
Ensuite, l'attaquant pourrait utiliser ces **100 connexions** pour effectuer une **recherche par force brute**. \*\*\*\* En supposant une vitesse de 300 req/s, le temps nécessaire pour exploiter ceci est le suivant :
* 56800235584 / 10000 / 300 / 3600 ≈ **5.25 heures** (50% de chance en 2.63h)
* (avec 100000 fichiers) 56800235584 / 100000 / 300 / 3600 ≈ **0.525 heures** (50% de chance en 0.263h)
Oui, il est possible de générer 100000 fichiers temporaires dans une instance EC2 de taille moyenne :
<figure><img src="../../.gitbook/assets/image (3) (1) (1) (3).png" alt=""><figcaption></figcaption></figure>
{% hint style="warning" %}
Notez que pour déclencher le délai d'attente, il suffirait d'inclure la page LFI vulnérable, pour qu'elle entre dans une boucle d'inclusion éternelle.
{% endhint %}
## Nginx
Il semble que par défaut Nginx supporte **512 connexions parallèles** en même temps (et ce nombre peut être amélioré).
<details>
<summary><strong>Apprenez le hacking AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Autres moyens de soutenir HackTricks :
* Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)!
* Obtenez le [**merchandising officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* Découvrez [**La Famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection d'[**NFTs**](https://opensea.io/collection/the-peass-family) exclusifs
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Partagez vos astuces de hacking en soumettant des PR aux dépôts github** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>