18 KiB
Nginx
Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź PLANY SUBSKRYPCYJNE!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud github repos.
Natychmiastowa konfiguracja do oceny podatności i testów penetracyjnych. Uruchom pełne testy penetracyjne z dowolnego miejsca za pomocą 20+ narzędzi i funkcji, które obejmują rozpoznanie, raportowanie. Nie zastępujemy pentesterów - rozwijamy niestandardowe narzędzia, moduły wykrywania i eksploatacji, aby umożliwić im zagłębienie się, zdobycie powłok i dobrą zabawę.
{% embed url="https://pentest-tools.com/" %}
Brakujące miejsce root
Podstawy konfigurowania katalogu głównego Nginx
Podczas konfigurowania serwera Nginx, dyrektywa root odgrywa kluczową rolę, definiując katalog bazowy, z którego są serwowane pliki. Rozważ poniższy przykład:
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 określony jako katalog główny. To ustawienie umożliwia dostęp do plików w określonym katalogu głównym, takich jak /hello.txt
. Jednakże ważne jest zauważenie, że zdefiniowana jest tylko określona lokalizacja (/hello.txt
). Brak konfiguracji dla lokalizacji głównej (location / {...}
). Ta pominięta część oznacza, że dyrektywa root jest stosowana globalnie, umożliwiając żądania do ścieżki głównej /
w celu uzyskania dostępu do plików znajdujących się w /etc/nginx
.
Z tej konfiguracji wynika istotne zagrożenie dla bezpieczeństwa. Proste żądanie GET
, takie jak GET /nginx.conf
, może ujawnić wrażliwe informacje poprzez udostępnienie pliku konfiguracyjnego Nginx znajdującego się w /etc/nginx/nginx.conf
. Ustawienie roota na mniej wrażliwy katalog, np. /etc
, może zmniejszyć to ryzyko, ale nadal może doprowadzić do niezamierzonego dostępu do innych istotnych plików, w tym innych plików konfiguracyjnych, logów dostępu, a nawet zaszyfrowanych poświadczeń używanych do autentykacji podstawowej protokołu HTTP.
Konfiguracja Alias LFI
W plikach konfiguracyjnych Nginx konieczna jest dokładna inspekcja dyrektyw "location". Podatność znana jako Local File Inclusion (LFI) może zostać nieumyślnie wprowadzona poprzez konfigurację, która przypomina poniższe:
location /imgs {
alias /path/images/;
}
Ta konfiguracja jest podatna na ataki LFI, ponieważ serwer interpretuje żądania takie jak /imgs../flag.txt
jako próbę dostępu do plików poza zamierzonym katalogiem, efektywnie rozwiązując się do /path/images/../flag.txt
. Ta wada pozwala atakującym na pobieranie plików z systemu plików serwera, do których nie powinno być dostępu 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/
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
Niebezpieczne ograniczenie ścieżki
Sprawdź następującą stronę, aby dowiedzieć się, jak ominąć dyrektywy takie jak:
location = /admin {
deny all;
}
location = /admin/ {
deny all;
}
Niestabilne użycie zmiennej / Podział żądania HTTP
{% hint style="danger" %}
Narażone zmienne $uri
i $document_uri
mogą zostać naprawione poprzez zastąpienie ich zmienną $request_uri
.
Regex może również być narażony, na przykład:
location ~ /docs/([^/])? { … $1 … }
- Narażone
location ~ /docs/([^/\s])? { … $1 … }
- Nie narażone (sprawdzanie spacji)
location ~ /docs/(.*)? { … $1 … }
- Nie narażone
{% endhint %}
Przykładem podatności w konfiguracji Nginx jest poniższy przykład:
location / {
return 302 https://example.com$uri;
}
Znaki \r (powrót karetki) i \n (nowa linia) oznaczają nowe znaki w żądaniach HTTP, a ich zaszyfrowane w formie URL to %0d%0a
. Włączenie tych znaków w żądaniu (np. http://localhost/%0d%0aDetectify:%20clrf
) do źle skonfigurowanego serwera skutkuje wydaniem przez serwer nowego nagłówka o nazwie Detectify
. Dzieje się tak, ponieważ zmienna $uri dekoduje zaszyfrowane w formie 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 ryzyku wstrzykiwania CRLF i podziału odpowiedzi na https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/.
Ta technika jest również wyjaśniona w tej prezentacji z przykładami podatności i mechanizmami wykrywania. Na przykład, aby wykryć tę konfigurację z perspektywy blackbox, można użyć tych żądań:
https://example.com/%20X
- Dowolny kod HTTPhttps://example.com/%20H
- 400 Bad Request
Jeśli jest podatny, pierwsze żądanie zwróci "X", ponieważ jest to dowolna metoda HTTP, a drugie spowoduje błąd, ponieważ H nie jest poprawną metodą. Serwer otrzyma coś w rodzaju: GET / H HTTP/1.1
, co spowoduje błąd.
Inne przykłady wykrywania to:
http://company.tld/%20HTTP/1.1%0D%0AXXXX:%20x
- Dowolny kod HTTPhttp://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 adresie URL.
location ^~ /lite/api/ {
proxy_pass http://lite-backend$uri$is_args$args;
}
- Zauważ, jak ponownie
$uri
znajduje się w adresie 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;
}
Dowolna zmienna
Odkryto, że dane dostarczone przez użytkownika mogą być traktowane jako zmienna Nginx w określonych okolicznościach. Przyczyna tego zachowania pozostaje w pewnym stopniu niejasna, ale nie jest to rzadkie ani proste do zweryfikowania. To anomalie zostało podkreślone w raporcie bezpieczeństwa na HackerOne, który można zobaczyć tutaj. Dalsze dochodzenie do komunikatu o błędzie doprowadziło do zidentyfikowania jego wystąpienia w module filtru SSI kodu źródłowego Nginx, wskazując na Server Side Includes (SSI) jako główną przyczynę.
Aby wykryć tę błędną konfigurację, można wykonać poniższą komendę, która polega na ustawieniu nagłówka referer w celu przetestowania drukowania zmiennej:
$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’
Skanowania dla tej konfiguracji na różnych systemach ujawniły wiele przypadków, gdzie zmienne Nginx mogły być wydrukowane przez użytkownika. Jednakże spadek liczby podatnych przypadków sugeruje, że wysiłki w celu załatania tego problemu były do pewnego stopnia skuteczne.
Odczyt surowej odpowiedzi z 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. Jest to osiągane poprzez serwowanie Nginx stron błędów niestandardowych w odpowiedzi na błędy backendu. Jednakże pojawiają się wyzwania, gdy Nginx napotyka nieprawidłowe żądanie HTTP. Takie żądanie jest przekazywane do backendu w otrzymanej postaci, a surowa odpowiedź backendu jest następnie bezpośrednio wysyłana do klienta bez interwencji Nginx.
Rozważmy przykładowy scenariusz dotyczący aplikacji uWSGI:
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ć, używane są konkretne dyrektywy w konfiguracji Nginx:
http {
error_page 500 /html/error.html;
proxy_intercept_errors on;
proxy_hide_header Secret-Header;
}
- proxy_intercept_errors: Ta dyrektywa umożliwia Nginxowi obsługę niestandardowej odpowiedzi dla odpowiedzi z serwera z kodem stanu większym niż 300. Zapewnia to, że dla naszej przykładowej aplikacji uWSGI odpowiedź
500 Error
jest przechwytywana i obsługiwana przez Nginx. - proxy_hide_header: Jak sugeruje nazwa, ta dyrektywa ukrywa określone nagłówki HTTP przed klientem, zwiększając prywatność i bezpieczeństwo.
Gdy zostanie wysłane prawidłowe żądanie GET
, Nginx przetwarza je normalnie, zwracając standardową odpowiedź błędu, nie ujawniając żadnych tajnych nagłówków. Jednak nieprawidłowe żądanie HTTP omija ten mechanizm, co skutkuje ujawnieniem surowych odpowiedzi z serwera, w tym tajnych nagłówków i komunikatów błędów.
merge_slashes ustawione na off
Domyślnie dyrektywa merge_slashes
Nginxa jest ustawiona na on
, co kompresuje wiele ukośników w przekierowaniu URL do pojedynczego ukośnika. Ta funkcja, podczas upraszczania przetwarzania URL, może niechcący ukrywać podatności aplikacji za Nginxem, zwłaszcza tych podatnych na ataki lokalnego dołączania plików (LFI). Eksperci ds. bezpieczeństwa Danny Robinson i Rotem Bar zwrócili uwagę na potencjalne ryzyko związane z tym domyślnym zachowaniem, zwłaszcza gdy Nginx działa jako odwrotny proxy.
Aby zmniejszyć takie ryzyko, zaleca się wyłączenie dyrektywy merge_slashes
dla aplikacji podatnych na te podatności. Zapewnia to, że Nginx przekazuje żądania do aplikacji bez zmiany struktury URL, nie maskując żadnych istniejących problemów z bezpieczeństwem.
Aby uzyskać więcej informacji, sprawdź Danny Robinson i Rotem Bar.
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:
http {
map $uri $mappocallow {
/map-poc/private 0;
/map-poc/secret 0;
/map-poc/public 1;
}
}
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 ominąć zabezpieczenia, uzyskując dostęp do niezdefiniowanego URI wewnątrz /map-poc
. Podręcznik Nginx zaleca ustawienie wartości domyślnej, aby uniknąć takich problemów.
Podatność na DNS Spoofing
Podatność na DNS spoofing w przypadku Nginx jest wykonalna 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. Metoda ta jednak nie działa, jeśli Nginx jest skonfigurowany do korzystania z localhost (127.0.0.1) do rozwiązywania nazw DNS. Nginx pozwala określić serwer DNS w następujący sposób:
resolver 8.8.8.8;
Dyrektywy proxy_pass
i internal
Dyrektywa proxy_pass
jest wykorzystywana do przekierowywania żądań do innych serwerów, zarówno wewnętrznie, jak i zewnętrznie. Dyrektywa internal
zapewnia, że określone lokalizacje są dostępne tylko w obrębie Nginx. Chociaż te dyrektywy same w sobie nie stanowią podatności, ich konfiguracja wymaga dokładnego 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, atak h2c Smuggling może zostać przeprowadzony w celu uzyskania dostępu do chronionych/wewnętrznych punktów końcowych.
{% hint style="danger" %}
Ta podatność pozwoliłaby atakującemu ustanowić bezpośrednie połączenie z punktem końcowym proxy_pass
(http://backend:9999
w tym przypadku), którego zawartość nie zostanie sprawdzona przez nginx.
{% endhint %}
Przykład podatnej konfiguracji do kradzieży /flag
znajdziesz tutaj:
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 określoną ś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 dowolną inną ścieżką wewnątrz tego wewnętrznego punktu końcowego. Dlatego nie ma znaczenia, czy ścieżka jest określona w adresie URL proxy_pass.
{% endhint %}
Wypróbuj to samodzielnie
Detectify stworzył repozytorium na GitHubie, gdzie możesz użyć Dockera, aby skonfigurować własny podatny serwer testowy Nginx z niektórymi błędami konfiguracji omówionymi w tym artykule i spróbować je znaleźć samodzielnie!
https://github.com/detectify/vulnerable-nginx
Narzędzia analizy statycznej
GIXY
Gixy to narzędzie do analizy konfiguracji Nginx. Głównym celem Gixy jest zapobieganie błędom konfiguracji związanych z bezpieczeństwem i automatyzacja wykrywania wad.
Nginxpwner
Nginxpwner to proste narzędzie do wyszukiwania powszechnych błędów konfiguracyjnych i podatności Nginx.
Odnośniki
- https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/
- http://blog.zorinaq.com/nginx-resolver-vulns/
- https://github.com/yandex/gixy/issues/115
Natychmiastowa dostępność konfiguracji do oceny podatności i testów penetracyjnych. Uruchom pełny test penetracyjny z dowolnego miejsca za pomocą ponad 20 narzędzi i funkcji, które obejmują rozpoznanie, raportowanie. Nie zastępujemy testerów penetracyjnych - rozwijamy niestandardowe narzędzia, moduły wykrywania i eksploatacji, aby umożliwić im zagłębianie się głębiej, przejmowanie kontroli i dobrą zabawę.
{% embed url="https://pentest-tools.com/" %}
Dowiedz się, jak hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź PLANY SUBSKRYPCYJNE!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud github repos.