Nginx

Reading time: 13 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks

Missing root location

Lors de la configuration du serveur Nginx, la directive root joue un rÎle crucial en définissant le répertoire de base à partir duquel les fichiers sont servis. Considérez l'exemple ci-dessous :

bash
server {
root /etc/nginx;

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

Dans cette configuration, /etc/nginx est dĂ©signĂ© comme le rĂ©pertoire racine. Cette configuration permet l'accĂšs aux fichiers dans le rĂ©pertoire racine spĂ©cifiĂ©, comme /hello.txt. Cependant, il est crucial de noter qu'un emplacement spĂ©cifique (/hello.txt) est dĂ©fini. Il n'y a pas de configuration pour l'emplacement racine (location / {...}). Cette omission signifie que la directive racine s'applique globalement, permettant aux requĂȘtes vers le chemin racine / d'accĂ©der aux fichiers sous /etc/nginx.

Une considĂ©ration de sĂ©curitĂ© critique dĂ©coule de cette configuration. Une simple requĂȘte GET, comme GET /nginx.conf, pourrait exposer des informations sensibles en servant le fichier de configuration Nginx situĂ© Ă  /etc/nginx/nginx.conf. DĂ©finir la racine sur un rĂ©pertoire moins sensible, comme /etc, pourrait attĂ©nuer ce risque, mais cela pourrait encore permettre un accĂšs non intentionnel Ă  d'autres fichiers critiques, y compris d'autres fichiers de configuration, des journaux d'accĂšs et mĂȘme des identifiants chiffrĂ©s utilisĂ©s pour l'authentification de base HTTP.

Alias LFI Misconfiguration

Dans les fichiers de configuration de Nginx, une inspection minutieuse est nĂ©cessaire pour les directives "location". Une vulnĂ©rabilitĂ© connue sous le nom d'Inclusion de Fichiers Locaux (LFI) peut ĂȘtre introduite involontairement par une configuration qui ressemble Ă  ce qui suit :

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

Cette configuration est sujette aux attaques LFI en raison de l'interprĂ©tation par le serveur des requĂȘtes comme /imgs../flag.txt comme une tentative d'accĂšs Ă  des fichiers en dehors du rĂ©pertoire prĂ©vu, se rĂ©solvant effectivement en /path/images/../flag.txt. Ce dĂ©faut permet aux attaquants de rĂ©cupĂ©rer des fichiers du systĂšme de fichiers du serveur qui ne devraient pas ĂȘtre accessibles via le web.

Pour attĂ©nuer cette vulnĂ©rabilitĂ©, la configuration doit ĂȘtre ajustĂ©e pour :

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

Plus d'infos : https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/

Tests 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

Restriction de chemin non sécurisé

Check the following page to learn how to bypass directives like:

plaintext
location = /admin {
deny all;
}

location = /admin/ {
deny all;
}

Proxy / WAF Protections Bypass

Utilisation de variables non sĂ©curisĂ©es / Division de requĂȘtes HTTP

caution

Variables vulnĂ©rables $uri et $document_uri et cela peut ĂȘtre corrigĂ© en les remplaçant par $request_uri.

Une regex peut Ă©galement ĂȘtre vulnĂ©rable comme :

location ~ /docs/([^/])? { 
 $1 
 } - Vulnérable

location ~ /docs/([^/\s])? { 
 $1 
 } - Non vulnérable (vérification des espaces)

location ~ /docs/(.*)? { 
 $1 
 } - Non vulnérable

Une vulnérabilité dans la configuration de Nginx est démontrée par l'exemple ci-dessous :

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

Les caractĂšres \r (retour chariot) et \n (saut de ligne) signifient des caractĂšres de nouvelle ligne dans les requĂȘtes HTTP, et leurs formes encodĂ©es en URL sont reprĂ©sentĂ©es par %0d%0a. L'inclusion de ces caractĂšres dans une requĂȘte (par exemple, http://localhost/%0d%0aDetectify:%20clrf) Ă  un serveur mal configurĂ© entraĂźne l'Ă©mission par le serveur d'un nouvel en-tĂȘte nommĂ© Detectify. Cela se produit parce que la variable $uri dĂ©code les caractĂšres de nouvelle ligne encodĂ©s en URL, entraĂźnant un en-tĂȘte inattendu dans la rĂ©ponse :

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

En savoir plus sur les risques d'injection CRLF et de séparation de réponse à https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/.

Cette technique est Ă©galement expliquĂ©e dans cette prĂ©sentation avec des exemples vulnĂ©rables et des mĂ©canismes de dĂ©tection. Par exemple, pour dĂ©tecter cette mauvaise configuration d'un point de vue blackbox, vous pourriez utiliser ces requĂȘtes :

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

Si vulnérable, la premiÚre renverra "X" comme étant n'importe quelle méthode HTTP et la seconde renverra une erreur car H n'est pas une méthode valide. Ainsi, le serveur recevra quelque chose comme : GET / H HTTP/1.1 et cela déclenchera l'erreur.

D'autres exemples de détection seraient :

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

Certaines configurations vulnérables trouvées dans cette présentation étaient :

  • Notez comment $uri est dĂ©fini tel quel dans l'URL finale.
location ^~ /lite/api/ {
proxy_pass http://lite-backend$uri$is_args$args;
}
  • Notez comment Ă  nouveau $uri est dans l'URL (cette fois Ă  l'intĂ©rieur d'un paramĂštre)
location ~ ^/dna/payment {
rewrite ^/dna/([^/]+) /registered/main.pl?cmd=unifiedPayment&context=$1&native_uri=$uri break;
proxy_pass http://$back;
  • Maintenant dans AWS S3
location /s3/ {
proxy_pass https://company-bucket.s3.amazonaws.com$uri;
}

Any variable

Il a Ă©tĂ© dĂ©couvert que les donnĂ©es fournies par l'utilisateur pourraient ĂȘtre traitĂ©es comme une variable Nginx dans certaines circonstances. La cause de ce comportement reste quelque peu insaisissable, mais ce n'est ni rare ni simple Ă  vĂ©rifier. Cette anomalie a Ă©tĂ© mise en Ă©vidence dans un rapport de sĂ©curitĂ© sur HackerOne, qui peut ĂȘtre consultĂ© ici. Une enquĂȘte plus approfondie sur le message d'erreur a conduit Ă  l'identification de son occurrence dans le module de filtre SSI du code de Nginx, pinpointant les Server Side Includes (SSI) comme la cause principale.

Pour dĂ©tecter cette mauvaise configuration, la commande suivante peut ĂȘtre exĂ©cutĂ©e, qui implique de dĂ©finir un en-tĂȘte referer pour tester l'impression de variables :

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

Des analyses de cette mauvaise configuration Ă  travers les systĂšmes ont rĂ©vĂ©lĂ© plusieurs instances oĂč les variables Nginx pouvaient ĂȘtre imprimĂ©es par un utilisateur. Cependant, une diminution du nombre d'instances vulnĂ©rables suggĂšre que les efforts pour corriger ce problĂšme ont Ă©tĂ© quelque peu rĂ©ussis.

Lecture de la réponse brute du backend

Nginx offre une fonctionnalitĂ© via proxy_pass qui permet l'interception des erreurs et des en-tĂȘtes HTTP produits par le backend, visant Ă  cacher les messages d'erreur internes et les en-tĂȘtes. Cela est accompli par Nginx servant des pages d'erreur personnalisĂ©es en rĂ©ponse aux erreurs du backend. Cependant, des dĂ©fis se posent lorsque Nginx rencontre une requĂȘte HTTP invalide. Une telle requĂȘte est transmise au backend telle quelle, et la rĂ©ponse brute du backend est ensuite directement envoyĂ©e au client sans l'intervention de Nginx.

Considérons un scénario d'exemple impliquant une application 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!"]

Pour gérer cela, des directives spécifiques dans la configuration Nginx sont utilisées :

http {
error_page 500 /html/error.html;
proxy_intercept_errors on;
proxy_hide_header Secret-Header;
}
  • proxy_intercept_errors : Cette directive permet Ă  Nginx de servir une rĂ©ponse personnalisĂ©e pour les rĂ©ponses du backend avec un code d'Ă©tat supĂ©rieur Ă  300. Elle garantit que, pour notre exemple d'application uWSGI, une rĂ©ponse 500 Error est interceptĂ©e et gĂ©rĂ©e par Nginx.
  • proxy_hide_header : Comme son nom l'indique, cette directive masque les en-tĂȘtes HTTP spĂ©cifiĂ©s du client, amĂ©liorant ainsi la confidentialitĂ© et la sĂ©curitĂ©.

Lorsqu'une requĂȘte GET valide est effectuĂ©e, Nginx la traite normalement, renvoyant une rĂ©ponse d'erreur standard sans rĂ©vĂ©ler d'en-tĂȘtes secrets. Cependant, une requĂȘte HTTP invalide contourne ce mĂ©canisme, entraĂźnant l'exposition des rĂ©ponses brutes du backend, y compris des en-tĂȘtes secrets et des messages d'erreur.

merge_slashes désactivé

Par défaut, la directive merge_slashes de Nginx est réglée sur on, ce qui compresse plusieurs barres obliques dans une URL en une seule barre oblique. Cette fonctionnalité, tout en rationalisant le traitement des URL, peut involontairement dissimuler des vulnérabilités dans les applications derriÚre Nginx, en particulier celles susceptibles d'attaques par inclusion de fichiers locaux (LFI). Les experts en sécurité Danny Robinson et Rotem Bar ont souligné les risques potentiels associés à ce comportement par défaut, surtout lorsque Nginx agit en tant que reverse-proxy.

Pour attĂ©nuer de tels risques, il est recommandĂ© de dĂ©sactiver la directive merge_slashes pour les applications sensibles Ă  ces vulnĂ©rabilitĂ©s. Cela garantit que Nginx transmet les requĂȘtes Ă  l'application sans modifier la structure de l'URL, Ă©vitant ainsi de masquer d'Ă©ventuels problĂšmes de sĂ©curitĂ© sous-jacents.

Pour plus d'informations, consultez Danny Robinson et Rotem Bar.

En-tĂȘtes de rĂ©ponse Maclicious

Comme indiquĂ© dans cet article, il existe certains en-tĂȘtes qui, s'ils sont prĂ©sents dans la rĂ©ponse du serveur web, modifieront le comportement du proxy Nginx. Vous pouvez les consulter dans la documentation :

  • X-Accel-Redirect : Indique Ă  Nginx de rediriger en interne une requĂȘte vers un emplacement spĂ©cifiĂ©.
  • X-Accel-Buffering : ContrĂŽle si Nginx doit mettre en mĂ©moire tampon la rĂ©ponse ou non.
  • X-Accel-Charset : DĂ©finit le jeu de caractĂšres pour la rĂ©ponse lors de l'utilisation de X-Accel-Redirect.
  • X-Accel-Expires : DĂ©finit le temps d'expiration pour la rĂ©ponse lors de l'utilisation de X-Accel-Redirect.
  • X-Accel-Limit-Rate : Limite le taux de transfert pour les rĂ©ponses lors de l'utilisation de X-Accel-Redirect.

Par exemple, l'en-tĂȘte X-Accel-Redirect provoquera une redirection interne dans Nginx. Ainsi, avoir une configuration Nginx avec quelque chose comme root / et une rĂ©ponse du serveur web avec X-Accel-Redirect: .env fera que Nginx enverra le contenu de /.env (Path Traversal).

Valeur par défaut dans la directive Map

Dans la configuration Nginx, la directive map joue souvent un rÎle dans le contrÎle d'autorisation. Une erreur courante consiste à ne pas spécifier une valeur par défaut, ce qui pourrait entraßner un accÚs non autorisé. Par exemple :

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

Sans un default, un utilisateur malveillant peut contourner la sécurité en accédant à une URI indéfinie dans /map-poc. Le manuel Nginx conseille de définir une valeur par défaut pour éviter de tels problÚmes.

Vulnérabilité au Spoofing DNS

Le spoofing DNS contre Nginx est rĂ©alisable sous certaines conditions. Si un attaquant connaĂźt le serveur DNS utilisĂ© par Nginx et peut intercepter ses requĂȘtes DNS, il peut falsifier des enregistrements DNS. Cette mĂ©thode, cependant, est inefficace si Nginx est configurĂ© pour utiliser localhost (127.0.0.1) pour la rĂ©solution DNS. Nginx permet de spĂ©cifier un serveur DNS comme suit :

yaml
resolver 8.8.8.8;

proxy_pass et directives internal

La directive proxy_pass est utilisĂ©e pour rediriger les requĂȘtes vers d'autres serveurs, que ce soit en interne ou en externe. La directive internal garantit que certains emplacements ne sont accessibles qu'au sein de Nginx. Bien que ces directives ne soient pas des vulnĂ©rabilitĂ©s en elles-mĂȘmes, leur configuration nĂ©cessite un examen minutieux pour Ă©viter des lacunes de sĂ©curitĂ©.

proxy_set_header Upgrade & Connection

Si le serveur nginx est configurĂ© pour passer les en-tĂȘtes Upgrade et Connection, une attaque de Smuggling h2c pourrait ĂȘtre rĂ©alisĂ©e pour accĂ©der Ă  des points de terminaison protĂ©gĂ©s/internes.

caution

Cette vulnérabilité permettrait à un attaquant de stablish a direct connection with the proxy_pass endpoint (http://backend:9999 dans ce cas) dont le contenu ne sera pas vérifié par nginx.

Exemple de configuration vulnérable pour voler /flag depuis ici:

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

warning

Notez que mĂȘme si le proxy_pass pointait vers un chemin spĂ©cifique tel que http://backend:9999/socket.io, la connexion sera Ă©tablie avec http://backend:9999, donc vous pouvez contacter tout autre chemin Ă  l'intĂ©rieur de ce point de terminaison interne. Il n'importe donc pas qu'un chemin soit spĂ©cifiĂ© dans l'URL de proxy_pass.

Essayez par vous-mĂȘme

Detectify a crĂ©Ă© un dĂ©pĂŽt GitHub oĂč vous pouvez utiliser Docker pour configurer votre propre serveur de test Nginx vulnĂ©rable avec certaines des mauvaises configurations discutĂ©es dans cet article et essayer de les trouver vous-mĂȘme !

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

Outils d'analyse statique

GIXY

Gixy est un outil pour analyser la configuration Nginx. L'objectif principal de Gixy est de prévenir les mauvaises configurations de sécurité et d'automatiser la détection des défauts.

Nginxpwner

Nginxpwner est un outil simple pour rechercher des mauvaises configurations et des vulnérabilités courantes de Nginx.

Références

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks