LFI2RCE via Nginx temp files
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Вразлива конфігурація
Example from bierbaumer.net показав, що навіть наведений нижче one-liner достатній, коли PHP працює за nginx reverse proxy, який буферизує тіла запитів на диск:
<?php
$action = $_GET['action'] ?? 'read';
$path = $_GET['file'] ?? 'index.php';
$action === 'read' ? readfile($path) : include $path;
The nginx side typically keeps default temp paths such as /var/lib/nginx/body and /var/lib/nginx/fastcgi. When a request body or upstream response is larger than the in-memory buffer (≈8 KB by default), nginx transparently writes the data to a temp file, keeps the file descriptor open, and only unlinks the file name. Any PHP include that follows symbolic links (like /proc/<pid>/fd/<fd>) can still execute the unlinked contents, giving you RCE through LFI.
Чому тимчасові файли nginx придатні для зловживань
- Тіла запитів, що перевищують поріг буфера, скидаються до
client_body_temp_path(за замовчуванням/tmp/nginx/client-bodyабо/var/lib/nginx/body). - Ім’я файлу випадкове, але файловий дескриптор залишається доступним під
/proc/<nginx_pid>/fd/<fd>. Поки тіло запиту не завершено (або ви тримаєте TCP-потік відкритим), nginx тримає дескриптор відкритим, навіть якщо запис шляху було видалено. - PHP include/require розв’язує ті символьні посилання
/proc/.../fd/..., тож атакуючий з LFI може перескочити через procfs, щоб виконати буферизований тимчасовий файл навіть після того, як nginx його видалив.
Класичний робочий процес експлуатації (резюме)
- Перелічіть PID воркерів. Отримуйте
/proc/<pid>/cmdlineчерез LFI, доки не знайдете рядки на кшталтnginx: worker process. Кількість воркерів рідко перевищує кількість ядер CPU, тому достатньо сканувати нижню область PID. - Примусьте nginx створити тимчасовий файл. Надішліть дуже великі тіла POST/PUT (або проксовані відповіді), щоб nginx скинув їх у
/var/lib/nginx/body/XXXXXXXX. Переконайтеся, що бекенд ніколи не читає весь body — наприклад, утримуйте TCP-з’єднання відкритим під час завантаження, щоб nginx тримав дескриптор відкритим. - Зіставте дескриптори з файлами. Маючи список PID, згенеруйте ланцюжки обхідних шляхів, такі як
/proc/<pidA>/cwd/proc/<pidB>/root/proc/<pidC>/fd/<fd>, щоб обійти будь-яку нормалізаціюrealpath()перед тим, як PHP розв’яже кінцеву ціль/proc/<victim_pid>/fd/<interesting_fd>. Брутфорс дескрипторів у діапазоні 10–45 зазвичай достатній, оскільки nginx повторно використовує цей діапазон для тимчасових файлів тіла запитів. - Include для виконання. Коли ви потрапите на дескриптор, який досі вказує на буферизоване тіло, один виклик
includeабоrequireзапустить ваш payload — навіть якщо початкове ім’я файлу вже було unlinked. Якщо вам потрібно лише прочитати файл, використайтеreadfile()для витягання тимчасового вмісту замість його виконання.
Сучасні варіації (2024–2025)
Ingress controllers та service meshes тепер регулярно виставляють nginx інстанси з додатковою поверхнею атаки. CVE-2025-1974 (“IngressNightmare”) — хороший приклад того, як еволюціонує класичний трюк з тимчасовими файлами:
- Атакуючі засовують шкідливий shared object як тіло запиту. Оскільки body >8 KB, nginx буферизує його в
/tmp/nginx/client-body/cfg-<random>. Намірено обманюючи в заголовкуContent-Length(наприклад, вказуючи 1 MB і ніколи не відправляючи останній шматок), тимчасовий файл залишається прикріпленим приблизно на ~60 секунд. - Уразливий код шаблона ingress-nginx дозволяв інжектити директиви в згенерований nginx config. Поєднання цього з залишеним тимчасовим файлом дозволило брутфорсити посилання
/proc/<pid>/fd/<fd>доки атакуючий не виявить буферизований shared object. - Інжектування
ssl_engine /proc/<pid>/fd/<fd>;змусило nginx завантажити буферизований.so. Конструктори всередині shared object призвели до миттєвого RCE всередині ingress controller pod, що, в свою чергу, вивело Kubernetes secrets.
Обрізаний фрагмент розвідки для такого типу атаки виглядає так:
Швидкий сканер procfs
```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>
Run it from any primitive (command injection, template injection, etc.) you already have. Feed the discovered `/proc/<pid>/fd/<fd>` paths back into your LFI parameter to include the buffered payload.
## Практичні поради
* When nginx disables buffering (`proxy_request_buffering off`, `client_body_buffer_size` tuned high, or `proxy_max_temp_file_size 0`), the technique becomes much harder—so always enumerate config files and response headers to check whether buffering is still enabled.
* Hanging uploads are noisy but effective. Use multiple processes to flood workers so that at least one temp file stays around long enough for your LFI brute force to catch it.
* In Kubernetes or other orchestrators, privilege boundaries may look different, but the primitive is the same: find a way to drop bytes into nginx buffers, then walk `/proc` from anywhere you can issue file system reads.
## Лаби
- [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/)
## Посилання
- [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]
> Вивчайте та практикуйте 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;">\
> Вивчайте та практикуйте 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;">
> Вивчайте та практикуйте 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>Підтримайте HackTricks</summary>
>
> - Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
> - **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на github.
>
> </details>


