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

18 KiB
Raw Blame History

Nginx

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Trenutno dostupno podešavanje za procenu ranjivosti i testiranje proboja. Pokrenite kompletan pentest od bilo kog mesta sa 20+ alata i funkcija koje idu od izviđanja do izveštavanja. Mi ne zamenjujemo pentestere - mi razvijamo prilagođene alate, module za detekciju i eksploataciju kako bismo im vratili neko vreme da dublje kopaju, otvaraju školjke i zabavljaju se.

{% embed url="https://pentest-tools.com/" %}

Nedostajuća root lokacija

Prilikom konfigurisanja Nginx servera, root direktiva igra ključnu ulogu definisanjem osnovnog direktorijuma iz kog se serviraju fajlovi. Razmotrite primer ispod:

server {
root /etc/nginx;

location /hello.txt {
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8080/;
}
}

U ovoj konfiguraciji, /etc/nginx je određen kao korenski direktorijum. Ova postavka omogućava pristup fajlovima unutar određenog korenskog direktorijuma, poput /hello.txt. Međutim, važno je napomenuti da je definisana samo određena lokacija (/hello.txt). Ne postoji konfiguracija za korensku lokaciju (location / {...}). Ova izostavljena stavka znači da se korenska direktiva primenjuje globalno, omogućavajući zahteve ka korenskom putanji / da pristupaju fajlovima u /etc/nginx.

Iz ove konfiguracije proizilazi kritično sigurnosno pitanje. Jednostavan GET zahtev, poput GET /nginx.conf, mogao bi otkriti osetljive informacije serviranjem Nginx konfiguracionog fajla koji se nalazi na lokaciji /etc/nginx/nginx.conf. Postavljanje korena na manje osetljiv direktorijum, poput /etc, moglo bi umanjiti ovaj rizik, ali i dalje može dozvoliti nenamerno pristup drugim kritičnim fajlovima, uključujući druge konfiguracione fajlove, pristupne logove, pa čak i šifrovane akreditive korišćene za HTTP osnovnu autentifikaciju.

Alias LFI Misconfiguracija

U konfiguracionim fajlovima Nginx-a, potrebno je pažljivo pregledati "location" direktive. Ranjivost poznata kao Lokalno Uključivanje Fajlova (LFI) može biti nenamerno uvedena kroz konfiguraciju koja liči na sledeću:

location /imgs {
alias /path/images/;
}

Ova konfiguracija je podložna LFI napadima zbog servera koji tumači zahteve poput /imgs../flag.txt kao pokušaj pristupa datotekama van namenjenog direktorijuma, efektivno se rešavajući u /path/images/../flag.txt. Ova greška omogućava napadačima da povrate datoteke sa fajl sistema servera koje ne bi trebalo da budu dostupne preko veba.

Da bi se ublažila ova ranjivost, konfiguracija treba da bude prilagođena:

location /imgs/ {
alias /path/images/;
}

Više informacija: https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/

Accunetix testovi:

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

Nebezbedno ograničenje putanje

Proverite sledeću stranicu da biste saznali kako zaobići direktive poput:

location = /admin {
deny all;
}

location = /admin/ {
deny all;
}

Nebezbedna upotreba promenljivih / Razdvajanje HTTP zahteva

{% hint style="danger" %} Ranjive promenljive $uri i $document_uri mogu se popraviti zamenom sa $request_uri.

Regex takođe može biti ranjiv, na primer:

location ~ /docs/([^/])? { … $1 … } - Ranjivo

location ~ /docs/([^/\s])? { … $1 … } - Nije ranjivo (provera razmaka)

location ~ /docs/(.*)? { … $1 … } - Nije ranjivo {% endhint %}

Ranjivost u Nginx konfiguraciji demonstrirana je u primeru ispod:

location / {
return 302 https://example.com$uri;
}

