LFI2RCE via fichiers temporaires de Nginx
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)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
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 PR au HackTricks et HackTricks Cloud dépÎts github.
Configuration vulnérable
Example from bierbaumer.net a montrĂ© que mĂȘme la ligne suivante suffit lorsque PHP sâexĂ©cute derriĂšre un reverse proxy nginx qui met en tampon les corps de requĂȘte sur le disque :
<?php
$action = $_GET['action'] ?? 'read';
$path = $_GET['file'] ?? 'index.php';
$action === 'read' ? readfile($path) : include $path;
Le cĂŽtĂ© nginx conserve gĂ©nĂ©ralement des chemins temporaires par dĂ©faut comme /var/lib/nginx/body et /var/lib/nginx/fastcgi. Quand un corps de requĂȘte ou une rĂ©ponse upstream dĂ©passe le tampon mĂ©moire (â8âŻKB par dĂ©faut), nginx Ă©crit transparemment les donnĂ©es dans un fichier temporaire, garde le descripteur de fichier ouvert et ne supprime que lâentrĂ©e du nom de fichier. Tout include PHP qui suit des liens symboliques (comme /proc/<pid>/fd/<fd>) peut toujours exĂ©cuter le contenu non liĂ©, vous donnant RCE via LFI.
Pourquoi les fichiers temporaires nginx sont exploitables
- Les corps de requĂȘte dĂ©passant le seuil du tampon sont vidĂ©s dans
client_body_temp_path(par défaut/tmp/nginx/client-bodyou/var/lib/nginx/body). - Le nom de fichier est aléatoire, mais le descripteur de fichier reste accessible sous
/proc/<nginx_pid>/fd/<fd>. Tant que le corps de la requĂȘte nâest pas complet (ou si vous maintenez le flux TCP en attente), nginx garde le descripteur ouvert mĂȘme si lâentrĂ©e de chemin a Ă©tĂ© supprimĂ©e. - Les include/require de PHP rĂ©solvent ces liens symboliques
/proc/.../fd/..., donc un attaquant disposant dâune LFI peut parcourir procfs pour exĂ©cuter le fichier temporaire bufferisĂ© mĂȘme aprĂšs que nginx lâait supprimĂ©.
Flux dâexploitation classique (rĂ©capitulatif)
- Enumérer les PIDs des workers. Récupérez
/proc/<pid>/cmdlinevia la LFI jusquâĂ trouver des chaĂźnes commenginx: worker process. Le nombre de workers dĂ©passe rarement le nombre de CPU, vous nâavez donc quâĂ scanner la plage basse des PIDs. - Forcer nginx Ă crĂ©er le fichier temporaire. Envoyez des corps POST/PUT trĂšs volumineux (ou des rĂ©ponses proxyĂ©es) afin que nginx Ă©crive dans
/var/lib/nginx/body/XXXXXXXX. Assurez-vous que le backend ne lit jamais tout le corps â p.ex. maintenez le thread dâupload en keep-alive pour que nginx garde le descripteur ouvert. - Mapper les descripteurs vers des fichiers. Avec la liste de PIDs, gĂ©nĂ©rez des chaĂźnes de traversal comme
/proc/<pidA>/cwd/proc/<pidB>/root/proc/<pidC>/fd/<fd>pour contourner toute normalisationrealpath()avant que PHP ne rĂ©solve la cible finale/proc/<victim_pid>/fd/<interesting_fd>. Le brute-force des descripteurs 10â45 suffit gĂ©nĂ©ralement car nginx rĂ©utilise cette plage pour les fichiers temporaires de body. - Inclure pour exĂ©cution. Quand vous touchez le descripteur qui pointe encore vers le body bufferisĂ©, un seul
includeourequireexĂ©cute votre payload â mĂȘme si le nom de fichier original a dĂ©jĂ Ă©tĂ© supprimĂ©. Si vous avez juste besoin de lire le fichier, utilisezreadfile()pour exfiltrer le contenu temporaire au lieu de lâexĂ©cuter.
Variations modernes (2024â2025)
Ingress controllers et service meshes exposent dĂ©sormais souvent des instances nginx avec une surface dâattaque accrue. CVE-2025-1974 (âIngressNightmareâ) est un bon exemple de lâĂ©volution du trick classique des fichiers temporaires :
- Les attaquants envoient un shared object malveillant comme corps de requĂȘte. Parce que le body >8âŻKB, nginx le bufferise dans
/tmp/nginx/client-body/cfg-<random>. En mentant intentionnellement dans lâen-tĂȘteContent-Length(p.ex. dĂ©clarer 1âŻMB et ne jamais envoyer le dernier chunk) le fichier temporaire reste fixĂ© pendant ~60âŻsecondes. - Le code de template vulnĂ©rable dâingress-nginx permettait dâinjecter des directives dans la config nginx gĂ©nĂ©rĂ©e. Combiner cela avec le fichier temporaire persistant rendait possible le brute-force des liens
/proc/<pid>/fd/<fd>jusquâĂ ce que lâattaquant dĂ©couvre le shared object bufferisĂ©. - Lâinjection de
ssl_engine /proc/<pid>/fd/<fd>;forçait nginx Ă charger le.sobufferisĂ©. Les constructeurs Ă lâintĂ©rieur du shared object ont donnĂ© une RCE immĂ©diate dans le pod de lâingress controller, qui a ensuite exposĂ© des secrets Kubernetes.
Un snippet de reconnaissance rĂ©duit pour ce type dâattaque ressemble Ă :
Scanner procfs rapide
```python #!/usr/bin/env python3 import osdef find_tempfds(pid_range=range(100, 4000), fd_range=range(10, 80)): for pid in pid_range: fd_dir = fâ/proc/{pid}/fdâ if not os.path.isdir(fd_dir): continue for fd in fd_range: try: path = os.readlink(fâ{fd_dir}/{fd}â) if âclient-bodyâ in path or ânginxâ in path: yield pid, fd, path except OSError: continue
for pid, fd, path in find_tempfds(): print(fâuse ?file=/proc/{pid}/fd/{fd} # {path}â)
</details>
Exécutez-le depuis n'importe quel primitive (command injection, template injection, etc.) que vous possédez déjà . Renvoyez les chemins découverts `/proc/<pid>/fd/<fd>` dans votre paramÚtre LFI pour inclure le payload tamponné.
## Conseils pratiques
* Quand nginx dĂ©sactive le buffering (`proxy_request_buffering off`, `client_body_buffer_size` rĂ©glĂ© haut, ou `proxy_max_temp_file_size 0`), la technique devient beaucoup plus difficile â donc Ă©numĂ©rez toujours les fichiers de config et les en-tĂȘtes de rĂ©ponse pour vĂ©rifier si le buffering est encore activĂ©.
* Les hanging uploads sont bruyants mais efficaces. Utilisez plusieurs processes pour inonder les workers afin qu'au moins un temp file reste présent assez longtemps pour que votre LFI brute force le récupÚre.
* Dans Kubernetes ou d'autres orchestrators, les frontiĂšres de privilĂšges peuvent sembler diffĂ©rentes, mais le principe est le mĂȘme : trouvez un moyen de dĂ©poser des bytes dans les nginx buffers, puis parcourez `/proc` depuis n'importe oĂč oĂč vous pouvez effectuer des lectures sur le systĂšme de fichiers.
## Labs
- [https://bierbaumer.net/security/php-lfi-with-nginx-assistance/php-lfi-with-nginx-assistance.tar.xz](https://bierbaumer.net/security/php-lfi-with-nginx-assistance/php-lfi-with-nginx-assistance.tar.xz)
- [https://2021.ctf.link/internal/challenge/ed0208cd-f91a-4260-912f-97733e8990fd/](https://2021.ctf.link/internal/challenge/ed0208cd-f91a-4260-912f-97733e8990fd/)
- [https://2021.ctf.link/internal/challenge/a67e2921-e09a-4bfa-8e7e-11c51ac5ee32/](https://2021.ctf.link/internal/challenge/a67e2921-e09a-4bfa-8e7e-11c51ac5ee32/)
## Références
- [https://bierbaumer.net/security/php-lfi-with-nginx-assistance/](https://bierbaumer.net/security/php-lfi-with-nginx-assistance/)
- [https://www.opswat.com/blog/ingressnightmare-cve-2025-1974-remote-code-execution-vulnerability-remediation](https://www.opswat.com/blog/ingressnightmare-cve-2025-1974-remote-code-execution-vulnerability-remediation)
> [!TIP]
> Apprenez et pratiquez le hacking AWS :<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Apprenez et pratiquez le hacking GCP : <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
> Apprenez et pratiquez le hacking Azure : <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>Soutenir HackTricks</summary>
>
> - Vérifiez 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 PR au** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépÎts github.
>
> </details>


