Nginx ์์ ํ์ผ์ ํตํ LFI2RCE
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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
์ทจ์ฝํ ๊ตฌ์ฑ
Example from bierbaumer.net ๋ PHP๊ฐ nginx ์ญ๋ฐฉํฅ ํ๋ก์ ๋ค์์ ์คํ๋์ด ์์ฒญ ๋ณธ๋ฌธ์ ๋์คํฌ์ ๋ฒํผ๋งํ ๋ ๋ค์ ํ ์ค์ง๋ฆฌ ๋ช ๋ น์ด(one-liner)์กฐ์ฐจ๋ ์ถฉ๋ถํ๋ค๋ ๊ฒ์ ๋ณด์ฌ์ค๋๋ค:
<?php
$action = $_GET['action'] ?? 'read';
$path = $_GET['file'] ?? 'index.php';
$action === 'read' ? readfile($path) : include $path;
nginx ์ชฝ์ ์ผ๋ฐ์ ์ผ๋ก /var/lib/nginx/body ๋ฐ /var/lib/nginx/fastcgi ๊ฐ์ ๊ธฐ๋ณธ ์์ ๊ฒฝ๋ก๋ฅผ ์ ์งํฉ๋๋ค. ์์ฒญ ๋ณธ๋ฌธ์ด๋ upstream ์๋ต์ด ๋ฉ๋ชจ๋ฆฌ ๋ฒํผ(๊ธฐ๋ณธ โ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๊ฐ ์ญ์ ํ ํ์๋ ๋ฒํผ๋ ์์ ํ์ผ์ ์คํํ ์ ์์ต๋๋ค.
ํด๋์ ์ต์คํ๋ก์ ์ํฌํ๋ก์ฐ (์์ฝ)
- ์์ปค PID ์ด๊ฑฐ. LFI๋ก
/proc/<pid>/cmdline์ ๊ฐ์ ธ์nginx: worker process๊ฐ์ ๋ฌธ์์ด์ ์ฐพ์ต๋๋ค. ์์ปค ์๋ ๋ณดํต CPU ์ฝ์ด ์๋ฅผ ๋์ง ์์ผ๋ฏ๋ก ๋ฎ์ PID ์์ญ๋ง ์ค์บํ๋ฉด ๋ฉ๋๋ค. - nginx๊ฐ ์์ ํ์ผ์ ์์ฑํ๊ฒ ๊ฐ์ . ๋งค์ฐ ํฐ POST/PUT ๋ณธ๋ฌธ(๋๋ ํ๋ก์๋ ์๋ต)์ ๋ณด๋ด nginx๊ฐ
/var/lib/nginx/body/XXXXXXXX๋ก ์คํํ๊ฒ ํฉ๋๋ค. ๋ฐฑ์๋๊ฐ ์ ์ฒด ๋ณธ๋ฌธ์ ์ ๋ ์ฝ์ง ์๋๋กโ์: ์ ๋ก๋ ์ค๋ ๋๋ฅผ keep-alive ์ํ๋ก ์ ์งํด nginx๊ฐ ๋์คํฌ๋ฆฝํฐ๋ฅผ ์ด์ด๋๊ฒ ํ์ธ์. - ๋์คํฌ๋ฆฝํฐ๋ฅผ ํ์ผ์ ๋งคํ. PID ๋ชฉ๋ก์ผ๋ก
/proc/<pidA>/cwd/proc/<pidB>/root/proc/<pidC>/fd/<fd>๊ฐ์ ํธ๋๋ฒ์ค ์ฒด์ธ์ ์์ฑํด PHP๊ฐ ์ต์ข/proc/<victim_pid>/fd/<interesting_fd>ํ๊น์ ํด๊ฒฐํ๊ธฐ ์ ์realpath()์ ๊ทํ๋ฅผ ์ฐํํ์ธ์. nginx๊ฐ ๋ฐ๋ ์์ ํ์ผ์ ๋ํด ๋๊ฐ ๊ทธ ๋ฒ์๋ฅผ ์ฌ์ฌ์ฉํ๋ฏ๋ก ํ์ผ ๋์คํฌ๋ฆฝํฐ 10โ45๋ฅผ ๋ธ๋ฃจํธํฌ์คํ๋ฉด ๋ณดํต ์ถฉ๋ถํฉ๋๋ค. - ์คํ์ ์ํ include. ๋ฒํผ๋ ๋ฐ๋๋ฅผ ๊ฐ๋ฆฌํค๋ ๋์คํฌ๋ฆฝํฐ๋ฅผ ์ฐพ์ผ๋ฉด ๋จ ํ๋์
include๋๋requireํธ์ถ๋ก ํ์ด๋ก๋๊ฐ ์คํ๋ฉ๋๋ค โ ์๋ณธ ํ์ผ๋ช ์ ์ด๋ฏธ unlink ๋์ด ์์ด๋์. ๋จ์ํ ํ์ผ ์ฝ๊ธฐ๋ง ํ์ํ๋ค๋ฉด ์คํ ๋์readfile()๋ก ์์ ๋ด์ฉ์ ์ ์ถํ์ธ์.
์ต์ ๋ณํ (2024โ2025)
Ingress controllers์ service meshes๋ ์ด์ nginx ์ธ์คํด์ค๋ฅผ ์ถ๊ฐ์ ์ธ ๊ณต๊ฒฉ๋ฉด๊ณผ ํจ๊ป ๋ ธ์ถ์ํค๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. CVE-2025-1974 (โIngressNightmareโ)๋ ํด๋์ ์์ํ์ผ ํธ๋ฆญ์ด ์ด๋ป๊ฒ ์งํํ๋์ง ๋ณด์ฌ์ฃผ๋ ์ข์ ์์ ๋๋ค:
- ๊ณต๊ฒฉ์๋ ์
์ฑ shared object๋ฅผ ์์ฒญ ๋ณธ๋ฌธ์ผ๋ก ํธ์ํฉ๋๋ค. ๋ณธ๋ฌธ์ด >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 ๋ด๋ถ์ ์์ฑ์๋ค์ ingress controller pod ๋ด๋ถ์์ ์ฆ๊ฐ์ ์ธ RCE๋ฅผ ๋ฐ์์์ผฐ๊ณ , ์ด๋ Kubernetes ๋น๋ฐ์ ๋ ธ์ถ์์ผฐ์ต๋๋ค.
์ด ์คํ์ผ ๊ณต๊ฒฉ์ ์ํ ์ถ์ฝ๋ ์ ์ฐฐ ์ค๋ํซ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
๋น ๋ฅธ 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.
## ์ค์ ํ
* nginx๊ฐ ๋ฒํผ๋ง์ ๋นํ์ฑํํ ๋ (`proxy_request_buffering off`, `client_body_buffer_size`๋ฅผ ํฌ๊ฒ ์กฐ์ ํ๊ฑฐ๋ `proxy_max_temp_file_size 0`), ์ด ๊ธฐ๋ฒ์ ํจ์ฌ ์ด๋ ค์์ง๋๋ค โ ๋ฐ๋ผ์ ์ค์ ํ์ผ๊ณผ ์๋ต ํค๋๋ฅผ ํญ์ ์ด๊ฑฐํ์ฌ ๋ฒํผ๋ง์ด ์ฌ์ ํ ํ์ฑํ๋์ด ์๋์ง ํ์ธํ์ธ์.
* Hanging uploads๋ ์๋๋ฝ์ง๋ง ํจ๊ณผ์ ์
๋๋ค. ์ฌ๋ฌ ํ๋ก์ธ์ค๋ฅผ ์ฌ์ฉํด ์์ปค๋ฅผ ๊ณผ๋ถํ์์ผ ์ ์ด๋ ํ๋์ ์์ ํ์ผ์ด LFI brute force๊ฐ ํฌ์ฐฉํ ์ ์์ ๋งํผ ์ค๋ ๋จ์ ์๊ฒ ํ์ธ์.
* Kubernetes๋ ๋ค๋ฅธ orchestrator ํ๊ฒฝ์์๋ ๊ถํ ๊ฒฝ๊ณ๊ฐ ๋ค๋ฅด๊ฒ ๋ณด์ผ ์ ์์ง๋ง, primitive๋ ๊ฐ์ต๋๋ค: nginx ๋ฒํผ์ ๋ฐ์ดํธ๋ฅผ ๋ฃ์ ๋ฐฉ๋ฒ์ ์ฐพ๊ณ , ํ์ผ ์์คํ
์ฝ๊ธฐ๋ฅผ ์คํํ ์ ์๋ ์ด๋ ๊ณณ์์๋ `/proc`์ ํ์ํ์ธ์.
## ์ค์ต
- [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) ํ์ธํ๊ธฐ!
> - **๐ฌ [**๋์ค์ฝ๋ ๊ทธ๋ฃน**](https://discord.gg/hRep4RUj7f) ๋๋ [**ํ
๋ ๊ทธ๋จ ๊ทธ๋ฃน**](https://t.me/peass)์ ์ฐธ์ฌํ๊ฑฐ๋ **ํธ์ํฐ** ๐ฆ [**@hacktricks_live**](https://twitter.com/hacktricks_live)**๋ฅผ ํ๋ก์ฐํ์ธ์.**
> - **[**HackTricks**](https://github.com/carlospolop/hacktricks) ๋ฐ [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.**
>
> </details>


