LFI2RCE via Nginx 一時ファイル
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グループまたはテレグラムグループに参加するか、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 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 ストリームを保留にしている)限り、パスエントリが unlink されていても nginx はディスクリプタを開いたままにします。 - PHP の include/require はこれらの
/proc/.../fd/...シンボリックリンクを解決するため、LFI を持つ攻撃者は procfs を辿って nginx が削除した後でもバッファされた一時ファイルを実行できます。
クラシックな悪用ワークフロー(再掲)
- Enumerate worker PIDs. LFI 経由で
/proc/<pid>/cmdlineを取得し、nginx: worker processのような文字列を見つけるまで調べます。worker の数は通常 CPU 数を超えないため、PID の下位領域だけを走査すれば十分です。 - Force nginx to create the temp file. 非常に大きな POST/PUT ボディ(またはプロキシされたレスポンス)を送信して、nginx が
/var/lib/nginx/body/XXXXXXXXに溢れるようにします。バックエンドがボディ全体を読み取らないように—例えばアップロードスレッドを keep-alive にしておく—ことで、nginx はディスクリプタを開いたままにします。 - Map descriptors to files. PID リストを使い、
/proc/<pidA>/cwd/proc/<pidB>/root/proc/<pidC>/fd/<fd>のようなトラバーサルチェインを生成して、PHP が最終的に/proc/<victim_pid>/fd/<interesting_fd>を解決する前のrealpath()正規化を回避します。nginx はボディ用の一時ファイルに対して通常 10–45 の範囲のディスクリプタを再利用するため、10–45 のディスクリプタを総当たりするだけで十分なことが多いです。 - Include for execution. まだバッファされたボディを指すディスクリプタを見つけたら、単一の
includeまたはrequire呼び出しでペイロードが実行されます—元のファイル名がすでに unlink されていても。ファイル読み取りだけで十分な場合は、実行の代わりにreadfile()に切り替えて一時コンテンツを外部へ持ち出してください。
モダンなバリエーション (2024–2025)
Ingress controllers や service meshes は現在、追加の攻撃面を伴って nginx インスタンスを公開することが多くなっています。CVE-2025-1974 (“IngressNightmare”) は、クラシックな一時ファイルトリックがどのように進化するかの良い例です:
- 攻撃者は悪意のある共有オブジェクトをリクエストボディとしてプッシュします。ボディが >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>
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ハッキングを学び、実践する:<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)または[**テレグラムグループ**](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>


