mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-23 21:24:06 +00:00
270 lines
16 KiB
Markdown
270 lines
16 KiB
Markdown
# Nginx
|
||
|
||
<details>
|
||
|
||
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
||
|
||
* ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? ¿O quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
||
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* Obtén el [**swag oficial de PEASS y HackTricks**](https://peass.creator-spring.com)
|
||
* **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Comparte tus trucos de hacking enviando PR al** [**repositorio de hacktricks**](https://github.com/carlospolop/hacktricks) **y al** [**repositorio de hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||
|
||
</details>
|
||
|
||
<figure><img src="../../.gitbook/assets/image (1) (1) (2) (4).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
[**DragonJAR Security Conference es un evento internacional de ciberseguridad**](https://www.dragonjarcon.org/) con más de una década que se celebrará el 7 y 8 de septiembre de 2023 en Bogotá, Colombia. Es un evento de gran contenido técnico donde se presentan las últimas investigaciones en español que atrae a hackers e investigadores de todo el mundo.\
|
||
¡Regístrate ahora en el siguiente enlace y no te pierdas esta gran conferencia!:
|
||
|
||
{% embed url="https://www.dragonjarcon.org/" %}
|
||
|
||
## Falta la ubicación raíz <a href="#missing-root-location" id="missing-root-location"></a>
|
||
```
|
||
server {
|
||
root /etc/nginx;
|
||
|
||
location /hello.txt {
|
||
try_files $uri $uri/ =404;
|
||
proxy_pass http://127.0.0.1:8080/;
|
||
}
|
||
}
|
||
```
|
||
La directiva "root" especifica la carpeta raíz para Nginx. En el ejemplo anterior, la carpeta raíz es `/etc/nginx`, lo que significa que podemos acceder a los archivos dentro de esa carpeta. La configuración anterior no tiene una ubicación para `/ (location / {...})`, solo para `/hello.txt`. Debido a esto, la directiva "root" se establecerá globalmente, lo que significa que las solicitudes a `/` lo llevarán a la ruta local `/etc/nginx`.
|
||
|
||
Una solicitud tan simple como `GET /nginx.conf` revelaría el contenido del archivo de configuración de Nginx almacenado en `/etc/nginx/nginx.conf`. Si la raíz se establece en `/etc`, una solicitud `GET` a `/nginx/nginx.conf` revelaría el archivo de configuración. En algunos casos, es posible acceder a otros archivos de configuración, registros de acceso e incluso credenciales cifradas para la autenticación básica de HTTP.
|
||
|
||
## Configuración incorrecta de LFI de Alias <a href="#alias-lfi-misconfiguration" id="alias-lfi-misconfiguration"></a>
|
||
|
||
Dentro de la configuración de Nginx, busque las declaraciones "location", si alguna se parece a:
|
||
```
|
||
location /imgs {
|
||
alias /path/images/;
|
||
}
|
||
```
|
||
Hay una vulnerabilidad de LFI porque:
|
||
```
|
||
/imgs../flag.txt
|
||
```
|
||
El siguiente es contenido de un libro de hacking sobre técnicas de hacking. El siguiente contenido es del archivo network-services-pentesting/pentesting-web/nginx.md. Traduzca el texto relevante en inglés al español y devuelva la traducción manteniendo la sintaxis de markdown. No traduzca cosas como código, nombres de técnicas de hacking, palabras de hacking, nombres de plataformas en la nube / SaaS (como Workspace, aws, gcp ...), la palabra 'leak', pentesting y etiquetas de markdown. Tampoco agregue nada aparte de la traducción y la sintaxis de markdown.
|
||
```
|
||
/path/images/../flag.txt
|
||
```
|
||
La configuración correcta será:
|
||
```
|
||
location /imgs/ {
|
||
alias /path/images/;
|
||
}
|
||
```
|
||
**Entonces, si encuentras algún servidor Nginx, debes verificar esta vulnerabilidad. Además, puedes descubrirla si encuentras que la fuerza bruta de archivos/directorios se comporta de manera extraña.**
|
||
|
||
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
|
||
```
|
||
## Uso inseguro de variables <a href="#unsafe-variable-use" id="unsafe-variable-use"></a>
|
||
|
||
Un ejemplo de una configuración vulnerable de Nginx es:
|
||
```
|
||
location / {
|
||
return 302 https://example.com$uri;
|
||
}
|
||
```
|
||
Los caracteres de nueva línea para las solicitudes HTTP son \r (retorno de carro) y \n (avance de línea). La codificación de URL de los caracteres de nueva línea resulta en la siguiente representación de los caracteres `%0d%0a`. Cuando estos caracteres se incluyen en una solicitud como `http://localhost/%0d%0aDetectify:%20clrf` a un servidor con la configuración incorrecta, el servidor responderá con una nueva cabecera llamada `Detectify` ya que la variable $uri contiene los caracteres de nueva línea decodificados de la URL.
|
||
```
|
||
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
|
||
```
|
||
Aprenda más sobre los riesgos de la inyección de 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/).
|
||
|
||
### Cualquier variable
|
||
|
||
En algunos casos, los datos suministrados por el usuario pueden ser tratados como una variable de Nginx. No está claro por qué puede estar sucediendo esto, pero no es tan poco común o fácil de probar como se ve en este [informe de H1](https://hackerone.com/reports/370094). Si buscamos el mensaje de error, podemos ver que se encuentra en el [módulo de filtro SSI](https://github.com/nginx/nginx/blob/2187586207e1465d289ae64cedc829719a048a39/src/http/modules/ngx\_http\_ssi\_filter\_module.c#L365), lo que revela que esto se debe a SSI.
|
||
|
||
Una forma de probar esto es establecer un valor de encabezado de referencia:
|
||
```
|
||
$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’
|
||
```
|
||
Escaneamos esta mala configuración y encontramos varias instancias donde un usuario podría imprimir el valor de las variables de Nginx. El número de instancias vulnerables encontradas ha disminuido, lo que podría indicar que esto fue parcheado.
|
||
|
||
## Lectura de respuesta de backend sin procesar
|
||
|
||
Con `proxy_pass` de Nginx, existe la posibilidad de interceptar errores y encabezados HTTP creados por el backend. Esto es muy útil si desea ocultar mensajes de error y encabezados internos para que sean manejados por Nginx. Nginx automáticamente servirá una página de error personalizada si el backend responde con una. Pero, ¿qué pasa si Nginx no entiende que es una respuesta HTTP?
|
||
|
||
Si un cliente envía una solicitud HTTP no válida a Nginx, esa solicitud se reenviará tal cual al backend, y el backend responderá con su contenido sin procesar. Entonces, Nginx no entenderá la respuesta HTTP no válida y simplemente la reenviará al cliente. Imagina una aplicación uWSGI como esta:
|
||
```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!"]
|
||
```
|
||
Y con las siguientes directivas en 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) servirá una respuesta personalizada si el backend tiene un estado de respuesta mayor a 300. En nuestra aplicación uWSGI anterior, enviaremos un `Error 500` que será interceptado por Nginx.
|
||
|
||
[proxy\_hide\_header](http://nginx.org/en/docs/http/ngx\_http\_proxy\_module.html#proxy\_hide\_header) es bastante autoexplicativo; ocultará cualquier encabezado HTTP especificado del cliente.
|
||
|
||
Si enviamos una solicitud `GET` normal, Nginx devolverá:
|
||
```
|
||
HTTP/1.1 500 Internal Server Error
|
||
Server: nginx/1.10.3
|
||
Content-Type: text/html
|
||
Content-Length: 34
|
||
Connection: close
|
||
```
|
||
Pero si enviamos una solicitud HTTP inválida, como:
|
||
```
|
||
GET /? XTTP/1.1
|
||
Host: 127.0.0.1
|
||
Connection: close
|
||
```
|
||
Obtendremos la siguiente respuesta:
|
||
```
|
||
XTTP/1.1 500 Error
|
||
Content-Type: text/html
|
||
Secret-Header: secret-info
|
||
|
||
Secret info, should not be visible!
|
||
```
|
||
## merge\_slashes establecido en off
|
||
|
||
La directiva [merge\_slashes](http://nginx.org/en/docs/http/ngx\_http\_core\_module.html#merge\_slashes) está establecida en "on" por defecto, lo que es un mecanismo para comprimir dos o más barras diagonales en una sola, por lo que `///` se convertiría en `/`. Si Nginx se utiliza como proxy inverso y la aplicación que se está proxyando es vulnerable a la inclusión de archivos locales, el uso de barras diagonales adicionales en la solicitud podría dejar espacio para explotarlo. Esto se describe en detalle por [Danny Robinson y Rotem Bar](https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d).
|
||
|
||
Encontramos 33 archivos de configuración de Nginx con `merge_slashes` establecido en "off".
|
||
|
||
## No se especifica el valor por defecto para la directiva map
|
||
|
||
Parece ser un caso común cuando **`map` se utiliza para algún tipo de control de autorización**. Un ejemplo simplificado podría ser:
|
||
```
|
||
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";
|
||
}
|
||
...
|
||
}
|
||
```
|
||
[Según el manual](https://nginx.org/en/docs/http/ngx\_http\_map\_module.html):
|
||
|
||
> valor por defecto\
|
||
> establece el valor resultante si el valor de origen no coincide con ninguna de las variantes especificadas. Cuando no se especifica un valor por defecto, el valor resultante por defecto será una cadena vacía.
|
||
|
||
Es fácil olvidar el valor `default`. Por lo tanto, **un delincuente puede evitar este "control de autorización"** simplemente accediendo a un **caso inexistente dentro de `/map-poc`** como `https://targethost.com/map-poc/another-private-area`.
|
||
|
||
## Suplantación de DNS en Nginx
|
||
|
||
Según este post: [http://blog.zorinaq.com/nginx-resol**ver-vulns/**](http://blog.zorinaq.com/nginx-resolver-vulns/) **podría ser posible falsificar registros DNS** a Nginx si se **conoce el servidor DNS que está usando Nginx** (y se puede interceptar de alguna manera la comunicación, por lo que esto **no es válido si se usa 127.0.0.1**) y el **dominio que está solicitando**.
|
||
|
||
Nginx puede especificar un servidor DNS para usar con:
|
||
```
|
||
resolver 8.8.8.8;
|
||
```
|
||
## Directivas `proxy_pass` e `internal`
|
||
|
||
La directiva **`proxy_pass`** se puede utilizar para **redirigir internamente solicitudes a otros servidores** internos o externos.\
|
||
La directiva **`internal`** se utiliza para dejar claro a Nginx que la **ubicación solo se puede acceder internamente**.
|
||
|
||
El uso de estas directivas **no es una vulnerabilidad, pero se debe verificar cómo están configuradas**.
|
||
|
||
## 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 H2C Smuggling**](../../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 `proxy_pass`** (`http://backend:9999` en este caso) cuyo contenido no será verificado por nginx.
|
||
{% endhint %}
|
||
|
||
Ejemplo de configuración vulnerable para robar `/flag` de [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` apuntaba a una ruta específica como `http://backend:9999/socket.io`, la conexión se establecerá con `http://backend:9999`, por lo que puedes contactar 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 de 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 de 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 (1) (1) (2) (4).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
[**DragonJAR Security Conference es un evento internacional de ciberseguridad**](https://www.dragonjarcon.org/) con más de una década que se celebrará el 7 y 8 de septiembre de 2023 en Bogotá, Colombia. Es un evento de gran contenido técnico donde se presentan las últimas investigaciones en español que atrae a hackers e investigadores de todo el mundo.\
|
||
¡Regístrate ahora en el siguiente enlace y no te pierdas esta gran conferencia!:
|
||
|
||
{% embed url="https://www.dragonjarcon.org/" %}
|
||
|
||
<details>
|
||
|
||
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
||
|
||
* ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? ¿O quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
||
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos.
|
||
* Obtén el [**swag oficial de PEASS y HackTricks**](https://peass.creator-spring.com)
|
||
* **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Comparte tus trucos de hacking enviando PR al** [**repositorio de hacktricks**](https://github.com/carlospolop/hacktricks) **y al** [**repositorio de hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||
|
||
</details>
|