Karakteri \r (Carriage Return) i \n (Line Feed) označavaju nove linije u HTTP zahtevima, a njihove URL enkodirane forme su predstavljene kao %0d%0a. Uključivanje ovih karaktera u zahtev (npr. http://localhost/%0d%0aDetectify:%20clrf) ka neispravno konfigurisanom serveru rezultuje serveru izdavanjem novog zaglavlja nazvanog Detectify. Do ovoga dolazi jer promenljiva $uri dekodira URL enkodirane nove linije, što dovodi do neočekivanog zaglavlja u odgovoru:

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

Saznajte više o rizicima CRLF ubacivanja i razdvajanja odgovora na https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/.

Takođe, ovu tehniku je objašnjena u ovom predavanju na https://www.youtube.com/watch?v=gWQyWdZbdoY&list=PL0xCSYnG_iTtJe2V6PQqamBF73n7-f1Nr&index=77 sa nekim ranjivim primerima i mehanizmima detekcije. Na primer, kako biste otkrili ovu lošu konfiguraciju iz crne kutije perspektive, možete koristiti ove zahteve:

  • https://example.com/%20X - Bilo koji HTTP kod
  • https://example.com/%20H - 400 Bad Request

Ako je ranjiv, prvi će vratiti "X" jer je bilo koji HTTP metod, a drugi će vratiti grešku jer H nije validan metod. Dakle, server će primiti nešto poput: GET / H HTTP/1.1 i to će izazvati grešku.

Još neki primeri detekcije bi bili:

  • http://company.tld/%20HTTP/1.1%0D%0AXXXX:%20x - Bilo koji HTTP kod
  • http://company.tld/%20HTTP/1.1%0D%0AHost:%20x - 400 Bad Request

Neki pronađeni ranjivi konfiguracije prikazani u tom predavanju su:

  • Primetite kako je $uri postavljen kao što je u konačnom URL-u.
location ^~ /lite/api/ {
proxy_pass http://lite-backend$uri$is_args$args;
}
  • Obratite pažnju kako se ponovo $uri nalazi u URL-u (ovaj put unutar parametra)
location ~ ^/dna/payment {
rewrite ^/dna/([^/]+) /registered/main.pl?cmd=unifiedPayment&context=$1&native_uri=$uri break;
proxy_pass http://$back;
  • Sada u AWS S3
location /s3/ {
proxy_pass https://company-bucket.s3.amazonaws.com$uri;
}

Bilo koja promenljiva

Otkriveno je da bi podaci koje je korisnik dostavio mogli biti tretirani kao Nginx promenljiva u određenim okolnostima. Uzrok ovog ponašanja ostaje donekle nejasan, ali nije retko niti jednostavno proveriti. Ova anomalija je istaknuta u izveštaju o bezbednosti na HackerOne platformi, koji možete pogledati ovde. Dalje istraživanje poruke o grešci dovelo je do identifikacije njenog pojavljivanja unutar SSI filter modula Nginx-ove osnove koda, označavajući Server Side Includes (SSI) kao koreni uzrok.

Da biste otkrili ovu lošu konfiguraciju, može se izvršiti sledeća komanda, koja uključuje postavljanje referer zaglavlja radi testiranja ispisa promenljive:

$ curl -H Referer: bar http://localhost/foo$http_referer | grep foobar

Skenovi za ovu konfiguraciju na različitim sistemima otkrili su više slučajeva gde Nginx promenljive mogu biti prikazane od strane korisnika. Međutim, smanjenje broja ranjivih instanci sugeriše da su napori za popravku ovog problema donekle uspešni.

Čitanje sirovog odgovora sa backend-a

Nginx nudi funkciju putem proxy_pass koja omogućava presretanje grešaka i HTTP zaglavlja proizvedenih od strane backend-a, sa ciljem skrivanja internih poruka o greškama i zaglavlja. Ovo se postiže tako što Nginx servira prilagođene stranice grešaka kao odgovor na greške backend-a. Međutim, izazovi se javljaju kada Nginx naiđe na nevažeći HTTP zahtev. Takav zahtev se prosleđuje backend-u onakav kakav je primljen, i sirovi odgovor backend-a se zatim direktno šalje klijentu bez posredovanja Nginx-a.

Razmotrite scenarij koji uključuje uWSGI aplikaciju:

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!"]

Da biste upravljali ovim, koriste se specifične direktive u Nginx konfiguraciji:

http {
error_page 500 /html/error.html;
proxy_intercept_errors on;
proxy_hide_header Secret-Header;
}
  • proxy_intercept_errors: Ova direktiva omogućava Nginx-u da posluži prilagođeni odgovor za odgovore sa servera sa statusnim kodom većim od 300. Osigurava da, za naš primer aplikacije uWSGI, odgovor 500 Error bude presretnut i obrađen od strane Nginx-a.
  • proxy_hide_header: Kao što naziv sugeriše, ova direktiva skriva određene HTTP zaglavlja od klijenta, poboljšavajući privatnost i bezbednost.

Kada se napravi validan GET zahtev, Nginx ga obrađuje na uobičajen način, vraćajući standardni grešni odgovor ne otkrivajući nikakva tajna zaglavlja. Međutim, nevažeći HTTP zahtev zaobilazi ovaj mehanizam, što rezultira izlaganjem sirovih odgovora sa servera, uključujući tajna zaglavlja i poruke o greškama.

merge_slashes postavljen na off

Podrazumevano, merge_slashes direktiva u Nginx-u je postavljena na on, što komprimuje višestruke kosine u URL-u u jednu kosu. Ova funkcija, dok olakšava obradu URL-ova, može nenamerno prikriti ranjivosti u aplikacijama iza Nginx-a, posebno onima sklonim napadima lokalnog uključivanja fajlova (LFI). Bezbednosni stručnjaci Danny Robinson i Rotem Bar su istakli potencijalne rizike povezane sa ovim podrazumevanim ponašanjem, posebno kada Nginx deluje kao reverzni proxy.

Da bi se umanjili takvi rizici, preporučuje se isključivanje merge_slashes direktive za aplikacije koje su podložne ovim ranjivostima. Ovo osigurava da Nginx prosleđuje zahteve aplikaciji bez menjanja strukture URL-a, čime se ne prikrivaju potencijalni sigurnosni problemi.

Za više informacija pogledajte Danny Robinson i Rotem Bar.

Zlonamerna zaglavlja odgovora

Kao što je prikazano u ovom objašnjenju, postoje određena zaglavlja koja, ako su prisutna u odgovoru sa web servera, mogu promeniti ponašanje Nginx proxy-ja. Možete ih proveriti u dokumentaciji:

  • X-Accel-Redirect: Ukazuje Nginx-u da interni preusmeri zahtev na određenu lokaciju.
  • X-Accel-Buffering: Kontroliše da li Nginx treba da baferuje odgovor ili ne.
  • X-Accel-Charset: Postavlja karakter set za odgovor prilikom korišćenja X-Accel-Redirect.
  • X-Accel-Expires: Postavlja vreme isteka za odgovor prilikom korišćenja X-Accel-Redirect.
  • X-Accel-Limit-Rate: Limitira brzinu transfera za odgovore prilikom korišćenja X-Accel-Redirect.

Na primer, zaglavlje X-Accel-Redirect će izazvati interni preusmeraj u Nginx-u. Dakle, imati Nginx konfiguraciju sa nečim poput root / i odgovor sa web servera sa X-Accel-Redirect: .env će naterati Nginx da pošalje sadržaj /.env (Prolazak kroz putanje).

Podrazumevana vrednost u Map direktivi

U Nginx konfiguraciji, map direktiva često igra ulogu u kontroli autorizacije. Česta greška je ne navođenje podrazumevane vrednosti, što može dovesti do neovlašćenog pristupa. Na primer:

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, zlonamerni korisnik može zaobići sigurnost pristupanjem nedefinisanom URI unutar /map-poc. Nginx priručnik savetuje postavljanje podrazumevane vrednosti kako bi se izbegli takvi problemi.

Ranjivost DNS prevara

DNS prevara protiv Nginxa je izvodljiva u određenim uslovima. Ako napadač zna DNS server koji koristi Nginx i može presresti njegove DNS upite, može falsifikovati DNS zapise. Međutim, ovaj metod nije efikasan ako je Nginx konfigurisan da koristi localhost (127.0.0.1) za DNS razrešavanje. Nginx omogućava specificiranje DNS servera na sledeći način:

resolver 8.8.8.8;

proxy_pass и internal Директиве

Директива proxy_pass се koristi za preusmeravanje zahteva ka drugim serverima, bilo interno ili eksterno. internal директива osigurava da određene lokacije budu dostupne samo unutar Nginx-a. Iako same po sebi ove dve dirlktive nisu ranjivosti, njihova konfiguracija zahteva pažljivu analizu kako bi se sprečili sigurnosni propusti.

proxy_set_header Upgrade & Connection

Ako je nginx server konfigurisan da prosleđuje zaglavlja Upgrade i Connection, može se izvesti h2c Smuggling napad kako bi se pristupilo zaštićenim/internim endpointima.

{% hint style="danger" %} Ova ranjivost bi omogućila napadaču da uspostavi direktnu vezu sa proxy_pass endpointom (http://backend:9999 u ovom slučaju) čiji sadržaj neće biti proveren od strane nginx-a. {% endhint %}

Primer ranjive konfiguracije za krađu /flag možete pronaći ovde:

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" %} Imajte na umu da čak i ako je proxy_pass usmeren ka određenom putanji poput http://backend:9999/socket.io veza će biti uspostavljena sa http://backend:9999 tako da možete kontaktirati bilo koju drugu putanju unutar tog internog krajnjeg tačke. Dakle, nije važno da li je putanja navedena u URL-u proxy_pass. {% endhint %}

Probajte sami

Detectify je kreirao GitHub repozitorijum gde možete koristiti Docker da postavite svoj vlastiti ranjivi Nginx test server sa nekim od konfiguracionih grešaka koje su diskutovane u ovom članku i pokušati da ih pronađete sami!

https://github.com/detectify/vulnerable-nginx

Alati za statičku analizu

GIXY

Gixy je alat za analizu Nginx konfiguracije. Glavni cilj Gixy-ja je sprečavanje bezbednosnih konfiguracija i automatizacija otkrivanja grešaka.

Nginxpwner

Nginxpwner je jednostavan alat za traženje uobičajenih Nginx konfiguracionih grešaka i ranjivosti.

Reference

Trenutno dostupna postavka za procenu ranjivosti & testiranje prodiranja. Pokrenite kompletan pentest od bilo kog mesta sa 20+ alata i funkcija koje idu od izviđanja do izveštavanja. Mi ne zamenjujemo pentestere - mi razvijamo prilagođene alate, module za otkrivanje & eksploataciju kako bismo im vratili neko vreme da dublje kopaju, otvaraju ljuske i zabavljaju se.

{% embed url="https://pentest-tools.com/" %}

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u: