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 지원하기

취약한 구성

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가 삭제한 후에도 버퍼된 임시 파일을 실행할 수 있습니다.

클래식 익스플로잇 워크플로우 (요약)

  1. 워커 PID 열거. LFI로 /proc/<pid>/cmdline을 가져와 nginx: worker process 같은 문자열을 찾습니다. 워커 수는 보통 CPU 코어 수를 넘지 않으므로 낮은 PID 영역만 스캔하면 됩니다.
  2. nginx가 임시 파일을 생성하게 강제. 매우 큰 POST/PUT 본문(또는 프록시된 응답)을 보내 nginx가 /var/lib/nginx/body/XXXXXXXX로 스필하게 합니다. 백엔드가 전체 본문을 절대 읽지 않도록—예: 업로드 스레드를 keep-alive 상태로 유지해 nginx가 디스크립터를 열어두게 하세요.
  3. 디스크립터를 파일에 매핑. PID 목록으로 /proc/<pidA>/cwd/proc/<pidB>/root/proc/<pidC>/fd/<fd> 같은 트래버설 체인을 생성해 PHP가 최종 /proc/<victim_pid>/fd/<interesting_fd> 타깃을 해결하기 전에 realpath() 정규화를 우회하세요. nginx가 바디 임시 파일에 대해 대개 그 범위를 재사용하므로 파일 디스크립터 10–45를 브루트포스하면 보통 충분합니다.
  4. 실행을 위한 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 os

def 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>