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

20 KiB
Raw Blame History

Nginx

{% hint style="success" %} Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Unterstützen Sie HackTricks
{% endhint %}

Sofort verfügbare Einrichtung für Schwachstellenbewertung & Penetrationstests. Führen Sie einen vollständigen Pentest von überall mit über 20 Tools & Funktionen durch, die von Recon bis Reporting reichen. Wir ersetzen keine Pentester - wir entwickeln maßgeschneiderte Tools, Erkennungs- & Ausnutzungs-Module, um ihnen etwas Zeit zurückzugeben, um tiefer zu graben, Shells zu öffnen und Spaß zu haben.

{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}

Fehlender Root-Standort

Bei der Konfiguration des Nginx-Servers spielt die Root-Direktive eine entscheidende Rolle, indem sie das Basisverzeichnis definiert, aus dem Dateien bereitgestellt werden. Betrachten Sie das folgende Beispiel:

server {
root /etc/nginx;

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

In dieser Konfiguration ist /etc/nginx als das Stammverzeichnis festgelegt. Dieses Setup ermöglicht den Zugriff auf Dateien innerhalb des angegebenen Stammverzeichnisses, wie z.B. /hello.txt. Es ist jedoch wichtig zu beachten, dass nur ein spezifischer Ort (/hello.txt) definiert ist. Es gibt keine Konfiguration für den Stammort (location / {...}). Diese Auslassung bedeutet, dass die Stamm-Direktive global gilt, was es Anfragen ermöglicht, auf den Stammpfad / zuzugreifen und Dateien unter /etc/nginx zu erreichen.

Eine kritische Sicherheitsüberlegung ergibt sich aus dieser Konfiguration. Eine einfache GET-Anfrage, wie GET /nginx.conf, könnte sensible Informationen offenlegen, indem die Nginx-Konfigurationsdatei unter /etc/nginx/nginx.conf bereitgestellt wird. Das Setzen des Stammverzeichnisses auf ein weniger sensibles Verzeichnis, wie /etc, könnte dieses Risiko mindern, dennoch könnte es weiterhin unbeabsichtigten Zugriff auf andere kritische Dateien, einschließlich anderer Konfigurationsdateien, Zugriffsprotokolle und sogar verschlüsselter Anmeldeinformationen für die HTTP-Basisauthentifizierung, ermöglichen.

Alias LFI Fehlkonfiguration

In den Konfigurationsdateien von Nginx ist eine genaue Überprüfung der "location"-Direktiven erforderlich. Eine Schwachstelle, die als Local File Inclusion (LFI) bekannt ist, kann unbeabsichtigt durch eine Konfiguration eingeführt werden, die der folgenden ähnelt:

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

Diese Konfiguration ist anfällig für LFI-Angriffe, da der Server Anfragen wie /imgs../flag.txt als Versuch interpretiert, auf Dateien außerhalb des vorgesehenen Verzeichnisses zuzugreifen, was effektiv zu /path/images/../flag.txt aufgelöst wird. Dieser Fehler ermöglicht es Angreifern, Dateien aus dem Dateisystem des Servers abzurufen, die nicht über das Web zugänglich sein sollten.

Um diese Schwachstelle zu mindern, sollte die Konfiguration angepasst werden zu:

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

Mehr Informationen: https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/

Accunetix-Tests:

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

Unsichere Pfadbeschränkung

Überprüfen Sie die folgende Seite, um zu erfahren, wie man Direktiven wie umgeht:

location = /admin {
deny all;
}

location = /admin/ {
deny all;
}

{% content-ref url="../../pentesting-web/proxy-waf-protections-bypass.md" %} proxy-waf-protections-bypass.md {% endcontent-ref %}

Unsichere Variablenverwendung / HTTP-Anforderungsaufteilung

{% hint style="danger" %} Anfällige Variablen $uri und $document_uri und dies kann behoben werden, indem sie durch $request_uri ersetzt werden.

Ein Regex kann ebenfalls anfällig sein wie:

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

location ~ /docs/([^/\s])? { … $1 … } - Nicht anfällig (überprüft Leerzeichen)

location ~ /docs/(.*)? { … $1 … } - Nicht anfällig {% endhint %}

Eine Schwachstelle in der Nginx-Konfiguration wird durch das folgende Beispiel veranschaulicht:

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

Die Zeichen \r (Carriage Return) und \n (Line Feed) kennzeichnen Zeilenumbrüche in HTTP-Anfragen, und ihre URL-kodierten Formen werden als %0d%0a dargestellt. Das Einfügen dieser Zeichen in eine Anfrage (z. B. http://localhost/%0d%0aDetectify:%20clrf) an einen falsch konfigurierten Server führt dazu, dass der Server einen neuen Header mit dem Namen Detectify ausgibt. Dies geschieht, weil die $uri-Variable die URL-kodierten Zeilenumbrüche dekodiert, was zu einem unerwarteten Header in der Antwort führt:

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

Lernen Sie mehr über die Risiken von CRLF-Injection und Response-Splitting unter https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/.

Diese Technik wird auch in diesem Vortrag erklärt mit einigen anfälligen Beispielen und Erkennungsmechanismen. Zum Beispiel, um diese Fehlkonfiguration aus einer Blackbox-Perspektive zu erkennen, könnten Sie diese Anfragen verwenden:

  • https://example.com/%20X - Jeder HTTP-Code
  • https://example.com/%20H - 400 Bad Request

Wenn anfällig, wird die erste als "X" zurückgegeben, da X jede HTTP-Methode ist, und die zweite wird einen Fehler zurückgeben, da H keine gültige Methode ist. Der Server erhält also etwas wie: GET / H HTTP/1.1 und dies wird den Fehler auslösen.

Ein weiteres Erkennungsbeispiel wäre:

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

Einige gefundene anfällige Konfigurationen, die in diesem Vortrag präsentiert wurden, waren:

  • Beachten Sie, wie $uri im endgültigen URL so gesetzt ist, wie es ist.
location ^~ /lite/api/ {
proxy_pass http://lite-backend$uri$is_args$args;
}
  • Beachten Sie, wie erneut $uri in der URL ist (diesmal innerhalb eines Parameters)
location ~ ^/dna/payment {
rewrite ^/dna/([^/]+) /registered/main.pl?cmd=unifiedPayment&context=$1&native_uri=$uri break;
proxy_pass http://$back;
  • Jetzt in AWS S3
location /s3/ {
proxy_pass https://company-bucket.s3.amazonaws.com$uri;
}

Any variable

Es wurde entdeckt, dass benutzereingereichte Daten unter bestimmten Umständen als Nginx-Variable behandelt werden könnten. Die Ursache für dieses Verhalten bleibt etwas unklar, ist jedoch weder selten noch einfach zu überprüfen. Diese Anomalie wurde in einem Sicherheitsbericht auf HackerOne hervorgehoben, der hier eingesehen werden kann. Weitere Untersuchungen der Fehlermeldung führten zur Identifizierung ihres Auftretens innerhalb des SSI-Filtermoduls des Nginx-Codebases, wobei Server Side Includes (SSI) als Hauptursache festgestellt wurden.

Um diese Fehlkonfiguration zu erkennen, kann der folgende Befehl ausgeführt werden, der das Setzen eines Referer-Headers beinhaltet, um das Drucken von Variablen zu testen:

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

Scans für diese Fehlkonfiguration über Systeme hinweg zeigten mehrere Fälle, in denen Nginx-Variablen von einem Benutzer ausgegeben werden konnten. Ein Rückgang der Anzahl der verwundbaren Instanzen deutet jedoch darauf hin, dass die Bemühungen, dieses Problem zu beheben, einigermaßen erfolgreich waren.

Rohes Backend-Antwortlesen

Nginx bietet eine Funktion über proxy_pass, die die Abfangung von Fehlern und HTTP-Headern, die vom Backend erzeugt werden, ermöglicht, um interne Fehlermeldungen und Header zu verbergen. Dies wird erreicht, indem Nginx benutzerdefinierte Fehlerseiten als Antwort auf Backend-Fehler bereitstellt. Herausforderungen treten jedoch auf, wenn Nginx eine ungültige HTTP-Anfrage erhält. Eine solche Anfrage wird unverändert an das Backend weitergeleitet, und die rohe Antwort des Backends wird dann direkt an den Client gesendet, ohne dass Nginx eingreift.

Betrachten Sie ein Beispiel-Szenario mit einer uWSGI-Anwendung:

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

Um dies zu verwalten, werden spezifische Direktiven in der Nginx-Konfiguration verwendet:

http {
error_page 500 /html/error.html;
proxy_intercept_errors on;
proxy_hide_header Secret-Header;
}
  • proxy_intercept_errors: Diese Direktive ermöglicht es Nginx, eine benutzerdefinierte Antwort für Backend-Antworten mit einem Statuscode größer als 300 bereitzustellen. Sie stellt sicher, dass für unsere Beispiel-uWSGI-Anwendung eine 500 Error-Antwort von Nginx abgefangen und verarbeitet wird.
  • proxy_hide_header: Wie der Name schon sagt, verbirgt diese Direktive bestimmte HTTP-Header vor dem Client und verbessert so die Privatsphäre und Sicherheit.

Wenn eine gültige GET-Anfrage gestellt wird, verarbeitet Nginx sie normalerweise und gibt eine standardmäßige Fehlerantwort zurück, ohne geheime Header offenzulegen. Eine ungültige HTTP-Anfrage umgeht jedoch diesen Mechanismus, was zur Offenlegung von rohen Backend-Antworten, einschließlich geheimer Header und Fehlermeldungen, führt.

merge_slashes auf aus gesetzt

Standardmäßig ist die merge_slashes-Direktive von Nginx auf on gesetzt, was mehrere aufeinanderfolgende Schrägstriche in einer URL zu einem einzelnen Schrägstrich komprimiert. Diese Funktion, die die Verarbeitung von URLs optimiert, kann unbeabsichtigt Schwachstellen in Anwendungen hinter Nginx verbergen, insbesondere solche, die anfällig für lokale Datei-Inklusionsangriffe (LFI) sind. Sicherheitsexperten Danny Robinson und Rotem Bar haben die potenziellen Risiken hervorgehoben, die mit diesem Standardverhalten verbunden sind, insbesondere wenn Nginx als Reverse-Proxy fungiert.

Um solche Risiken zu mindern, wird empfohlen, die merge_slashes-Direktive auszuschalten für Anwendungen, die anfällig für diese Schwachstellen sind. Dies stellt sicher, dass Nginx Anfragen an die Anwendung weiterleitet, ohne die URL-Struktur zu ändern, und somit keine zugrunde liegenden Sicherheitsprobleme maskiert.

Für weitere Informationen siehe Danny Robinson und Rotem Bar.

Maclicious Response Headers

Wie in diesem Bericht gezeigt, gibt es bestimmte Header, die, wenn sie in der Antwort des Webservers vorhanden sind, das Verhalten des Nginx-Proxys ändern. Sie können sie in den Dokumenten überprüfen:

  • X-Accel-Redirect: Weist Nginx an, eine Anfrage intern an einen bestimmten Ort weiterzuleiten.
  • X-Accel-Buffering: Steuert, ob Nginx die Antwort puffern soll oder nicht.
  • X-Accel-Charset: Legt den Zeichensatz für die Antwort fest, wenn X-Accel-Redirect verwendet wird.
  • X-Accel-Expires: Legt die Ablaufzeit für die Antwort fest, wenn X-Accel-Redirect verwendet wird.
  • X-Accel-Limit-Rate: Begrenzung der Übertragungsrate für Antworten, wenn X-Accel-Redirect verwendet wird.

Zum Beispiel wird der Header X-Accel-Redirect eine interne Umleitung in Nginx verursachen. Wenn also eine Nginx-Konfiguration mit etwas wie root / und einer Antwort vom Webserver mit X-Accel-Redirect: .env vorhanden ist, wird Nginx den Inhalt von /.env senden (Path Traversal).

Standardwert in der Map-Direktive

In der Nginx-Konfiguration spielt die map-Direktive oft eine Rolle bei der Autorisierungskontrolle. Ein häufiger Fehler besteht darin, keinen Standard-Wert anzugeben, was zu unbefugtem Zugriff führen könnte. Zum Beispiel:

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";
}
}

Ohne ein default kann ein böswilliger Benutzer die Sicherheit umgehen, indem er auf eine nicht definierte URI innerhalb von /map-poc zugreift. Das Nginx-Handbuch empfiehlt, einen Standardwert festzulegen, um solche Probleme zu vermeiden.

DNS Spoofing Verwundbarkeit

DNS-Spoofing gegen Nginx ist unter bestimmten Bedingungen möglich. Wenn ein Angreifer den DNS-Server kennt, der von Nginx verwendet wird, und seine DNS-Abfragen abfangen kann, kann er DNS-Einträge fälschen. Diese Methode ist jedoch ineffektiv, wenn Nginx so konfiguriert ist, dass es localhost (127.0.0.1) für die DNS-Auflösung verwendet. Nginx erlaubt die Angabe eines DNS-Servers wie folgt:

resolver 8.8.8.8;

proxy_pass und internal Direktiven

Die proxy_pass Direktive wird verwendet, um Anfragen an andere Server weiterzuleiten, entweder intern oder extern. Die internal Direktive stellt sicher, dass bestimmte Standorte nur innerhalb von Nginx zugänglich sind. Obwohl diese Direktiven an sich keine Schwachstellen sind, erfordert ihre Konfiguration eine sorgfältige Prüfung, um Sicherheitslücken zu vermeiden.

proxy_set_header Upgrade & Connection

Wenn der Nginx-Server so konfiguriert ist, dass er die Upgrade- und Connection-Header weitergibt, könnte ein h2c Smuggling-Angriff durchgeführt werden, um auf geschützte/interne Endpunkte zuzugreifen.

{% hint style="danger" %} Diese Schwachstelle würde es einem Angreifer ermöglichen, eine direkte Verbindung mit dem proxy_pass Endpunkt (http://backend:9999 in diesem Fall) herzustellen, dessen Inhalt nicht von Nginx überprüft wird. {% endhint %}

Beispiel für eine verwundbare Konfiguration, um /flag von hier zu stehlen:

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" %} Beachten Sie, dass selbst wenn proxy_pass auf einen bestimmten Pfad wie http://backend:9999/socket.io zeigt, die Verbindung mit http://backend:9999 hergestellt wird, sodass Sie jeden anderen Pfad innerhalb dieses internen Endpunkts kontaktieren können. Es spielt also keine Rolle, ob ein Pfad in der URL von proxy_pass angegeben ist. {% endhint %}

Probieren Sie es selbst aus

Detectify hat ein GitHub-Repository erstellt, in dem Sie Docker verwenden können, um Ihren eigenen verwundbaren Nginx-Testserver mit einigen der in diesem Artikel besprochenen Fehlkonfigurationen einzurichten und selbst nach ihnen zu suchen!

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

Statische Analysetools

GIXY

Gixy ist ein Tool zur Analyse der Nginx-Konfiguration. Das Hauptziel von Gixy ist es, Sicherheitsfehlkonfigurationen zu verhindern und die Fehlererkennung zu automatisieren.

Nginxpwner

Nginxpwner ist ein einfaches Tool, um nach häufigen Nginx-Fehlkonfigurationen und -anfälligkeiten zu suchen.

Referenzen

Sofort verfügbare Einrichtung für Schwachstellenbewertung & Penetrationstests. Führen Sie einen vollständigen Pentest von überall mit über 20 Tools und Funktionen durch, die von Recon bis Reporting reichen. Wir ersetzen keine Pentester - wir entwickeln maßgeschneiderte Tools, Erkennungs- und Ausnutzungs-Module, um ihnen etwas Zeit zurückzugeben, um tiefer zu graben, Shells zu öffnen und Spaß zu haben.

{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}

{% hint style="success" %} Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Unterstützen Sie HackTricks
{% endhint %}