LFI2RCE via Nginx temp files
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Verwundbare Konfiguration
Example from bierbaumer.net zeigte, dass bereits der folgende Einzeiler ausreicht, wenn PHP hinter einem nginx reverse proxy läuft, der request bodies auf die Festplatte puffert:
<?php
$action = $_GET['action'] ?? 'read';
$path = $_GET['file'] ?? 'index.php';
$action === 'read' ? readfile($path) : include $path;
Die nginx-Seite verwendet typischerweise Standard-Temp-Pfade wie /var/lib/nginx/body und /var/lib/nginx/fastcgi. Wenn ein Request-Body oder eine Upstream-Antwort größer ist als der In-Memory-Buffer (≈8 KB standardmäßig), schreibt nginx die Daten transparent in eine Temp-Datei, hält den File-Descriptor offen und unlinkt nur den Dateinamen. Jedes PHP include, das symbolische Links auflöst (wie /proc/<pid>/fd/<fd>), kann die unlinked Inhalte weiterhin ausführen und ermöglicht so RCE über LFI.
Why nginx temp files are abusable
- Request bodies, die den Buffer-Schwellenwert überschreiten, werden in
client_body_temp_pathgespült (Standard ist/tmp/nginx/client-bodyoder/var/lib/nginx/body). - Der Dateiname ist zufällig, aber der File-Descriptor bleibt unter
/proc/<nginx_pid>/fd/<fd>erreichbar. Solange der Request-Body nicht vollständig ist (oder Sie den TCP-Stream offen halten), behält nginx den Descriptor offen, obwohl der Pfadeintrag unlinkt wurde. - PHPs include/require löst diese
/proc/.../fd/...-Symlinks auf, sodass ein Angreifer mit LFI über procfs springen kann, um die gepufferten Temp-Dateien auszuführen, selbst nachdem nginx sie gelöscht hat.
Classic exploitation workflow (recap)
- Enumerate worker PIDs. Hole
/proc/<pid>/cmdlineüber das LFI, bis du Strings wienginx: worker processfindest. Die Anzahl der Worker überschreitet selten die CPU-Anzahl, daher reicht es, im niedrigeren PID-Bereich zu scannen. - Force nginx to create the temp file. Sende sehr große POST/PUT-Bodies (oder proxied responses), sodass nginx auf
/var/lib/nginx/body/XXXXXXXXauslagert. Sorge dafür, dass das Backend den gesamten Body nie liest — z. B. den Upload-Thread keep-alive lassen, damit nginx den Descriptor offenhält. - Map descriptors to files. Mit der PID-Liste generiere Traversal-Ketten wie
/proc/<pidA>/cwd/proc/<pidB>/root/proc/<pidC>/fd/<fd>, um eine möglicherealpath()-Normalisierung zu umgehen, bevor PHP das finale/proc/<victim_pid>/fd/<interesting_fd>-Ziel auflöst. Das Brute-Forcen von File-Deskriptoren 10–45 reicht normalerweise aus, da nginx diesen Bereich für body temp files wiederverwendet. - Include for execution. Wenn du auf den Descriptor triffst, der noch auf den gepufferten Body zeigt, führt ein einzelnes
includeoderrequiredein Payload aus — obwohl der ursprüngliche Dateiname bereits unlinkt wurde. Wenn du nur Dateiinhalt lesen musst, wechsle zureadfile()zum Exfiltrieren der temporären Inhalte statt sie auszuführen.
Modern variations (2024–2025)
Ingress controllers und service meshes exposen inzwischen routinemäßig nginx-Instanzen mit zusätzlicher Angriffsfläche. CVE-2025-1974 (“IngressNightmare”) ist ein gutes Beispiel dafür, wie sich der klassische Temp-File-Trick weiterentwickelt:
- Angreifer pushen ein bösartiges shared object als Request-Body. Weil der Body >8 KB ist, puffert nginx ihn nach
/tmp/nginx/client-body/cfg-<random>. Durch absichtliches Falschangaben imContent-Length-Header (z. B. 1 MB behaupten und den letzten Chunk nie senden) bleibt die Temp-Datei für ~60 Sekunden gepinnt. - Der verwundbare ingress-nginx-Template-Code erlaubte das Injizieren von Direktiven in die generierte nginx-Konfiguration. In Kombination mit der lingernden Temp-Datei war es möglich,
/proc/<pid>/fd/<fd>-Links zu brute-forcen, bis das gepufferte shared object gefunden wurde. - Das Injizieren von
ssl_engine /proc/<pid>/fd/<fd>;zwang nginx dazu, das gepufferte.sozu laden. Konstruktoren innerhalb des shared objects lieferten sofortige RCE innerhalb des ingress controller pods, was wiederum Kubernetes-Secrets offenlegte.
A trimmed-down reconnaissance snippet for this style of attack looks like:
Quick procfs scanner
```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>
Führe es von einem beliebigen bereits vorhandenen Primitive (command injection, template injection, etc.) aus. Speise die entdeckten `/proc/<pid>/fd/<fd>`-Pfade zurück in deinen LFI-Parameter, um die gepufferte Nutzlast einzuschließen.
## Praktische Tipps
* Wenn nginx Buffering deaktiviert (`proxy_request_buffering off`, `client_body_buffer_size` auf hohe Werte gesetzt, oder `proxy_max_temp_file_size 0`), wird die Technik deutlich schwieriger — daher immer Konfigurationsdateien und Response-Header enumerieren, um zu prüfen, ob Buffering noch aktiviert ist.
* Hanging uploads sind auffällig, aber effektiv. Verwende mehrere Prozesse, um die Worker zu überfluten, sodass mindestens eine Temp-Datei lange genug erhalten bleibt, damit dein LFI brute force sie erwischen kann.
* In Kubernetes oder anderen Orchestratoren können sich Privilegiengrenzen anders darstellen, aber das Primitive ist dasselbe: finde einen Weg, Bytes in die nginx-Puffer zu schreiben, und durchlaufe dann `/proc` von jedem Ort aus, an dem du Dateisystem-Lesezugriff hast.
## 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/)
## Referenzen
- [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]
> Lernen & üben Sie AWS Hacking:<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;">\
> Lernen & üben Sie GCP Hacking: <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;">
> Lernen & üben Sie Azure Hacking: <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>Unterstützen Sie HackTricks</summary>
>
> - Überprüfen Sie die [**Abonnementpläne**](https://github.com/sponsors/carlospolop)!
> - **Treten Sie der** 💬 [**Discord-Gruppe**](https://discord.gg/hRep4RUj7f) oder der [**Telegram-Gruppe**](https://t.me/peass) bei oder **folgen** Sie uns auf **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Teilen Sie Hacking-Tricks, indem Sie PRs an die** [**HackTricks**](https://github.com/carlospolop/hacktricks) und [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub-Repos senden.
>
> </details>
HackTricks

