LFI2RCE via Nginx temp files
Tip
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
易受攻击的配置
Example from bierbaumer.net 表明,当 PHP 在一个将请求体缓冲到磁盘的 nginx reverse proxy 后运行时,甚至下面这个单行命令就足够了:
<?php
$action = $_GET['action'] ?? 'read';
$path = $_GET['file'] ?? 'index.php';
$action === 'read' ? readfile($path) : include $path;
The nginx 一侧通常保留默认临时路径,例如 /var/lib/nginx/body 和 /var/lib/nginx/fastcgi。当请求体或上游响应大于内存缓冲区(≈8 KB 默认)时,nginx 会透明地将数据写入临时文件,保持文件描述符打开,但仅 unlink 掉文件名。任何跟随符号链接(例如 /proc/<pid>/fd/<fd>)的 PHP include 仍然可以执行已 unlink 的内容,从而通过 LFI 获得 RCE。
为什么 nginx 临时文件可被滥用
- 超出缓冲阈值的请求体会被刷新到
client_body_temp_path(默认是/tmp/nginx/client-body或/var/lib/nginx/body)。 - 文件名是随机的,但文件描述符仍可通过
/proc/<nginx_pid>/fd/<fd>访问。只要请求体未完成(或者你让 TCP 流保持悬挂),nginx 就会保持描述符打开,即便路径条目已被 unlink。 - PHP 的 include/require 会解析那些
/proc/.../fd/...符号链接,所以拥有 LFI 的攻击者可以通过 procfs 跳转来执行已缓冲的临时文件,即便 nginx 已经删除了原始文件名。
经典利用流程(回顾)
- 枚举 worker PID。 通过 LFI 抓取
/proc/<pid>/cmdline,直到找到像nginx: worker process的字符串。worker 数量很少超过 CPU 数量,所以只需扫描较低的 PID 空间即可。 - 迫使 nginx 创建临时文件。 发送非常大的 POST/PUT body(或通过代理的响应),使 nginx 将其溢写到
/var/lib/nginx/body/XXXXXXXX。确保后端不会读取完整的 body——例如让上传线程保持连接(keep TCP stream hanging),使 nginx 保持描述符打开。 - 将描述符映射到文件。 有了 PID 列表后,生成遍历链例如
/proc/<pidA>/cwd/proc/<pidB>/root/proc/<pidC>/fd/<fd>,以绕过任何在 PHP 解析最终/proc/<victim_pid>/fd/<interesting_fd>目标之前的realpath()规范化。对文件描述符 10–45 的暴力枚举通常已足够,因为 nginx 对 body temp files 会重用该范围。 - include 执行。 当你命中仍指向缓冲 body 的描述符时,单次
include或require调用就会运行你的 payload——即便原始文件名已被 unlink。如果你只需要读取文件内容,可以改用readfile()来外泄临时内容而不是执行它们。
现代变种(2024–2025)
Ingress 控制器和服务网格现在经常暴露带有额外攻击面向的 nginx 实例。CVE-2025-1974 (“IngressNightmare”) 就是经典临时文件技巧如何演化的一个例子:
- 攻击者将恶意共享对象作为请求体推送。由于 body > 8 KB,nginx 将其缓冲到
/tmp/nginx/client-body/cfg-<random>。通过在Content-Length头部故意造假(例如声明 1 MB,但从不发送最后那部分),临时文件会被固定约 ~60 秒。 - 易受攻击的 ingress-nginx 模板代码允许在生成的 nginx 配置中注入指令。将其与悬挂的临时文件结合,就可以暴力枚举
/proc/<pid>/fd/<fd>链接,直到攻击者发现缓冲的共享对象。 - 注入
ssl_engine /proc/<pid>/fd/<fd>;会强制 nginx 加载缓冲的.so。共享对象内的构造函数会立即在 ingress controller pod 内产生 RCE,进而暴露 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>
从你已经拥有的任何 primitive(command injection、template injection 等)上运行它。把发现的 `/proc/<pid>/fd/<fd>` 路径回传到你的 LFI 参数中,以包含缓冲的 payload。
## Practical tips
* 当 nginx 禁用缓冲(`proxy_request_buffering off`,`client_body_buffer_size` 调高,或 `proxy_max_temp_file_size 0`)时,该技术会变得更困难——因此请始终枚举配置文件和响应头以检查是否仍启用缓冲。
* 挂起的上传虽然会产生噪音但有效。使用多个进程淹没 workers,以便至少有一个临时文件能停留足够长时间让你的 LFI brute force 抓住它。
* 在 Kubernetes 或其他 orchestrators 中,特权边界可能看起来不同,但原理相同:找到将字节写入 nginx 缓冲区的方法,然后从任何可以执行文件系统读取的地方遍历 `/proc`。
## 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/)
## References
- [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 黑客技术:<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 黑客技术:<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 黑客技术:<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)**.**
> - **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub 仓库提交 PR 来分享黑客技巧。
>
> </details>
HackTricks

