mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/network-services-pentesting/pentesting-web/nginx.md'] t
This commit is contained in:
parent
4f1b0772e5
commit
6a114dd215
BIN
src/images/nginx_try_files.png
Normal file
BIN
src/images/nginx_try_files.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 190 KiB |
@ -30,7 +30,7 @@ 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 :
|
||||
Pour atténuer cette vulnérabilité, la configuration doit être ajustée à :
|
||||
```
|
||||
location /imgs/ {
|
||||
alias /path/images/;
|
||||
@ -48,7 +48,7 @@ alias../ => HTTP status code 403
|
||||
```
|
||||
## Restriction de chemin non sécurisé <a href="#unsafe-variable-use" id="unsafe-variable-use"></a>
|
||||
|
||||
Check the following page to learn how to bypass directives like:
|
||||
Consultez la page suivante pour apprendre à contourner des directives telles que :
|
||||
```plaintext
|
||||
location = /admin {
|
||||
deny all;
|
||||
@ -93,7 +93,7 @@ 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/](https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/).
|
||||
|
||||
Cette technique est également [**expliquée dans cette présentation**](https://www.youtube.com/watch?v=gWQyWdZbdoY&list=PL0xCSYnG_iTtJe2V6PQqamBF73n7-f1Nr&index=77) 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 :
|
||||
Cette technique est également [**expliquée dans cette présentation**](https://www.youtube.com/watch?v=gWQyWdZbdoY&list=PL0xCSYnG_iTtJe2V6PQqamBF73n7-f1Nr&index=77) 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 boîte noire, vous pourriez utiliser ces requêtes :
|
||||
|
||||
- `https://example.com/%20X` - Tout code HTTP
|
||||
- `https://example.com/%20H` - 400 Bad Request
|
||||
@ -127,15 +127,65 @@ 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](https://hackerone.com/reports/370094). 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](https://github.com/nginx/nginx/blob/2187586207e1465d289ae64cedc829719a048a39/src/http/modules/ngx_http_ssi_filter_module.c#L365), pinpointant les Server Side Includes (SSI) comme la cause principale.
|
||||
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](https://hackerone.com/reports/370094). 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 source de Nginx](https://github.com/nginx/nginx/blob/2187586207e1465d289ae64cedc829719a048a39/src/http/modules/ngx_http_ssi_filter_module.c#L365), 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 :
|
||||
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 variable :
|
||||
```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
|
||||
### Utilisation de try_files avec les variables $URI$ARGS
|
||||
|
||||
La mauvaise configuration suivante de Nginx peut conduire à une vulnérabilité LFI :
|
||||
```
|
||||
location / {
|
||||
try_files $uri$args $uri$args/ /index.html;
|
||||
}
|
||||
```
|
||||
Dans notre configuration, nous avons la directive `try_files` qui est utilisée pour vérifier l'existence de fichiers dans un ordre spécifié. Nginx servira le premier qu'il trouvera. La syntaxe de base de la directive `try_files` est la suivante :
|
||||
```
|
||||
try_files file1 file2 ... fileN fallback;
|
||||
```
|
||||
Nginx vérifiera l'existence de chaque fichier dans l'ordre spécifié. Si un fichier existe, il sera servi immédiatement. Si aucun des fichiers spécifiés n'existe, la requête sera transmise à l'option de secours, qui peut être un autre URI ou une page d'erreur spécifique.
|
||||
|
||||
Cependant, lors de l'utilisation des variables `$uri$args` dans cette directive, Nginx essaiera de rechercher un fichier qui correspond à l'URI de la requête combinée avec les arguments de chaîne de requête. Par conséquent, nous pouvons exploiter cette configuration :
|
||||
```
|
||||
http {
|
||||
server {
|
||||
root /var/www/html/public;
|
||||
|
||||
location / {
|
||||
try_files $uri$args $uri$args/ /index.html;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Avec la charge utile suivante :
|
||||
```
|
||||
GET /?../../../../../../../../etc/passwd HTTP/1.1
|
||||
Host: example.com
|
||||
```
|
||||
En utilisant notre payload, nous allons échapper au répertoire racine (défini dans la configuration Nginx) et charger le fichier `/etc/passwd`. Dans les journaux de débogage, nous pouvons observer comment Nginx essaie les fichiers :
|
||||
```
|
||||
...SNIP...
|
||||
|
||||
2025/07/11 15:49:16 [debug] 79694#79694: *4 trying to use file: "/../../../../../../../../etc/passwd" "/var/www/html/public/../../../../../../../../etc/passwd"
|
||||
2025/07/11 15:49:16 [debug] 79694#79694: *4 try file uri: "/../../../../../../../../etc/passwd"
|
||||
|
||||
...SNIP...
|
||||
|
||||
2025/07/11 15:49:16 [debug] 79694#79694: *4 http filename: "/var/www/html/public/../../../../../../../../etc/passwd"
|
||||
|
||||
...SNIP...
|
||||
|
||||
2025/07/11 15:49:16 [debug] 79694#79694: *4 HTTP/1.1 200 OK
|
||||
|
||||
```
|
||||
PoC contre Nginx utilisant la configuration mentionnée ci-dessus :
|
||||

|
||||
|
||||
## Lecture brute de la réponse 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.
|
||||
|
||||
@ -160,7 +210,7 @@ Lorsqu'une requête `GET` valide est effectuée, Nginx la traite normalement, re
|
||||
|
||||
## 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.
|
||||
Par défaut, la **directive `merge_slashes` de Nginx** est définie 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 sujettes aux attaques d'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.
|
||||
|
||||
@ -176,7 +226,7 @@ Comme indiqué dans [**cet article**](https://mizu.re/post/cors-playground), il
|
||||
- `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).
|
||||
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 en sorte que Nginx envoie le contenu de **`/.env`** (Path Traversal).
|
||||
|
||||
### **Valeur par défaut dans la directive Map**
|
||||
|
||||
@ -209,7 +259,7 @@ 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é.
|
||||
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 attentif pour éviter des lacunes de sécurité.
|
||||
|
||||
## proxy_set_header Upgrade & Connection
|
||||
|
||||
@ -239,11 +289,11 @@ 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.**
|
||||
> 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 si un chemin est 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 !
|
||||
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 erreurs de configuration discutées dans cet article et essayer de les trouver vous-même !
|
||||
|
||||
[https://github.com/detectify/vulnerable-nginx](https://github.com/detectify/vulnerable-nginx)
|
||||
|
||||
@ -251,11 +301,11 @@ Detectify a créé un dépôt GitHub où vous pouvez utiliser Docker pour config
|
||||
|
||||
### [GIXY](https://github.com/yandex/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.
|
||||
Gixy est un outil pour analyser la configuration Nginx. L'objectif principal de Gixy est de prévenir les erreurs de configuration de sécurité et d'automatiser la détection des défauts.
|
||||
|
||||
### [Nginxpwner](https://github.com/stark0de/nginxpwner)
|
||||
|
||||
Nginxpwner est un outil simple pour rechercher des mauvaises configurations et des vulnérabilités courantes de Nginx.
|
||||
Nginxpwner est un outil simple pour rechercher des erreurs de configuration et des vulnérabilités courantes de Nginx.
|
||||
|
||||
## Références
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user