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
- VĂ©rifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PRs au HackTricks et HackTricks Cloud dépÎts github.
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 :
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:
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 HTTPhttps://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 HTTPhttp://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 :
$ 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 :
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 :
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";
}
}
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 :
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
- https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/
- http://blog.zorinaq.com/nginx-resolver-vulns/
- https://github.com/yandex/gixy/issues/115
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
- VĂ©rifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PRs au HackTricks et HackTricks Cloud dépÎts github.