hacktricks/network-services-pentesting/pentesting-web/nginx.md

306 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Nginx
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* 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.
</details>
{% endhint %}
<figure><img src="../../.gitbook/assets/image (14) (1).png" alt=""><figcaption></figcaption></figure>
**Natychmiastowo dostępna konfiguracja do oceny podatności i testów penetracyjnych**. Przeprowadź pełny pentest z dowolnego miejsca z ponad 20 narzędziami i funkcjami, które obejmują od rekonesansu po raportowanie. Nie zastępujemy pentesterów - rozwijamy niestandardowe narzędzia, moduły wykrywania i eksploatacji, aby dać im z powrotem trochę czasu na głębsze badania, przełamywanie zabezpieczeń i zabawę.
{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}
## Brak lokalizacji root <a href="#missing-root-location" id="missing-root-location"></a>
Podczas konfigurowania serwera Nginx, **dyrektywa root** odgrywa kluczową rolę, definiując katalog bazowy, z którego serwowane są pliki. Rozważ poniższy przykład:
```bash
server {
root /etc/nginx;
location /hello.txt {
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8080/;
}
}
```
W tej konfiguracji `/etc/nginx` jest wyznaczone jako katalog główny. Ta konfiguracja umożliwia dostęp do plików w określonym katalogu głównym, takich jak `/hello.txt`. Jednak ważne jest, aby zauważyć, że zdefiniowana jest tylko konkretna lokalizacja (`/hello.txt`). Nie ma konfiguracji dla lokalizacji głównej (`location / {...}`). To pominięcie oznacza, że dyrektywa root ma zastosowanie globalnie, co umożliwia żądaniom do ścieżki głównej `/` dostęp do plików w `/etc/nginx`.
Krytyczne zagadnienie bezpieczeństwa wynika z tej konfiguracji. Proste żądanie `GET`, takie jak `GET /nginx.conf`, może ujawnić wrażliwe informacje, serwując plik konfiguracyjny Nginx znajdujący się w `/etc/nginx/nginx.conf`. Ustawienie katalogu głównego na mniej wrażliwy katalog, taki jak `/etc`, może złagodzić to ryzyko, jednak nadal może umożliwić niezamierzony dostęp do innych krytycznych plików, w tym innych plików konfiguracyjnych, dzienników dostępu, a nawet zaszyfrowanych poświadczeń używanych do podstawowej autoryzacji HTTP.
## Alias LFI Misconfiguration <a href="#alias-lfi-misconfiguration" id="alias-lfi-misconfiguration"></a>
W plikach konfiguracyjnych Nginx należy dokładnie sprawdzić dyrektywy "location". Wrażliwość znana jako Local File Inclusion (LFI) może być niezamierzenie wprowadzona przez konfigurację, która przypomina następującą:
```
location /imgs {
alias /path/images/;
}
```
Ta konfiguracja jest podatna na ataki LFI, ponieważ serwer interpretuje żądania takie jak `/imgs../flag.txt` jako próbę uzyskania dostępu do plików poza zamierzonym katalogiem, co skutkuje efektywnym rozwiązaniem do `/path/images/../flag.txt`. Ta wada pozwala atakującym na pobieranie plików z systemu plików serwera, które nie powinny być dostępne przez sieć.
Aby złagodzić tę podatność, konfiguracja powinna zostać dostosowana do:
```
location /imgs/ {
alias /path/images/;
}
```
Więcej informacji: [https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/](https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/)
Testy 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
```
## Unsafe path restriction <a href="#unsafe-variable-use" id="unsafe-variable-use"></a>
Sprawdź następującą stronę, aby dowiedzieć się, jak obejść dyrektywy takie jak:
```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 %}
## Niebezpieczne użycie zmiennych / Podział żądania HTTP <a href="#unsafe-variable-use" id="unsafe-variable-use"></a>
{% hint style="danger" %}
Wrażliwe zmienne `$uri` i `$document_uri`, które można naprawić, zastępując je `$request_uri`.
Wyrażenie regularne również może być wrażliwe, jak:
`location ~ /docs/([^/])? { … $1 … }` - Wrażliwe&#x20;
`location ~ /docs/([^/\s])? { … $1 … }` - Nie wrażliwe (sprawdza spacje)
`location ~ /docs/(.*)? { … $1 … }` - Nie wrażliwe
{% endhint %}
Wrażliwość w konfiguracji Nginx jest pokazana w poniższym przykładzie:
```
location / {
return 302 https://example.com$uri;
}
```
Znaki \r (Carriage Return) i \n (Line Feed) oznaczają znaki nowej linii w żądaniach HTTP, a ich zakodowane w URL formy są reprezentowane jako `%0d%0a`. Włączenie tych znaków w żądaniu (np. `http://localhost/%0d%0aDetectify:%20clrf`) do źle skonfigurowanego serwera skutkuje tym, że serwer wydaje nowy nagłówek o nazwie `Detectify`. Dzieje się tak, ponieważ zmienna $uri dekoduje zakodowane w URL znaki nowej linii, co prowadzi do nieoczekiwanego nagłówka w odpowiedzi:
```
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
```
Dowiedz się więcej o ryzykach związanych z wstrzykiwaniem CRLF i dzieleniem odpowiedzi na [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/).
Ta technika jest [**wyjaśniona w tej prezentacji**](https://www.youtube.com/watch?v=gWQyWdZbdoY\&list=PL0xCSYnG\_iTtJe2V6PQqamBF73n7-f1Nr\&index=77) z przykładami podatności i mechanizmami wykrywania. Na przykład, aby wykryć tę błędną konfigurację z perspektywy czarnej skrzynki, możesz użyć tych żądań:
* `https://example.com/%20X` - Dowolny kod HTTP
* `https://example.com/%20H` - 400 Bad Request
Jeśli jest podatny, pierwsze zwróci, ponieważ "X" jest dowolną metodą HTTP, a drugie zwróci błąd, ponieważ H nie jest prawidłową metodą. Serwer otrzyma coś takiego: `GET / H HTTP/1.1` i to spowoduje błąd.
Inne przykłady wykrywania to:
* `http://company.tld/%20HTTP/1.1%0D%0AXXXX:%20x` - Dowolny kod HTTP
* `http://company.tld/%20HTTP/1.1%0D%0AHost:%20x` - 400 Bad Request
Niektóre znalezione podatne konfiguracje przedstawione w tej prezentacji to:
* Zauważ, jak **`$uri`** jest ustawione tak, jak jest w końcowym URL
```
location ^~ /lite/api/ {
proxy_pass http://lite-backend$uri$is_args$args;
}
```
* Zauważ, że ponownie **`$uri`** znajduje się w URL (tym razem wewnątrz parametru)
```
location ~ ^/dna/payment {
rewrite ^/dna/([^/]+) /registered/main.pl?cmd=unifiedPayment&context=$1&native_uri=$uri break;
proxy_pass http://$back;
```
* Teraz w AWS S3
```
location /s3/ {
proxy_pass https://company-bucket.s3.amazonaws.com$uri;
}
```
### Any variable
Odkryto, że **dane dostarczone przez użytkownika** mogą być traktowane jako **zmienna Nginx** w określonych okolicznościach. Przyczyna tego zachowania pozostaje nieco niejasna, jednak nie jest to rzadkie ani proste do weryfikacji. Ta anomalia została podkreślona w raporcie bezpieczeństwa na HackerOne, który można zobaczyć [tutaj](https://hackerone.com/reports/370094). Dalsze badania komunikatu o błędzie doprowadziły do identyfikacji jego wystąpienia w [module filtra SSI w kodzie Nginx](https://github.com/nginx/nginx/blob/2187586207e1465d289ae64cedc829719a048a39/src/http/modules/ngx\_http\_ssi\_filter\_module.c#L365), wskazując na Server Side Includes (SSI) jako przyczynę.
Aby **wykryć tę błędną konfigurację**, można wykonać następujące polecenie, które polega na ustawieniu nagłówka referer w celu przetestowania drukowania zmiennej:
```bash
$ curl -H Referer: bar http://localhost/foo$http_referer | grep foobar
```
Skany tej niewłaściwej konfiguracji w różnych systemach ujawniły wiele przypadków, w których zmienne Nginx mogły być drukowane przez użytkownika. Jednak spadek liczby podatnych przypadków sugeruje, że wysiłki na rzecz naprawienia tego problemu były w pewnym stopniu udane.
## Odczyt surowej odpowiedzi backendu
Nginx oferuje funkcję poprzez `proxy_pass`, która pozwala na przechwytywanie błędów i nagłówków HTTP generowanych przez backend, mając na celu ukrycie wewnętrznych komunikatów o błędach i nagłówków. Osiąga się to poprzez serwowanie przez Nginx niestandardowych stron błędów w odpowiedzi na błędy backendu. Jednak pojawiają się wyzwania, gdy Nginx napotyka nieprawidłowe żądanie HTTP. Takie żądanie jest przekazywane do backendu w takiej formie, w jakiej zostało odebrane, a surowa odpowiedź backendu jest następnie bezpośrednio wysyłana do klienta bez interwencji Nginx.
Rozważmy przykładowy scenariusz z aplikacją 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!"]
```
Aby to zarządzać, w konfiguracji Nginx używane są specyficzne dyrektywy:
```
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): Ta dyrektywa umożliwia Nginxowi serwowanie niestandardowej odpowiedzi dla odpowiedzi backendu z kodem statusu większym niż 300. Zapewnia, że w naszym przykładzie aplikacji uWSGI odpowiedź `500 Error` jest przechwytywana i obsługiwana przez Nginx.
* [**proxy\_hide\_header**](http://nginx.org/en/docs/http/ngx\_http\_proxy\_module.html#proxy\_hide\_header): Jak sama nazwa wskazuje, ta dyrektywa ukrywa określone nagłówki HTTP przed klientem, zwiększając prywatność i bezpieczeństwo.
Gdy zostanie wysłane ważne żądanie `GET`, Nginx przetwarza je normalnie, zwracając standardową odpowiedź błędu bez ujawniania jakichkolwiek tajnych nagłówków. Jednak nieprawidłowe żądanie HTTP omija ten mechanizm, co skutkuje ujawnieniem surowych odpowiedzi backendu, w tym tajnych nagłówków i komunikatów o błędach.
## merge\_slashes ustawione na off
Domyślnie dyrektywa **`merge_slashes`** w Nginx jest ustawiona na **`on`**, co kompresuje wiele ukośników w URL w jeden ukośnik. Ta funkcja, choć upraszcza przetwarzanie URL, może nieumyślnie ukrywać luki w aplikacjach za Nginx, szczególnie tych podatnych na ataki lokalnego włączenia plików (LFI). Eksperci ds. bezpieczeństwa **Danny Robinson i Rotem Bar** podkreślili potencjalne ryzyko związane z tym domyślnym zachowaniem, szczególnie gdy Nginx działa jako reverse-proxy.
Aby złagodzić takie ryzyko, zaleca się **wyłączenie dyrektywy `merge_slashes`** dla aplikacji podatnych na te luki. Zapewnia to, że Nginx przekazuje żądania do aplikacji bez zmiany struktury URL, a tym samym nie maskuje żadnych ukrytych problemów z bezpieczeństwem.
Aby uzyskać więcej informacji, sprawdź [Danny Robinson i Rotem Bar](https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d).
### **Maclicious Response Headers**
Jak pokazano w [**tym artykule**](https://mizu.re/post/cors-playground), istnieją pewne nagłówki, które, jeśli są obecne w odpowiedzi z serwera WWW, zmienią zachowanie proxy Nginx. Możesz je sprawdzić [**w dokumentacji**](https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/):
* `X-Accel-Redirect`: Wskazuje Nginxowi, aby wewnętrznie przekierował żądanie do określonej lokalizacji.
* `X-Accel-Buffering`: Kontroluje, czy Nginx powinien buforować odpowiedź, czy nie.
* `X-Accel-Charset`: Ustawia zestaw znaków dla odpowiedzi przy użyciu X-Accel-Redirect.
* `X-Accel-Expires`: Ustawia czas wygaśnięcia dla odpowiedzi przy użyciu X-Accel-Redirect.
* `X-Accel-Limit-Rate`: Ogranicza szybkość transferu dla odpowiedzi przy użyciu X-Accel-Redirect.
Na przykład nagłówek **`X-Accel-Redirect`** spowoduje wewnętrzne **przekierowanie** w Nginx. Tak więc posiadanie konfiguracji Nginx z czymś takim jak **`root /`** i odpowiedzi z serwera WWW z **`X-Accel-Redirect: .env`** spowoduje, że Nginx wyśle zawartość **`/.env`** (Path Traversal).
### **Wartość domyślna w dyrektywie map**
W **konfiguracji Nginx** dyrektywa `map` często odgrywa rolę w **kontroli autoryzacji**. Powszechnym błędem jest nieokreślenie wartości **domyślnej**, co może prowadzić do nieautoryzowanego dostępu. Na przykład:
```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";
}
}
```
Bez `default`, **złośliwy użytkownik** może obejść zabezpieczenia, uzyskując dostęp do **niezdefiniowanego URI** w `/map-poc`. [Podręcznik Nginx](https://nginx.org/en/docs/http/ngx\_http\_map\_module.html) zaleca ustawienie **wartości domyślnej**, aby uniknąć takich problemów.
### **Luka w Spoofingu DNS**
Spoofing DNS przeciwko Nginx jest możliwy w określonych warunkach. Jeśli atakujący zna **serwer DNS** używany przez Nginx i może przechwycić jego zapytania DNS, może sfałszować rekordy DNS. Ta metoda jest jednak nieskuteczna, jeśli Nginx jest skonfigurowany do używania **localhost (127.0.0.1)** do rozwiązywania DNS. Nginx pozwala na określenie serwera DNS w następujący sposób:
```yaml
resolver 8.8.8.8;
```
### **`proxy_pass` i `internal` Dyrektywy**
Dyrektywa **`proxy_pass`** jest wykorzystywana do przekierowywania żądań do innych serwerów, zarówno wewnętrznych, jak i zewnętrznych. Dyrektywa **`internal`** zapewnia, że niektóre lokalizacje są dostępne tylko wewnątrz Nginx. Chociaż te dyrektywy same w sobie nie są lukami, ich konfiguracja wymaga starannego zbadania, aby zapobiec lukom w zabezpieczeniach.
## proxy\_set\_header Upgrade & Connection
Jeśli serwer nginx jest skonfigurowany do przekazywania nagłówków Upgrade i Connection, można przeprowadzić [**atak h2c Smuggling**](../../pentesting-web/h2c-smuggling.md), aby uzyskać dostęp do chronionych/wewnętrznych punktów końcowych.
{% hint style="danger" %}
Ta luka pozwoliłaby atakującemu na **nawiązanie bezpośredniego połączenia z punktem końcowym `proxy_pass`** (`http://backend:9999` w tym przypadku), którego zawartość nie będzie sprawdzana przez nginx.
{% endhint %}
Przykład podatnej konfiguracji do kradzieży `/flag` z [tutaj](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" %}
Zauważ, że nawet jeśli `proxy_pass` wskazywał na konkretną **ścieżkę** taką jak `http://backend:9999/socket.io`, połączenie zostanie nawiązane z `http://backend:9999`, więc możesz **skontaktować się z każdą inną ścieżką wewnątrz tego wewnętrznego punktu końcowego. Więc nie ma znaczenia, czy ścieżka jest określona w URL proxy_pass.**
{% endhint %}
## Spróbuj sam
Detectify stworzył repozytorium na GitHubie, w którym możesz użyć Dockera do skonfigurowania własnego podatnego serwera testowego Nginx z niektórymi z omówionych w tym artykule błędów konfiguracyjnych i spróbować je znaleźć samodzielnie!
[https://github.com/detectify/vulnerable-nginx](https://github.com/detectify/vulnerable-nginx)
## Narzędzia analizy statycznej
### [GIXY](https://github.com/yandex/gixy)
Gixy to narzędzie do analizy konfiguracji Nginx. Głównym celem Gixy jest zapobieganie błędom konfiguracyjnym związanym z bezpieczeństwem oraz automatyzacja wykrywania wad.
### [Nginxpwner](https://github.com/stark0de/nginxpwner)
Nginxpwner to proste narzędzie do wyszukiwania powszechnych błędów konfiguracyjnych Nginx i podatności.
## Referencje
* [**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)
<figure><img src="../../.gitbook/assets/image (14) (1).png" alt=""><figcaption></figcaption></figure>
**Natychmiast dostępna konfiguracja do oceny podatności i testów penetracyjnych**. Przeprowadź pełny pentest z dowolnego miejsca z ponad 20 narzędziami i funkcjami, które obejmują od rekonesansu po raportowanie. Nie zastępujemy pentesterów - rozwijamy niestandardowe narzędzia, moduły wykrywania i eksploatacji, aby dać im z powrotem trochę czasu na głębsze badania, przełamywanie zabezpieczeń i zabawę.
{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}
{% hint style="success" %}
Ucz się i ćwicz Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Ucz się i ćwicz Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Wsparcie dla HackTricks</summary>
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Dziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na GitHubie.
</details>
{% endhint %}