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, aż po raportowanie. Nie zastępujemy pentesterów - rozwijamy niestandardowe narzędzia, moduły wykrywania i eksploatacji, aby umożliwić im zagłębienie się głębiej, przejęcie kontroli 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. Ta konfiguracja 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 omissja 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. Prosty żądanie GET
, na przykład GET /nginx.conf
, może ujawnić poufne informacje poprzez udostępnienie pliku konfiguracyjnego Nginx znajdującego się w /etc/nginx/nginx.conf
. Ustawienie roota na mniej wrażliwy katalog, na przykład /etc
, może zmniejszyć to ryzyko, ale nadal może umożliwiać niezamierzony dostęp 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ższy przykład:
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 spoza zamierzonego katalogu, 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 ich zastąpienie przez $request_uri
.
Regex może również być podatne, na przykład:
location ~ /docs/([^/])? { … $1 … }
- Narażone
location ~ /docs/([^/\s])? { … $1 … }
- Niepodatne (sprawdzanie spacji)
location ~ /docs/(.*)? { … $1 … }
- Niepodatne
{% endhint %}
Przykład podatności w konfiguracji Nginx jest przedstawiony poniżej:
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 są reprezentowane jako %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ż "X" 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 rzadka ani łatwa do zweryfikowania. To anomalie zostało podkreślone w raporcie bezpieczeństwa na HackerOne, który można zobaczyć tutaj. Dalsze dochodzenie w sprawie komunikatu o błędzie doprowadziło do zidentyfikowania jego występowania 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ć następujące polecenie, które 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 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 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 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 backendu z kodem stanu większym niż 300. Zapewnia, ż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, poprawiają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 poufnych nagłówków. Jednakże nieprawidłowe żądanie HTTP omija ten mechanizm, co skutkuje ujawnieniem surowych odpowiedzi z backendu, w tym poufnych 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 w aplikacjach za Nginx, 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 konfiguracyjnymi omówionymi w tym artykule i spróbować je znaleźć samodzielnie!
https://github.com/detectify/vulnerable-nginx
Narzędzia do 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 pentesterów - rozwijamy niestandardowe narzędzia, moduły wykrywania i eksploatacji, aby umożliwić im zagłębienie się głębiej, zdobycie dostępu 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 do HackTricks i HackTricks Cloud github repos.