# 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 %}
**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
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
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
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
{% 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
`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)
**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:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\
Ucz się i ćwicz Hacking GCP: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Wsparcie dla HackTricks
* 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.
{% endhint %}