LFI2RCE via Eternal waiting
Reading time: 6 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Soutenir HackTricks
- VĂ©rifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PRs au HackTricks et HackTricks Cloud dépÎts github.
Informations de base
Par dĂ©faut, lorsqu'un fichier est tĂ©lĂ©chargĂ© sur PHP (mĂȘme s'il ne s'y 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 certaines 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échargé, vous obtiendrez RCE.
Notez qu'en rĂšgle gĂ©nĂ©rale, PHP n'autorise que le tĂ©lĂ©chargement de 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 62*62*62*62*62*62 = 56800235584
Autres techniques
D'autres techniques reposent sur l'attaque des protocoles PHP (vous ne pourrez pas le faire si vous ne contrÎlez que la derniÚre partie du chemin), la divulgation du chemin du fichier, l'abus de fichiers attendus, ou faire souffrir PHP d'un défaut de segmentation afin que les fichiers temporaires téléchargés ne soient pas supprimés.
Cette technique est trĂšs similaire Ă la derniĂšre mais sans avoir besoin de trouver un zero day.
Technique de l'attente Ă©ternelle
Dans cette technique, nous n'avons besoin de contrÎler qu'un chemin relatif. Si nous parvenons à télécharger des fichiers et à faire en sorte que LFI ne se termine jamais, nous aurons "assez de temps" pour brute-forcer les fichiers téléchargés et trouver n'importe lequel des fichiers téléchargés.
Avantages de cette technique :
- Vous devez juste contrÎler un chemin relatif à l'intérieur d'un include
- Ne nécessite pas nginx ou un niveau d'accÚs inattendu aux fichiers journaux
- Ne nécessite pas un 0 day pour provoquer un défaut de segmentation
- Ne nécessite pas de divulgation de chemin
Les principaux problĂšmes de cette technique sont :
- Besoin d'un fichier spécifique (il peut y en avoir d'autres)
- L'énorme quantité de noms de fichiers potentiels : 56800235584
- Si le serveur n'utilise pas de chiffres, le nombre total potentiel est : 19770609664
- Par dĂ©faut, seulement 20 fichiers peuvent ĂȘtre tĂ©lĂ©chargĂ©s dans une unique requĂȘte.
- Le nombre max de travailleurs parallÚles du serveur utilisé.
- Cette limite avec les précédentes peut faire durer cette attaque trop longtemps
- 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 temporaires tĂ©lĂ©chargĂ©s, sinon, cela sera Ă©galement un problĂšme
Alors, comment pouvez-vous faire en sorte qu'un include PHP ne se termine jamais ? Juste en incluant le fichier /sys/kernel/security/apparmor/revision
(non disponible dans les conteneurs Docker malheureusement...).
Essayez-le simplement en appelant :
php -a # open php cli
include("/sys/kernel/security/apparmor/revision");
Apache2
Par défaut, Apache supporte 150 connexions simultanées, suivant https://ubiq.co/tech-blog/increase-max-connections-apache/ il est possible d'augmenter ce nombre jusqu'à 8000. Suivez cela 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.
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, utilisez la derniĂšre connexion pour brute-forcer des 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)
warning
Notez que dans l'exemple précédent, nous DoSons complÚtement d'autres clients !
Si le serveur Apache est amélioré et que nous pouvions abuser de 4000 connexions (à mi-chemin du nombre 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 mod 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/<php-version>/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 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 tĂ©lĂ©chargeait 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 Ă la plateforme en consommant toutes les connexions.
Donc, pour Ă©viter le DoS, supposons qu'un attaquant n'utilisera que 100 connexions en mĂȘme temps et que le temps de traitement maximum par php-fmp (request_terminate_timeout
) est 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 de : 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 brute-force. **** Supposant une vitesse de 300 req/s, le temps nécessaire pour exploiter cela 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 :
.png)
warning
Notez que pour déclencher le timeout, il suffirait d'inclure la page LFI vulnérable, afin qu'elle entre dans une boucle d'inclusion éternelle.
Nginx
Il semble qu'en par dĂ©faut, Nginx supporte 512 connexions parallĂšles en mĂȘme temps (et ce nombre peut ĂȘtre amĂ©liorĂ©).
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Soutenir HackTricks
- VĂ©rifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PRs au HackTricks et HackTricks Cloud dépÎts github.