hacktricks/network-services-pentesting/pentesting-web/nginx.md

356 lines
16 KiB
Markdown
Raw Normal View History

2023-06-05 18:33:24 +00:00
# Nginx
<details>
<summary><strong>Aprende hacking en AWS de cero a héroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
2023-06-05 18:33:24 +00:00
Otras formas de apoyar a HackTricks:
* Si quieres ver a tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF**, consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sigue** a **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Comparte tus trucos de hacking enviando PRs a los repositorios de github de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
2023-06-05 18:33:24 +00:00
</details>
<figure><img src="../../.gitbook/assets/image (1) (1) (2) (4).png" alt=""><figcaption></figcaption></figure>
2023-06-05 18:33:24 +00:00
[**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/" %}
## Ubicación root faltante <a href="#missing-root-location" id="missing-root-location"></a>
2023-06-05 18:33:24 +00:00
```
server {
root /etc/nginx;
2023-06-05 18:33:24 +00:00
location /hello.txt {
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8080/;
}
2023-06-05 18:33:24 +00:00
}
```
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 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 `/` te llevarán a la ruta local `/etc/nginx`.
2023-06-05 18:33:24 +00:00
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 está configurada 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 HTTP.
2023-06-05 18:33:24 +00:00
## Configuración errónea de Alias LFI <a href="#alias-lfi-misconfiguration" id="alias-lfi-misconfiguration"></a>
2023-06-05 18:33:24 +00:00
Dentro de la configuración de Nginx, busca las declaraciones "location", si alguna se parece a:
2023-06-05 18:33:24 +00:00
```
location /imgs {
alias /path/images/;
2023-06-05 18:33:24 +00:00
}
```
Existe una vulnerabilidad LFI porque:
2023-06-05 18:33:24 +00:00
```
/imgs../flag.txt
```
```markdown
# Pentesting Nginx
## Enumeración
### Banner Grabbing
Usar `curl` para obtener información del servidor:
```bash
curl -I http://<IP>
```
### Contenido oculto
Buscar directorios y archivos ocultos con herramientas como `gobuster`:
```bash
gobuster dir -u http://<IP> -w <wordlist>
```
### Archivos de configuración
Intentar acceder a archivos de configuración comunes como `nginx.conf`:
```bash
curl http://<IP>/nginx.conf
```
## Explotación
### Desbordamiento de buffer
Buscar vulnerabilidades de desbordamiento de buffer que puedan ser explotadas.
### Inyección de comandos
Probar inyecciones de comandos a través de parámetros de URL o campos de entrada.
## Post-explotación
### Escalada de privilegios
Buscar métodos para escalar privilegios y obtener un mayor acceso al sistema.
### Persistencia
Establecer mecanismos de persistencia para mantener el acceso a largo plazo.
### Limpieza
Eliminar huellas para evitar la detección.
## Herramientas útiles
- `curl`
- `gobuster`
- `nikto`
- `wpscan` (para sitios WordPress)
## Referencias
- [Nginx Official Documentation](https://nginx.org/en/docs/)
- [OWASP Testing Guide](https://owasp.org/www-project-web-security-testing-guide/)
```
2023-06-05 18:33:24 +00:00
```
/path/images/../flag.txt
```
La configuración correcta será:
```
location /imgs/ {
alias /path/images/;
2023-06-05 18:33:24 +00:00
}
```
**Entonces, si encuentras algún servidor Nginx deberías verificar esta vulnerabilidad. También puedes descubrirla si notas que el brute force de archivos/directorios se comporta de manera extraña.**
2023-06-05 18:33:24 +00:00
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 Acunetix:
2023-06-05 18:33:24 +00:00
```
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="#unsafe-variable-use" id="unsafe-variable-use"></a>
Consulta la siguiente página para aprender cómo sortear directivas como:
```plaintext
location = /admin {
deny all;
}
location = /admin/ {
deny all;
}
```
{% content-ref url="../../pentesting-web/proxy-waf-protections-bypass.md" %}
[proxy-waf-protections-bypass.md](../../pentesting-web/proxy-waf-protections-bypass.md)
{% endcontent-ref %}
## Uso inseguro de variables <a href="#unsafe-variable-use" id="unsafe-variable-use"></a>
2023-06-05 18:33:24 +00:00
Un ejemplo de una configuración vulnerable de Nginx es:
```
location / {
return 302 https://example.com$uri;
2023-06-05 18:33:24 +00:00
}
```
Los caracteres de nueva línea para las solicitudes HTTP son \r (Retorno de Carro) y \n (Avance de Línea). La codificación 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 mala configuración, el servidor responderá con un nuevo encabezado llamado `Detectify` ya que la variable $uri contiene los caracteres de nueva línea decodificados por URL.
2023-06-05 18:33:24 +00:00
```
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 respuesta 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/).
2023-06-05 18:33:24 +00:00
### 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 inusual ni fácil de probar como se ve en este [informe 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), revelando así que esto se debe a SSI.
2023-06-05 18:33:24 +00:00
Una forma de probar esto es establecer un valor de encabezado referer:
2023-06-05 18:33:24 +00:00
```
$ curl -H Referer: bar http://localhost/foo$http_referer | grep foobar
```
Escaneamos en busca de 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.
2023-06-05 18:33:24 +00:00
## Lectura de respuesta del backend en crudo
2023-06-05 18:33:24 +00:00
Con `proxy_pass` de Nginx, existe la posibilidad de interceptar errores y encabezados HTTP creados por el backend. Esto es muy útil si quieres ocultar mensajes de error internos y encabezados para que en su lugar sean manejados por Nginx. Nginx servirá automáticamente una página de error personalizada si el backend responde con una. Pero, ¿qué pasa si Nginx no entiende que es una respuesta HTTP?
2023-06-05 18:33:24 +00:00
Si un cliente envía una solicitud HTTP inválida a Nginx, esa solicitud se reenviará tal cual al backend, y el backend responderá con su contenido en crudo. Entonces, Nginx no entenderá la respuesta HTTP inválida y simplemente la reenviará al cliente. Imagina una aplicación uWSGI como esta:
2023-06-05 18:33:24 +00:00
```python
def application(environ, start_response):
start_response('500 Error', [('Content-Type',
2023-06-05 18:33:24 +00:00
'text/html'),('Secret-Header','secret-info')])
return [b"Secret info, should not be visible!"]
2023-06-05 18:33:24 +00:00
```
Y con las siguientes directivas en Nginx:
```
http {
error_page 500 /html/error.html;
proxy_intercept_errors on;
proxy_hide_header Secret-Header;
2023-06-05 18:33:24 +00:00
}
```
[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 `500 Error` que será interceptado por Nginx.
2023-06-05 18:33:24 +00:00
[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.
2023-06-05 18:33:24 +00:00
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
```
Recibiremos la siguiente respuesta:
2023-06-05 18:33:24 +00:00
```
XTTP/1.1 500 Error
Content-Type: text/html
Secret-Header: secret-info
Secret info, should not be visible!
```
## merge\_slashes configurado en off
2023-06-05 18:33:24 +00:00
La directiva [merge\_slashes](http://nginx.org/en/docs/http/ngx\_http\_core\_module.html#merge\_slashes) está configurada en "on" por defecto, lo cual es un mecanismo para comprimir dos o más barras inclinadas en una, de modo que `///` se convertiría en `/`. Si Nginx se utiliza como un proxy inverso y la aplicación que está siendo proxy es vulnerable a la inclusión de archivos locales, usar barras extras en la solicitud podría dejar espacio para explotarlo. Esto está descrito 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).
2023-06-05 18:33:24 +00:00
Encontramos 33 archivos de configuración de Nginx con `merge_slashes` configurado en "off".
2023-06-05 18:33:24 +00:00
## no se especifica el valor predeterminado para la directiva map
2023-06-05 18:33:24 +00:00
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;
}
2023-06-05 18:33:24 +00:00
...
}
```
```
server {
...
location /map-poc {
if ($mappocallow = 0) {return 403;}
return 200 "Hello. It is private area: $mappocallow";
}
2023-06-05 18:33:24 +00:00
...
}
```
[Según el manual](https://nginx.org/en/docs/http/ngx_http_map_module.html):
2023-06-05 18:33:24 +00:00
> valor por defecto\
> establece el valor resultante si el valor fuente no coincide con ninguna de las variantes especificadas. Cuando no se especifica el valor por defecto,\
> el valor resultante por defecto será una cadena vacía.
2023-06-05 18:33:24 +00:00
Es fácil olvidar el valor `default`. Así que un **malhechor puede eludir este "control de autorización"** simplemente accediendo a un **caso inexistente dentro de `/map-poc`** como `https://targethost.com/map-poc/another-private-area`.
2023-06-05 18:33:24 +00:00
## DNS Spoofing Nginx
2023-06-05 18:33:24 +00:00
Según este post: [http://blog.zorinaq.com/nginx-resolver-vulns/](http://blog.zorinaq.com/nginx-resolver-vulns/) **Podría ser posible falsificar registros DNS** en Nginx si **conoces el servidor DNS que Nginx** está utilizando (y puedes 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**.
2023-06-05 18:33:24 +00:00
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.\
2023-06-05 18:33:24 +00:00
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 deberías verificar cómo están configuradas**.
2023-06-05 18:33:24 +00:00
## 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.
2023-06-05 18:33:24 +00:00
{% 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 va a ser revisado por nginx.
2023-06-05 18:33:24 +00:00
{% 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;
2023-06-05 18:33:24 +00:00
ssl_certificate /usr/local/nginx/conf/cert.pem;
ssl_certificate_key /usr/local/nginx/conf/privkey.pem;
2023-06-05 18:33:24 +00:00
location / {
proxy_pass http://backend:9999;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
}
2023-06-05 18:33:24 +00:00
location /flag {
deny all;
}
2023-06-05 18:33:24 +00:00
```
{% hint style="warning" %}
Ten en cuenta que incluso si el `proxy_pass` apuntaba a un **path** específico como `http://backend:9999/socket.io` la conexión se establecerá con `http://backend:9999` por lo que puedes **contactar cualquier otro path dentro de ese endpoint interno. Por lo tanto, no importa si se especifica un path en la URL de proxy\_pass.**
2023-06-05 18:33:24 +00:00
{% endhint %}
## Pruébalo tú mismo
Detectify ha creado un repositorio de GitHub donde puedes usar Docker para configurar tu propio servidor de pruebas Nginx vulnerable con algunas de las desconfiguraciones discutidas en este artículo y ¡intentar encontrarlas tú mismo!
2023-06-05 18:33:24 +00:00
[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 principal objetivo de Gixy es prevenir desconfiguraciones de seguridad y automatizar la detección de fallos.
2023-06-05 18:33:24 +00:00
### [Nginxpwner](https://github.com/stark0de/nginxpwner)
Nginxpwner es una herramienta simple para buscar desconfiguraciones y vulnerabilidades comunes de Nginx.
2023-06-05 18:33:24 +00:00
## 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>
2023-06-05 18:33:24 +00:00
[**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><strong>Aprende hacking en AWS desde cero hasta héroe 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:
2023-06-05 18:33:24 +00:00
* Si quieres ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** revisa los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Comparte tus trucos de hacking enviando PRs a los repositorios de GitHub** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
2023-06-05 18:33:24 +00:00
</details>