# Nginx {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** πŸ’¬ [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %}
**μ¦‰μ‹œ μ‚¬μš© κ°€λŠ₯ν•œ 취약점 평가 및 침투 ν…ŒμŠ€νŠΈ μ„€μ •**. 20개 μ΄μƒμ˜ 도ꡬ 및 κΈ°λŠ₯을 μ‚¬μš©ν•˜μ—¬ μ–΄λ””μ„œλ‚˜ 전체 침투 ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•˜μ„Έμš”. μš°λ¦¬λŠ” 침투 ν…ŒμŠ€ν„°λ₯Ό λŒ€μ²΄ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ - μš°λ¦¬λŠ” 그듀이 더 깊이 νŒŒκ³ λ“€κ³ , μ‰˜μ„ ν„°λœ¨λ¦¬κ³ , 재미λ₯Ό λŠλ‚„ 수 μžˆλ„λ‘ λ§žμΆ€ν˜• 도ꡬ, 탐지 및 μ•…μš© λͺ¨λ“ˆμ„ κ°œλ°œν•©λ‹ˆλ‹€. {% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %} ## Missing root location Nginx μ„œλ²„λ₯Ό ꡬ성할 λ•Œ, **root μ§€μ‹œμ–΄**λŠ” 파일이 μ œκ³΅λ˜λŠ” κΈ°λ³Έ 디렉토리λ₯Ό μ •μ˜ν•¨μœΌλ‘œμ¨ μ€‘μš”ν•œ 역할을 ν•©λ‹ˆλ‹€. μ•„λž˜ 예λ₯Ό κ³ λ €ν•˜μ„Έμš”: ```bash server { root /etc/nginx; location /hello.txt { try_files $uri $uri/ =404; proxy_pass http://127.0.0.1:8080/; } } ``` 이 κ΅¬μ„±μ—μ„œ `/etc/nginx`λŠ” 루트 λ””λ ‰ν† λ¦¬λ‘œ μ§€μ •λ©λ‹ˆλ‹€. 이 섀정은 `/hello.txt`와 같은 μ§€μ •λœ 루트 디렉토리 λ‚΄μ˜ νŒŒμΌμ— λŒ€ν•œ 접근을 ν—ˆμš©ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ νŠΉμ • μœ„μΉ˜(`location /hello.txt`)만 μ •μ˜λ˜μ–΄ μžˆλ‹€λŠ” 점이 μ€‘μš”ν•©λ‹ˆλ‹€. 루트 μœ„μΉ˜(`location / {...}`)에 λŒ€ν•œ ꡬ성은 μ—†μŠ΅λ‹ˆλ‹€. 이 λˆ„λ½μ€ 루트 μ§€μ‹œμ–΄κ°€ μ „μ—­μ μœΌλ‘œ μ μš©λ˜μ–΄, 루트 경둜 `/`에 λŒ€ν•œ μš”μ²­μ΄ `/etc/nginx` μ•„λž˜μ˜ νŒŒμΌμ— μ ‘κ·Όν•  수 있게 ν•©λ‹ˆλ‹€. 이 κ΅¬μ„±μ—μ„œ μ€‘μš”ν•œ λ³΄μ•ˆ κ³ λ € 사항이 λ°œμƒν•©λ‹ˆλ‹€. `GET /nginx.conf`와 같은 κ°„λ‹¨ν•œ `GET` μš”μ²­μ€ `/etc/nginx/nginx.conf`에 μœ„μΉ˜ν•œ Nginx ꡬ성 νŒŒμΌμ„ μ œκ³΅ν•¨μœΌλ‘œμ¨ λ―Όκ°ν•œ 정보λ₯Ό λ…ΈμΆœν•  수 μžˆμŠ΅λ‹ˆλ‹€. 루트λ₯Ό `/etc`와 같은 덜 λ―Όκ°ν•œ λ””λ ‰ν† λ¦¬λ‘œ μ„€μ •ν•˜λ©΄ 이 μœ„ν—˜μ„ μ™„ν™”ν•  수 μžˆμ§€λ§Œ, μ—¬μ „νžˆ λ‹€λ₯Έ ꡬ성 파일, μ ‘κ·Ό 둜그 및 HTTP κΈ°λ³Έ 인증에 μ‚¬μš©λ˜λŠ” μ•”ν˜Έν™”λœ 자격 증λͺ…κ³Ό 같은 λ‹€λ₯Έ μ€‘μš”ν•œ νŒŒμΌμ— λŒ€ν•œ μ˜λ„μΉ˜ μ•Šμ€ 접근을 ν—ˆμš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. ## Alias LFI Misconfiguration Nginx의 ꡬ성 νŒŒμΌμ—μ„œλŠ” "location" μ§€μ‹œμ–΄μ— λŒ€ν•œ λ©΄λ°€ν•œ κ²€ν† κ°€ ν•„μš”ν•©λ‹ˆλ‹€. Local File Inclusion (LFI)둜 μ•Œλ €μ§„ 취약점은 λ‹€μŒκ³Ό μœ μ‚¬ν•œ ꡬ성을 톡해 μš°μ—°νžˆ λ„μž…λ  수 μžˆμŠ΅λ‹ˆλ‹€: ``` location /imgs { alias /path/images/; } ``` 이 ꡬ성은 μ„œλ²„κ°€ `/imgs../flag.txt`와 같은 μš”μ²­μ„ μ˜λ„λœ 디렉토리 μ™ΈλΆ€μ˜ νŒŒμΌμ— μ ‘κ·Όν•˜λ €λŠ” μ‹œλ„λ‘œ ν•΄μ„ν•˜κΈ° λ•Œλ¬Έμ— LFI 곡격에 μ·¨μ•½ν•©λ‹ˆλ‹€. μ΄λŠ” μ‹€μ œλ‘œ `/path/images/../flag.txt`둜 ν•΄κ²°λ©λ‹ˆλ‹€. 이 결함은 κ³΅κ²©μžκ°€ 웹을 톡해 μ ‘κ·Όν•  수 μ—†μ–΄μ•Ό ν•˜λŠ” μ„œλ²„μ˜ 파일 μ‹œμŠ€ν…œμ—μ„œ νŒŒμΌμ„ 검색할 수 있게 ν•©λ‹ˆλ‹€. 이 취약점을 μ™„ν™”ν•˜κΈ° μœ„ν•΄ ꡬ성은 λ‹€μŒκ³Ό 같이 μ‘°μ •λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€: ``` location /imgs/ { alias /path/images/; } ``` 더 λ§Žμ€ 정보: [https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/](https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/) Accunetix ν…ŒμŠ€νŠΈ: ``` alias../ => HTTP status code 403 alias.../ => HTTP status code 404 alias../../ => HTTP status code 403 alias../../../../../../../../../../../ => HTTP status code 400 alias../ => HTTP status code 403 ``` ## μ•ˆμ „ν•˜μ§€ μ•Šμ€ 경둜 μ œν•œ λ‹€μŒ νŽ˜μ΄μ§€λ₯Ό ν™•μΈν•˜μ—¬ λ‹€μŒκ³Ό 같은 μ§€μ‹œλ¬Έμ„ μš°νšŒν•˜λŠ” 방법을 μ•Œμ•„λ³΄μ„Έμš”: ```plaintext location = /admin { deny all; } location = /admin/ { deny all; } ``` {% content-ref url="../../pentesting-web/proxy-waf-protections-bypass.md" %} [proxy-waf-protections-bypass.md](../../pentesting-web/proxy-waf-protections-bypass.md) {% endcontent-ref %} ## μ•ˆμ „ν•˜μ§€ μ•Šμ€ λ³€μˆ˜ μ‚¬μš© / HTTP μš”μ²­ λΆ„ν•  {% hint style="danger" %} μ·¨μ•½ν•œ λ³€μˆ˜ `$uri`와 `$document_uri`κ°€ 있으며, 이λ₯Ό `$request_uri`둜 κ΅μ²΄ν•˜μ—¬ μˆ˜μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ •κ·œ ν‘œν˜„μ‹λ„ μ·¨μ•½ν•  수 μžˆμŠ΅λ‹ˆλ‹€: `location ~ /docs/([^/])? { … $1 … }` - 취약함 `location ~ /docs/([^/\s])? { … $1 … }` - μ·¨μ•½ν•˜μ§€ μ•ŠμŒ (곡간 확인) `location ~ /docs/(.*)? { … $1 … }` - μ·¨μ•½ν•˜μ§€ μ•ŠμŒ {% endhint %} Nginx κ΅¬μ„±μ˜ 취약점은 μ•„λž˜ 예제둜 μ„€λͺ…λ©λ‹ˆλ‹€: ``` location / { return 302 https://example.com$uri; } ``` HTTP μš”μ²­μ—μ„œ \r (캐리지 리턴) 및 \n (라인 ν”Όλ“œ) λ¬ΈμžλŠ” μƒˆ 쀄 문자λ₯Ό λ‚˜νƒ€λ‚΄λ©°, μ΄λ“€μ˜ URL 인코딩 ν˜•νƒœλŠ” `%0d%0a`둜 ν‘œν˜„λ©λ‹ˆλ‹€. 잘λͺ» κ΅¬μ„±λœ μ„œλ²„μ— μ΄λŸ¬ν•œ 문자λ₯Ό ν¬ν•¨ν•œ μš”μ²­(예: `http://localhost/%0d%0aDetectify:%20clrf`)을 보내면 μ„œλ²„λŠ” `Detectify`λΌλŠ” μƒˆ 헀더λ₯Ό λ°œκΈ‰ν•©λ‹ˆλ‹€. μ΄λŠ” $uri λ³€μˆ˜κ°€ URL μΈμ½”λ”©λœ μƒˆ 쀄 문자λ₯Ό λ””μ½”λ”©ν•˜μ—¬ 응닡에 μ˜ˆμƒμΉ˜ λͺ»ν•œ 헀더가 ν¬ν•¨λ˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€: ``` HTTP/1.1 302 Moved Temporarily Server: nginx/1.19.3 Content-Type: text/html Content-Length: 145 Connection: keep-alive Location: https://example.com/ Detectify: clrf ``` CRLF μ£Όμž… 및 응닡 λΆ„ν• μ˜ μœ„ν—˜μ— λŒ€ν•΄ 더 μ•Œμ•„λ³΄λ €λ©΄ [https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/](https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/)λ₯Ό λ°©λ¬Έν•˜μ„Έμš”. λ˜ν•œ 이 κΈ°μˆ μ€ [**이 κ°•μ—°μ—μ„œ μ„€λͺ…λ©λ‹ˆλ‹€**](https://www.youtube.com/watch?v=gWQyWdZbdoY\&list=PL0xCSYnG\_iTtJe2V6PQqamBF73n7-f1Nr\&index=77) μ·¨μ•½ν•œ μ˜ˆμ œμ™€ 탐지 λ©”μ»€λ‹ˆμ¦˜κ³Ό ν•¨κ»˜. 예λ₯Ό λ“€μ–΄, λΈ”λž™λ°•μŠ€ κ΄€μ μ—μ„œ 이 잘λͺ»λœ ꡬ성을 νƒμ§€ν•˜κΈ° μœ„ν•΄ λ‹€μŒ μš”μ²­μ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€: * `https://example.com/%20X` - λͺ¨λ“  HTTP μ½”λ“œ * `https://example.com/%20H` - 400 잘λͺ»λœ μš”μ²­ μ·¨μ•½ν•œ 경우, 첫 λ²ˆμ§ΈλŠ” "X"κ°€ λͺ¨λ“  HTTP λ©”μ„œλ“œμ΄λ―€λ‘œ λ°˜ν™˜λ˜κ³ , 두 λ²ˆμ§ΈλŠ” Hκ°€ μœ νš¨ν•œ λ©”μ„œλ“œκ°€ μ•„λ‹ˆλ―€λ‘œ 였λ₯˜κ°€ λ°˜ν™˜λ©λ‹ˆλ‹€. λ”°λΌμ„œ μ„œλ²„λŠ” `GET / H HTTP/1.1`κ³Ό 같은 것을 μˆ˜μ‹ ν•˜κ²Œ 되고, μ΄λŠ” 였λ₯˜λ₯Ό μœ λ°œν•©λ‹ˆλ‹€. 또 λ‹€λ₯Έ 탐지 μ˜ˆλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€: * `http://company.tld/%20HTTP/1.1%0D%0AXXXX:%20x` - λͺ¨λ“  HTTP μ½”λ“œ * `http://company.tld/%20HTTP/1.1%0D%0AHost:%20x` - 400 잘λͺ»λœ μš”μ²­ κ·Έ κ°•μ—°μ—μ„œ 발견된 μ·¨μ•½ν•œ ꡬ성 쀑 μΌλΆ€λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€: * μ΅œμ’… URLμ—μ„œ **`$uri`**κ°€ κ·ΈλŒ€λ‘œ μ„€μ •λœ 방법을 μ£Όλͺ©ν•˜μ„Έμš”. ``` location ^~ /lite/api/ { proxy_pass http://lite-backend$uri$is_args$args; } ``` * λ‹€μ‹œ **`$uri`**κ°€ URL에 μžˆλŠ” 것을 μ£Όλͺ©ν•˜μ„Έμš” (μ΄λ²ˆμ—λŠ” λ§€κ°œλ³€μˆ˜ μ•ˆμ— μžˆμŠ΅λ‹ˆλ‹€) ``` location ~ ^/dna/payment { rewrite ^/dna/([^/]+) /registered/main.pl?cmd=unifiedPayment&context=$1&native_uri=$uri break; proxy_pass http://$back; ``` * 이제 AWS S3μ—μ„œ ``` location /s3/ { proxy_pass https://company-bucket.s3.amazonaws.com$uri; } ``` ### Any variable **μ‚¬μš©μž 제곡 데이터**κ°€ νŠΉμ • μƒν™©μ—μ„œ **Nginx λ³€μˆ˜**둜 처리될 수 있음이 λ°œκ²¬λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 이 ν–‰λ™μ˜ 원인은 λ‹€μ†Œ λΆˆλΆ„λͺ…ν•˜μ§€λ§Œ, λ“œλ¬Όμ§€ μ•ŠμœΌλ©° κ²€μ¦ν•˜κΈ°λ„ κ°„λ‹¨ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 이 이상 ν˜„μƒμ€ HackerOne의 λ³΄μ•ˆ λ³΄κ³ μ„œμ—μ„œ κ°•μ‘°λ˜μ—ˆμœΌλ©°, [μ—¬κΈ°](https://hackerone.com/reports/370094)μ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. 였λ₯˜ λ©”μ‹œμ§€μ— λŒ€ν•œ μΆ”κ°€ μ‘°μ‚¬λŠ” [Nginx μ½”λ“œλ² μ΄μŠ€μ˜ SSI ν•„ν„° λͺ¨λ“ˆ](https://github.com/nginx/nginx/blob/2187586207e1465d289ae64cedc829719a048a39/src/http/modules/ngx_http_ssi_filter_module.c#L365) λ‚΄μ—μ„œ λ°œμƒν•˜λŠ” 것을 ν™•μΈν•˜μ˜€μœΌλ©°, μ„œλ²„ μ‚¬μ΄λ“œ 포함(SSI)이 κ·Όλ³Έ μ›μΈμœΌλ‘œ 지λͺ©λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 이 **잘λͺ»λœ ꡬ성**을 **탐지**ν•˜κΈ° μœ„ν•΄, λ‹€μŒ λͺ…령을 μ‹€ν–‰ν•  수 있으며, μ΄λŠ” λ³€μˆ˜ 좜λ ₯을 ν…ŒμŠ€νŠΈν•˜κΈ° μœ„ν•΄ referer 헀더λ₯Ό μ„€μ •ν•˜λŠ” 것을 ν¬ν•¨ν•©λ‹ˆλ‹€: ```bash $ curl -H β€˜Referer: bar’ http://localhost/foo$http_referer | grep β€˜foobar’ ``` 이 잘λͺ»λœ ꡬ성에 λŒ€ν•œ μŠ€μΊ” κ²°κ³Ό, μ‚¬μš©μžκ°€ Nginx λ³€μˆ˜λ₯Ό 좜λ ₯ν•  수 μžˆλŠ” μ—¬λŸ¬ μΈμŠ€ν„΄μŠ€κ°€ λ°œκ²¬λ˜μ—ˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μ·¨μ•½ν•œ μΈμŠ€ν„΄μŠ€μ˜ μˆ˜κ°€ κ°μ†Œν•œ 것은 이 문제λ₯Ό νŒ¨μΉ˜ν•˜κΈ° μœ„ν•œ λ…Έλ ₯이 μ–΄λŠ 정도 μ„±κ³΅μ μ΄μ—ˆλ‹€λŠ” 것을 μ‹œμ‚¬ν•©λ‹ˆλ‹€. ## μ›μ‹œ λ°±μ—”λ“œ 응닡 읽기 NginxλŠ” `proxy_pass`λ₯Ό 톡해 λ°±μ—”λ“œμ—μ„œ μƒμ„±λœ 였λ₯˜ 및 HTTP 헀더λ₯Ό κ°€λ‘œμ±„λŠ” κΈ°λŠ₯을 μ œκ³΅ν•˜μ—¬ λ‚΄λΆ€ 였λ₯˜ λ©”μ‹œμ§€μ™€ 헀더λ₯Ό μˆ¨κΈ°λ„λ‘ μ„€κ³„λ˜μ—ˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” Nginxκ°€ λ°±μ—”λ“œ 였λ₯˜μ— λŒ€ν•œ μ‚¬μš©μž μ •μ˜ 였λ₯˜ νŽ˜μ΄μ§€λ₯Ό μ œκ³΅ν•¨μœΌλ‘œμ¨ μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ Nginxκ°€ 잘λͺ»λœ HTTP μš”μ²­μ„ μ²˜λ¦¬ν•  λ•Œ λ¬Έμ œκ°€ λ°œμƒν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ μš”μ²­μ€ μˆ˜μ‹ λœ λŒ€λ‘œ λ°±μ—”λ“œλ‘œ μ „λ‹¬λ˜λ©°, λ°±μ—”λ“œμ˜ μ›μ‹œ 응닡은 Nginx의 κ°œμž… 없이 ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ 직접 μ „μ†‘λ©λ‹ˆλ‹€. uWSGI μ• ν”Œλ¦¬μΌ€μ΄μ…˜κ³Ό κ΄€λ ¨λœ μ˜ˆμ‹œ μ‹œλ‚˜λ¦¬μ˜€λ₯Ό κ³ λ €ν•΄ λ³΄μ‹­μ‹œμ˜€: ```python def application(environ, start_response): start_response('500 Error', [('Content-Type', 'text/html'), ('Secret-Header', 'secret-info')]) return [b"Secret info, should not be visible!"] ``` 이λ₯Ό κ΄€λ¦¬ν•˜κΈ° μœ„ν•΄ Nginx κ΅¬μ„±μ—μ„œ νŠΉμ • μ§€μ‹œμ–΄κ°€ μ‚¬μš©λ©λ‹ˆλ‹€: ``` http { error_page 500 /html/error.html; proxy_intercept_errors on; proxy_hide_header Secret-Header; } ``` * [**proxy\_intercept\_errors**](http://nginx.org/en/docs/http/ngx\_http\_proxy\_module.html#proxy\_intercept\_errors): 이 μ§€μ‹œμ–΄λŠ” Nginxκ°€ μƒνƒœ μ½”λ“œκ°€ 300보닀 큰 λ°±μ—”λ“œ 응닡에 λŒ€ν•΄ μ‚¬μš©μž μ •μ˜ 응닡을 μ œκ³΅ν•  수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€. μ΄λŠ” μ˜ˆμ‹œλ‘œ λ“  uWSGI μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 경우 `500 Error` 응닡이 Nginx에 μ˜ν•΄ κ°€λ‘œμ±„μ§€κ³  μ²˜λ¦¬λ˜λ„λ‘ 보μž₯ν•©λ‹ˆλ‹€. * [**proxy\_hide\_header**](http://nginx.org/en/docs/http/ngx\_http\_proxy\_module.html#proxy\_hide\_header): μ΄λ¦„μ—μ„œ μ•Œ 수 μžˆλ“―μ΄, 이 μ§€μ‹œμ–΄λŠ” ν΄λΌμ΄μ–ΈνŠΈλ‘œλΆ€ν„° μ§€μ •λœ HTTP 헀더λ₯Ό 숨겨 개인 정보 보호 및 λ³΄μ•ˆμ„ κ°•ν™”ν•©λ‹ˆλ‹€. μœ νš¨ν•œ `GET` μš”μ²­μ΄ 이루어지면 NginxλŠ” 이λ₯Ό μ •μƒμ μœΌλ‘œ μ²˜λ¦¬ν•˜μ—¬ λΉ„λ°€ 헀더λ₯Ό λ…ΈμΆœν•˜μ§€ μ•Šκ³  ν‘œμ€€ 였λ₯˜ 응닡을 λ°˜ν™˜ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μœ νš¨ν•˜μ§€ μ•Šμ€ HTTP μš”μ²­μ€ 이 λ©”μ»€λ‹ˆμ¦˜μ„ μš°νšŒν•˜μ—¬ λΉ„λ°€ 헀더와 였λ₯˜ λ©”μ‹œμ§€λ₯Ό ν¬ν•¨ν•œ μ›μ‹œ λ°±μ—”λ“œ 응닡이 λ…ΈμΆœλ©λ‹ˆλ‹€. ## merge\_slashesλ₯Ό off둜 μ„€μ • 기본적으둜 Nginx의 **`merge_slashes` μ§€μ‹œμ–΄**λŠ” **`on`**으둜 μ„€μ •λ˜μ–΄ μžˆμ–΄ URL의 μ—¬λŸ¬ 개의 μŠ¬λž˜μ‹œλ₯Ό ν•˜λ‚˜μ˜ μŠ¬λž˜μ‹œλ‘œ μ••μΆ•ν•©λ‹ˆλ‹€. 이 κΈ°λŠ₯은 URL 처리λ₯Ό κ°„μ†Œν™”ν•˜μ§€λ§Œ, Nginx 뒀에 μžˆλŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ 특히 둜컬 파일 포함(LFI) 곡격에 μ·¨μ•½ν•œ 경우 취약점을 숨길 수 μžˆμŠ΅λ‹ˆλ‹€. λ³΄μ•ˆ μ „λ¬Έκ°€ **Danny Robinsonκ³Ό Rotem Bar**λŠ” Nginxκ°€ λ¦¬λ²„μŠ€ ν”„λ‘μ‹œλ‘œ μž‘λ™ν•  λ•Œ 이 κΈ°λ³Έ λ™μž‘κ³Ό κ΄€λ ¨λœ 잠재적 μœ„ν—˜μ„ κ°•μ‘°ν–ˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ μœ„ν—˜μ„ μ™„ν™”ν•˜κΈ° μœ„ν•΄, μ΄λŸ¬ν•œ 취약점에 μ·¨μ•½ν•œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— λŒ€ν•΄ **`merge_slashes` μ§€μ‹œμ–΄λ₯Ό λ„λŠ” 것이 ꢌμž₯λ©λ‹ˆλ‹€**. μ΄λŠ” Nginxκ°€ URL ꡬ쑰λ₯Ό λ³€κ²½ν•˜μ§€ μ•Šκ³  μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— μš”μ²­μ„ μ „λ‹¬ν•˜λ„λ‘ 보μž₯ν•˜μ—¬ 기본적인 λ³΄μ•ˆ 문제λ₯Ό μˆ¨κΈ°μ§€ μ•Šλ„λ‘ ν•©λ‹ˆλ‹€. μžμ„Έν•œ λ‚΄μš©μ€ [Danny Robinsonκ³Ό Rotem Bar](https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d)λ₯Ό ν™•μΈν•˜μ„Έμš”. ### **Maclicious Response Headers** [**이 κΈ€**](https://mizu.re/post/cors-playground)μ—μ„œ 보여쀀 바와 같이, μ›Ή μ„œλ²„μ˜ 응닡에 μ‘΄μž¬ν•˜λŠ” νŠΉμ • ν—€λ”λŠ” Nginx ν”„λ‘μ‹œμ˜ λ™μž‘μ„ λ³€κ²½ν•©λ‹ˆλ‹€. 이듀을 [**λ¬Έμ„œμ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€**](https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/): * `X-Accel-Redirect`: Nginxκ°€ μš”μ²­μ„ μ§€μ •λœ μœ„μΉ˜λ‘œ λ‚΄λΆ€ λ¦¬λ””λ ‰μ…˜ν•˜λ„λ‘ μ§€μ‹œν•©λ‹ˆλ‹€. * `X-Accel-Buffering`: Nginxκ°€ 응닡을 버퍼링할지 μ—¬λΆ€λ₯Ό μ œμ–΄ν•©λ‹ˆλ‹€. * `X-Accel-Charset`: X-Accel-Redirectλ₯Ό μ‚¬μš©ν•  λ•Œ μ‘λ‹΅μ˜ 문자 집합을 μ„€μ •ν•©λ‹ˆλ‹€. * `X-Accel-Expires`: X-Accel-Redirectλ₯Ό μ‚¬μš©ν•  λ•Œ μ‘λ‹΅μ˜ 만료 μ‹œκ°„μ„ μ„€μ •ν•©λ‹ˆλ‹€. * `X-Accel-Limit-Rate`: X-Accel-Redirectλ₯Ό μ‚¬μš©ν•  λ•Œ μ‘λ‹΅μ˜ 전솑 속도λ₯Ό μ œν•œν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, 헀더 **`X-Accel-Redirect`**λŠ” Nginxμ—μ„œ λ‚΄λΆ€ **λ¦¬λ””λ ‰μ…˜**을 λ°œμƒμ‹œν‚΅λ‹ˆλ‹€. λ”°λΌμ„œ **`root /`**와 같은 Nginx ꡬ성이 있고 μ›Ή μ„œλ²„μ˜ 응닡에 **`X-Accel-Redirect: .env`**κ°€ ν¬ν•¨λ˜λ©΄ NginxλŠ” **`/.env`**의 λ‚΄μš©μ„ μ „μ†‘ν•˜κ²Œ λ©λ‹ˆλ‹€ (경둜 탐색). ### **Map Directive의 κΈ°λ³Έκ°’** **Nginx ꡬ성**μ—μ„œ `map` μ§€μ‹œμ–΄λŠ” μ’…μ’… **κΆŒν•œ μ œμ–΄**μ—μ„œ 역할을 ν•©λ‹ˆλ‹€. 일반적인 μ‹€μˆ˜λŠ” **κΈ°λ³Έ** 값을 μ§€μ •ν•˜μ§€ μ•ŠλŠ” κ²ƒμœΌλ‘œ, μ΄λŠ” 무단 μ ‘κ·ΌμœΌλ‘œ μ΄μ–΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄: ```yaml http { map $uri $mappocallow { /map-poc/private 0; /map-poc/secret 0; /map-poc/public 1; } } ``` ```yaml server { location /map-poc { if ($mappocallow = 0) {return 403;} return 200 "Hello. It is private area: $mappocallow"; } } ``` `default`κ°€ μ—†μœΌλ©΄, **μ•…μ˜μ μΈ μ‚¬μš©μž**λŠ” `/map-poc` λ‚΄μ—μ„œ **μ •μ˜λ˜μ§€ μ•Šμ€ URI**에 μ ‘κ·Όν•˜μ—¬ λ³΄μ•ˆμ„ μš°νšŒν•  수 μžˆμŠ΅λ‹ˆλ‹€. [Nginx 맀뉴얼](https://nginx.org/en/docs/http/ngx\_http\_map\_module.html)μ—μ„œλŠ” μ΄λŸ¬ν•œ 문제λ₯Ό ν”Όν•˜κΈ° μœ„ν•΄ **κΈ°λ³Έκ°’**을 μ„€μ •ν•  것을 ꢌμž₯ν•©λ‹ˆλ‹€. ### **DNS μŠ€ν‘Έν•‘ 취약점** νŠΉμ • μ‘°κ±΄μ—μ„œ Nginx에 λŒ€ν•œ DNS μŠ€ν‘Έν•‘μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€. κ³΅κ²©μžκ°€ Nginxμ—μ„œ μ‚¬μš©ν•˜λŠ” **DNS μ„œλ²„**λ₯Ό μ•Œκ³  κ·Έ DNS 쿼리λ₯Ό κ°€λ‘œμ±Œ 수 μžˆλ‹€λ©΄, DNS λ ˆμ½”λ“œλ₯Ό μŠ€ν‘Έν•‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ Nginxκ°€ DNS 해석을 μœ„ν•΄ **localhost (127.0.0.1)**λ₯Ό μ‚¬μš©ν•˜λ„λ‘ κ΅¬μ„±λœ 경우, 이 방법은 νš¨κ³Όμ μ΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. NginxλŠ” λ‹€μŒκ³Ό 같이 DNS μ„œλ²„λ₯Ό 지정할 수 μžˆμŠ΅λ‹ˆλ‹€: ```yaml resolver 8.8.8.8; ``` ### **`proxy_pass` 및 `internal` μ§€μ‹œμ–΄** **`proxy_pass`** μ§€μ‹œμ–΄λŠ” μš”μ²­μ„ λ‚΄λΆ€ λ˜λŠ” μ™ΈλΆ€μ˜ λ‹€λ₯Έ μ„œλ²„λ‘œ λ¦¬λ””λ ‰μ…˜ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€. **`internal`** μ§€μ‹œμ–΄λŠ” νŠΉμ • μœ„μΉ˜κ°€ Nginx λ‚΄μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯ν•˜λ„λ‘ 보μž₯ν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ μ§€μ‹œμ–΄ μžμ²΄λŠ” 취약점이 μ•„λ‹ˆμ§€λ§Œ, λ³΄μ•ˆ λˆ„μˆ˜λ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•΄ ꡬ성에 λŒ€ν•œ μ‹ μ€‘ν•œ κ²€ν† κ°€ ν•„μš”ν•©λ‹ˆλ‹€. ## proxy\_set\_header Upgrade & Connection nginx μ„œλ²„κ°€ Upgrade 및 Connection 헀더λ₯Ό μ „λ‹¬ν•˜λ„λ‘ κ΅¬μ„±λœ 경우 [**h2c Smuggling 곡격**](../../pentesting-web/h2c-smuggling.md)λ₯Ό μˆ˜ν–‰ν•˜μ—¬ 보호된/λ‚΄λΆ€ μ—”λ“œν¬μΈνŠΈμ— μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€. {% hint style="danger" %} 이 취약점은 κ³΅κ²©μžκ°€ **`proxy_pass` μ—”λ“œν¬μΈνŠΈμ™€ 직접 연결을 μ„€μ •ν•  수 있게 ν•©λ‹ˆλ‹€** (`http://backend:9999`의 경우) 이 μ½˜ν…μΈ λŠ” nginx에 μ˜ν•΄ ν™•μΈλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. {% endhint %} `/flag`λ₯Ό ν›”μΉ˜κΈ° μœ„ν•œ μ·¨μ•½ν•œ ꡬ성 μ˜ˆμ‹œ: [μ—¬κΈ°](https://bishopfox.com/blog/h2c-smuggling-request)μ—μ„œ ν™•μΈν•˜μ„Έμš”. ``` server { listen 443 ssl; server_name localhost; ssl_certificate /usr/local/nginx/conf/cert.pem; ssl_certificate_key /usr/local/nginx/conf/privkey.pem; location / { proxy_pass http://backend:9999; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; } location /flag { deny all; } ``` {% hint style="warning" %} `proxy_pass`κ°€ `http://backend:9999/socket.io`와 같은 νŠΉμ • **경둜**λ₯Ό 가리킀고 μžˆλ”λΌλ„, 연결은 `http://backend:9999`둜 μ„€μ •λ˜λ―€λ‘œ **λ‚΄λΆ€ μ—”λ“œν¬μΈνŠΈ λ‚΄μ˜ λ‹€λ₯Έ κ²½λ‘œμ— 연락할 수 μžˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ proxy_pass의 URL에 κ²½λ‘œκ°€ μ§€μ •λ˜μ–΄ μžˆλŠ”μ§€λŠ” μ€‘μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.** {% endhint %} ## 직접 ν•΄λ³΄μ„Έμš” DetectifyλŠ” Dockerλ₯Ό μ‚¬μš©ν•˜μ—¬ 이 κΈ°μ‚¬μ—μ„œ λ…Όμ˜λœ λͺ‡ 가지 잘λͺ»λœ κ΅¬μ„±μœΌλ‘œ μ·¨μ•½ν•œ Nginx ν…ŒμŠ€νŠΈ μ„œλ²„λ₯Ό μ„€μ •ν•˜κ³  직접 μ°Ύμ•„λ³Ό 수 μžˆλŠ” GitHub 리포지토리λ₯Ό λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€! [https://github.com/detectify/vulnerable-nginx](https://github.com/detectify/vulnerable-nginx) ## 정적 뢄석 도ꡬ ### [GIXY](https://github.com/yandex/gixy) GixyλŠ” Nginx ꡬ성을 λΆ„μ„ν•˜λŠ” λ„κ΅¬μž…λ‹ˆλ‹€. Gixy의 μ£Όμš” λͺ©ν‘œλŠ” λ³΄μ•ˆ 잘λͺ»λœ ꡬ성을 λ°©μ§€ν•˜κ³  결함 탐지λ₯Ό μžλ™ν™”ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. ### [Nginxpwner](https://github.com/stark0de/nginxpwner) NginxpwnerλŠ” 일반적인 Nginx 잘λͺ»λœ ꡬ성 및 취약점을 μ°ΎκΈ° μœ„ν•œ κ°„λ‹¨ν•œ λ„κ΅¬μž…λ‹ˆλ‹€. ## 참고자료 * [**https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/**](https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/) * [**http://blog.zorinaq.com/nginx-resolver-vulns/**](http://blog.zorinaq.com/nginx-resolver-vulns/) * [**https://github.com/yandex/gixy/issues/115**](https://github.com/yandex/gixy/issues/115)
**μ·¨μ•½μ„± 평가 및 침투 ν…ŒμŠ€νŠΈλ₯Ό μœ„ν•œ μ¦‰μ‹œ μ‚¬μš© κ°€λŠ₯ν•œ μ„€μ •**. 20개 μ΄μƒμ˜ 도ꡬ 및 κΈ°λŠ₯을 μ‚¬μš©ν•˜μ—¬ μ–΄λ””μ„œλ‚˜ 전체 침투 ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•˜μ„Έμš”. μš°λ¦¬λŠ” 침투 ν…ŒμŠ€ν„°λ₯Ό λŒ€μ²΄ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ - μš°λ¦¬λŠ” 그듀이 더 깊이 νŒŒκ³ λ“€κ³ , μ‰˜μ„ ν„°λœ¨λ¦¬κ³ , 재미λ₯Ό λŠλ‚„ 수 μžˆλ„λ‘ λ§žμΆ€ν˜• 도ꡬ, 탐지 및 μ•…μš© λͺ¨λ“ˆμ„ κ°œλ°œν•©λ‹ˆλ‹€. {% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %} {% hint style="success" %} AWS ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ GCP ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
HackTricks μ§€μ›ν•˜κΈ° * [**ꡬ독 κ³„νš**](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을 μ œμΆœν•˜μ—¬ ν•΄ν‚Ή νŒμ„ κ³΅μœ ν•˜μ„Έμš”.**
{% endhint %}