mirror of
https://github.com/carlospolop/hacktricks
synced 2025-01-05 17:58:50 +00:00
290 lines
18 KiB
Markdown
290 lines
18 KiB
Markdown
# Nginx
|
||
|
||
<details>
|
||
|
||
<summary><strong>Aprende hacking en AWS desde cero hasta experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Experto en Equipos Rojos de AWS de HackTricks)</strong></a><strong>!</strong></summary>
|
||
|
||
Otras formas de apoyar a HackTricks:
|
||
|
||
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
||
* Obtén el [**oficial PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Comparte tus trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositorios de github.
|
||
|
||
</details>
|
||
|
||
<figure><img src="../../.gitbook/assets/image (2) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
**Configuración instantánea disponible para evaluación de vulnerabilidades y pruebas de penetración**. Ejecuta una prueba de penetración completa desde cualquier lugar con más de 20 herramientas y funciones que van desde la recolección de información hasta la generación de informes. No reemplazamos a los pentesters, desarrollamos herramientas personalizadas, módulos de detección y explotación para darles tiempo para profundizar, abrir shells y divertirse.
|
||
|
||
{% embed url="https://pentest-tools.com/" %}
|
||
|
||
## Falta la ubicación raíz <a href="#missing-root-location" id="missing-root-location"></a>
|
||
|
||
## **Aspectos esenciales de la configuración del directorio raíz de Nginx**
|
||
|
||
Al configurar el servidor Nginx, la **directiva root** juega un papel crítico al definir el directorio base desde el cual se sirven los archivos. Considera el ejemplo a continuación:
|
||
```bash
|
||
server {
|
||
root /etc/nginx;
|
||
|
||
location /hello.txt {
|
||
try_files $uri $uri/ =404;
|
||
proxy_pass http://127.0.0.1:8080/;
|
||
}
|
||
}
|
||
```
|
||
En esta configuración, `/etc/nginx` está designado como el directorio raíz. Esta configuración permite acceder a archivos dentro del directorio raíz especificado, como `/hello.txt`. Sin embargo, es crucial tener en cuenta que solo se define una ubicación específica (`/hello.txt`). No hay configuración para la ubicación raíz (`location / {...}`). Esta omisión significa que la directiva raíz se aplica globalmente, lo que permite que las solicitudes al camino raíz `/` accedan a archivos bajo `/etc/nginx`.
|
||
|
||
Esta configuración plantea una consideración de seguridad crítica. Una simple solicitud `GET`, como `GET /nginx.conf`, podría exponer información sensible al servir el archivo de configuración de Nginx ubicado en `/etc/nginx/nginx.conf`. Establecer la raíz en un directorio menos sensible, como `/etc`, podría mitigar este riesgo, sin embargo, aún podría permitir el acceso no deseado a otros archivos críticos, incluidos otros archivos de configuración, registros de acceso e incluso credenciales encriptadas utilizadas para la autenticación básica de HTTP.
|
||
|
||
## Configuración Incorrecta de Alias LFI <a href="#alias-lfi-misconfiguration" id="alias-lfi-misconfiguration"></a>
|
||
|
||
En los archivos de configuración de Nginx, se justifica una inspección detallada de las directivas "location". Una vulnerabilidad conocida como Inclusión Local de Archivos (LFI) puede introducirse inadvertidamente a través de una configuración que se asemeja a la siguiente:
|
||
```
|
||
location /imgs {
|
||
alias /path/images/;
|
||
}
|
||
```
|
||
Esta configuración es propensa a ataques de LFI debido a que el servidor interpreta solicitudes como `/imgs../flag.txt` como un intento de acceder a archivos fuera del directorio previsto, resolviendo efectivamente a `/path/images/../flag.txt`. Esta falla permite a los atacantes recuperar archivos del sistema de archivos del servidor que no deberían ser accesibles a través de la web.
|
||
|
||
Para mitigar esta vulnerabilidad, la configuración debe ajustarse a:
|
||
```
|
||
location /imgs/ {
|
||
alias /path/images/;
|
||
}
|
||
```
|
||
Más información: [https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/](https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/)
|
||
|
||
Pruebas de 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
|
||
```
|
||
## Restricción de ruta insegura <a href="#uso-de-variable-insegura" id="uso-de-variable-insegura"></a>
|
||
|
||
Consulte la siguiente página para aprender cómo evadir directivas como:
|
||
```plaintext
|
||
location = /admin {
|
||
deny all;
|
||
}
|
||
|
||
location = /admin/ {
|
||
deny all;
|
||
}
|
||
```
|
||
## Uso inseguro de variables / División de solicitudes HTTP <a href="#unsafe-variable-use" id="unsafe-variable-use"></a>
|
||
|
||
{% hint style="danger" %}
|
||
Las variables vulnerables `$uri` y `$document_uri` deben ser reemplazadas por `$request_uri`.
|
||
|
||
Una expresión regular también puede ser vulnerable como:
|
||
|
||
`location ~ /docs/([^/])? { … $1 … }` - Vulnerable 
|
||
|
||
`location ~ /docs/([^/\s])? { … $1 … }` - No vulnerable (verificación de espacios)
|
||
|
||
`location ~ /docs/(.*)? { … $1 … }` - No vulnerable
|
||
{% endhint %}
|
||
|
||
Se demuestra una vulnerabilidad en la configuración de Nginx en el siguiente ejemplo:
|
||
```
|
||
location / {
|
||
return 302 https://example.com$uri;
|
||
}
|
||
```
|
||
Los caracteres \r (retorno de carro) y \n (avance de línea) significan caracteres de nueva línea en las solicitudes HTTP, y sus formas codificadas en URL se representan como `%0d%0a`. Incluir estos caracteres en una solicitud (por ejemplo, `http://localhost/%0d%0aDetectify:%20clrf`) a un servidor mal configurado resulta en que el servidor emita una nueva cabecera llamada `Detectify`. Esto sucede porque la variable $uri decodifica los caracteres de nueva línea codificados en URL, lo que lleva a una cabecera inesperada en la respuesta:
|
||
```
|
||
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
|
||
```
|
||
Aprende más sobre los riesgos de la inyección CRLF y la división de respuestas en [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/).
|
||
|
||
Además, esta técnica se [**explica en esta charla**](https://www.youtube.com/watch?v=gWQyWdZbdoY\&list=PL0xCSYnG\_iTtJe2V6PQqamBF73n7-f1Nr\&index=77) con algunos ejemplos vulnerables y mecanismos de detección. Por ejemplo, para detectar esta mala configuración desde una perspectiva de caja negra, podrías usar estas solicitudes:
|
||
|
||
- `https://example.com/%20X` - Cualquier código HTTP
|
||
- `https://example.com/%20H` - 400 Solicitud incorrecta
|
||
|
||
Si es vulnerable, la primera devolverá "X" ya que es cualquier método HTTP y la segunda devolverá un error ya que H no es un método válido. Por lo tanto, el servidor recibirá algo como: `GET / H HTTP/1.1` y esto desencadenará el error.
|
||
|
||
Otros ejemplos de detección serían:
|
||
|
||
- `http://company.tld/%20HTTP/1.1%0D%0AXXXX:%20x` - Cualquier código HTTP
|
||
- `http://company.tld/%20HTTP/1.1%0D%0AHost:%20x` - 400 Solicitud incorrecta
|
||
|
||
Algunas configuraciones vulnerables encontradas presentadas en esa charla fueron:
|
||
|
||
- Observa cómo **`$uri`** se establece tal cual en la URL final.
|
||
```
|
||
location ^~ /lite/api/ {
|
||
proxy_pass http://lite-backend$uri$is_args$args;
|
||
}
|
||
```
|
||
* Observa cómo nuevamente **`$uri`** está en la URL (esta vez dentro de un parámetro)
|
||
```
|
||
location ~ ^/dna/payment {
|
||
rewrite ^/dna/([^/]+) /registered/main.pl?cmd=unifiedPayment&context=$1&native_uri=$uri break;
|
||
proxy_pass http://$back;
|
||
```
|
||
* Ahora en AWS S3
|
||
```
|
||
location /s3/ {
|
||
proxy_pass https://company-bucket.s3.amazonaws.com$uri;
|
||
}
|
||
```
|
||
### Cualquier variable
|
||
|
||
Se descubrió que los **datos proporcionados por el usuario** podrían ser tratados como una **variable de Nginx** en ciertas circunstancias. La causa de este comportamiento sigue siendo algo esquiva, sin embargo, no es rara ni sencilla de verificar. Esta anomalía fue resaltada en un informe de seguridad en HackerOne, el cual se puede ver [aquí](https://hackerone.com/reports/370094). Una investigación más profunda sobre el mensaje de error llevó a la identificación de su ocurrencia dentro del [módulo de filtro SSI del código base de Nginx](https://github.com/nginx/nginx/blob/2187586207e1465d289ae64cedc829719a048a39/src/http/modules/ngx\_http\_ssi\_filter\_module.c#L365), señalando a las Inclusiones del Lado del Servidor (SSI) como la causa raíz.
|
||
|
||
Para **detectar esta mala configuración**, se puede ejecutar el siguiente comando, que implica establecer un encabezado de referencia para probar la impresión de variables:
|
||
```bash
|
||
$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’
|
||
```
|
||
Escaneos para esta mala configuración en los sistemas revelaron múltiples instancias donde variables de Nginx podrían ser impresas por un usuario. Sin embargo, una disminución en el número de instancias vulnerables sugiere que los esfuerzos para parchar este problema han sido algo exitosos.
|
||
|
||
## Lectura de respuesta en bruto del backend
|
||
|
||
Nginx ofrece una característica a través de `proxy_pass` que permite la intercepción de errores y encabezados HTTP producidos por el backend, con el objetivo de ocultar mensajes de error y encabezados internos. Esto se logra mediante Nginx sirviendo páginas de error personalizadas en respuesta a errores del backend. Sin embargo, surgen desafíos cuando Nginx se encuentra con una solicitud HTTP inválida. Tal solicitud se reenvía al backend tal como se recibió, y la respuesta en bruto del backend se envía directamente al cliente sin intervención de Nginx.
|
||
|
||
Considere un escenario de ejemplo que involucra una aplicación 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!"]
|
||
```
|
||
Para gestionar esto, se utilizan directivas específicas en la configuración de Nginx:
|
||
```
|
||
http {
|
||
error_page 500 /html/error.html;
|
||
proxy_intercept_errors on;
|
||
proxy_hide_header Secret-Header;
|
||
}
|
||
```
|
||
* [**proxy\_intercept\_errors**](http://nginx.org/en/docs/http/ngx\_http\_proxy\_module.html#proxy\_intercept\_errors): Esta directiva permite a Nginx servir una respuesta personalizada para respuestas del servidor con un código de estado mayor a 300. Asegura que, para nuestro ejemplo de aplicación uWSGI, una respuesta de `Error 500` sea interceptada y manejada por Nginx.
|
||
* [**proxy\_hide\_header**](http://nginx.org/en/docs/http/ngx\_http\_proxy\_module.html#proxy\_hide\_header): Como su nombre sugiere, esta directiva oculta encabezados HTTP especificados al cliente, mejorando la privacidad y seguridad.
|
||
|
||
Cuando se realiza una solicitud `GET` válida, Nginx la procesa normalmente, devolviendo una respuesta de error estándar sin revelar ningún encabezado secreto. Sin embargo, una solicitud HTTP no válida evade este mecanismo, lo que resulta en la exposición de respuestas del servidor en bruto, incluidos encabezados secretos y mensajes de error.
|
||
|
||
## merge\_slashes establecido en off
|
||
|
||
Por defecto, la directiva **`merge_slashes` de Nginx** está establecida en **`on`**, lo que comprime múltiples barras inclinadas en una URL en una sola barra. Esta característica, si bien agiliza el procesamiento de URL, puede ocultar inadvertidamente vulnerabilidades en aplicaciones detrás de Nginx, especialmente aquellas propensas a ataques de inclusión de archivos locales (LFI). Los expertos en seguridad **Danny Robinson y Rotem Bar** han destacado los riesgos potenciales asociados con este comportamiento predeterminado, especialmente cuando Nginx actúa como un proxy inverso.
|
||
|
||
Para mitigar tales riesgos, se recomienda **desactivar la directiva `merge_slashes`** para aplicaciones susceptibles a estas vulnerabilidades. Esto asegura que Nginx reenvíe las solicitudes a la aplicación sin alterar la estructura de la URL, evitando así ocultar problemas de seguridad subyacentes.
|
||
|
||
Para obtener más información, consulta [Danny Robinson y Rotem Bar](https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d).
|
||
|
||
### **Valor predeterminado en la directiva Map**
|
||
|
||
En la **configuración de Nginx**, la directiva `map` a menudo desempeña un papel en el **control de autorización**. Un error común es no especificar un valor **predeterminado**, lo que podría resultar en acceso no autorizado. Por ejemplo:
|
||
```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";
|
||
}
|
||
}
|
||
```
|
||
Sin un `default`, un **usuario malicioso** puede evadir la seguridad accediendo a una **URI no definida** dentro de `/map-poc`. [El manual de Nginx](https://nginx.org/en/docs/http/ngx\_http\_map\_module.html) recomienda establecer un **valor predeterminado** para evitar este tipo de problemas.
|
||
|
||
### **Vulnerabilidad de Suplantación de DNS**
|
||
|
||
La suplantación de DNS contra Nginx es factible bajo ciertas condiciones. Si un atacante conoce el **servidor DNS** utilizado por Nginx y puede interceptar sus consultas DNS, puede suplantar registros DNS. Sin embargo, este método es ineficaz si Nginx está configurado para usar **localhost (127.0.0.1)** para la resolución DNS. Nginx permite especificar un servidor DNS de la siguiente manera:
|
||
```yaml
|
||
resolver 8.8.8.8;
|
||
```
|
||
### Directivas `proxy_pass` e `internal`
|
||
|
||
La directiva **`proxy_pass`** se utiliza para redirigir solicitudes a otros servidores, ya sea interna o externamente. La directiva **`internal`** asegura que ciertas ubicaciones solo sean accesibles dentro de Nginx. Si bien estas directivas no son vulnerabilidades por sí mismas, su configuración requiere un examen cuidadoso para prevenir fallos de seguridad.
|
||
|
||
## proxy\_set\_header Upgrade & Connection
|
||
|
||
Si el servidor nginx está configurado para pasar los encabezados Upgrade y Connection, se podría realizar un [**ataque de Smuggling h2c**](../../pentesting-web/h2c-smuggling.md) para acceder a puntos finales protegidos/internos.
|
||
|
||
{% hint style="danger" %}
|
||
Esta vulnerabilidad permitiría a un atacante **establecer una conexión directa con el punto final de `proxy_pass`** (`http://backend:9999` en este caso) cuyo contenido no será verificado por nginx.
|
||
{% endhint %}
|
||
|
||
Ejemplo de configuración vulnerable para robar `/flag` desde [aquí](https://bishopfox.com/blog/h2c-smuggling-request):
|
||
```
|
||
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" %}
|
||
Ten en cuenta que incluso si `proxy_pass` apunta a una **ruta** específica como `http://backend:9999/socket.io`, la conexión se establecerá con `http://backend:9999`, por lo que puedes **acceder a cualquier otra ruta dentro de ese punto final interno. Por lo tanto, no importa si se especifica una ruta en la URL de proxy\_pass.**
|
||
{% endhint %}
|
||
|
||
## Pruébalo tú mismo
|
||
|
||
Detectify ha creado un repositorio en GitHub donde puedes usar Docker para configurar tu propio servidor de prueba vulnerable de Nginx con algunas de las configuraciones incorrectas discutidas en este artículo ¡y tratar de encontrarlas tú mismo!
|
||
|
||
[https://github.com/detectify/vulnerable-nginx](https://github.com/detectify/vulnerable-nginx)
|
||
|
||
## Herramientas de análisis estático
|
||
|
||
### [GIXY](https://github.com/yandex/gixy)
|
||
|
||
Gixy es una herramienta para analizar la configuración de Nginx. El objetivo principal de Gixy es prevenir la configuración incorrecta de seguridad y automatizar la detección de fallas.
|
||
|
||
### [Nginxpwner](https://github.com/stark0de/nginxpwner)
|
||
|
||
Nginxpwner es una herramienta simple para buscar configuraciones incorrectas y vulnerabilidades comunes en Nginx.
|
||
|
||
## Referencias
|
||
|
||
* [**https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/**](https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/)
|
||
* [**http://blog.zorinaq.com/nginx-resolver-vulns/**](http://blog.zorinaq.com/nginx-resolver-vulns/)
|
||
* [**https://github.com/yandex/gixy/issues/115**](https://github.com/yandex/gixy/issues/115)
|
||
|
||
<figure><img src="../../.gitbook/assets/image (2) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
**Configuración instantáneamente disponible para evaluación de vulnerabilidades y pruebas de penetración**. Ejecuta una prueba de penetración completa desde cualquier lugar con más de 20 herramientas y funciones que van desde la recolección de información hasta la generación de informes. No reemplazamos a los pentesters, desarrollamos herramientas personalizadas, módulos de detección y explotación para darles tiempo para profundizar, obtener acceso y divertirse.
|
||
|
||
{% embed url="https://pentest-tools.com/" %}
|
||
|
||
<details>
|
||
|
||
<summary><strong>Aprende hacking en AWS desde cero hasta experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
Otras formas de apoyar a HackTricks:
|
||
|
||
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF**, ¡consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
||
* Obtén la [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
|
||
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Comparte tus trucos de hacking enviando PRs a los repositorios de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||
|
||
</details>
|