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

18 KiB
Raw Blame History

Nginx

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

DragonJAR Security Conference is an international cybersecurity event with over a decade of history that will take place on September 7th and 8th, 2023 in Bogotá, Colombia. It is a highly technical event where the latest research in Spanish is presented, attracting hackers and researchers from around the world.
Register now at the following link and don't miss this great conference!:

{% embed url="https://www.dragonjarcon.org/" %}

Localização raiz ausente

server {
root /etc/nginx;

location /hello.txt {
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8080/;
}
}

A diretiva root especifica a pasta raiz para o Nginx. No exemplo acima, a pasta raiz é /etc/nginx, o que significa que podemos acessar arquivos dentro dessa pasta. A configuração acima não possui uma localização para / (location / {...}), apenas para /hello.txt. Por causa disso, a diretiva root será definida globalmente, o que significa que solicitações para / o levarão ao caminho local /etc/nginx.

Uma solicitação simples como GET /nginx.conf revelaria o conteúdo do arquivo de configuração do Nginx armazenado em /etc/nginx/nginx.conf. Se a raiz estiver definida como /etc, uma solicitação GET para /nginx/nginx.conf revelaria o arquivo de configuração. Em alguns casos, é possível acessar outros arquivos de configuração, logs de acesso e até mesmo credenciais criptografadas para autenticação básica HTTP.

Configuração incorreta de LFI com Alias

Dentro da configuração do Nginx, procure as declarações "location", se alguma delas se parecer com:

location /imgs {
alias /path/images/;
}

Existe uma vulnerabilidade de LFI porque:

/imgs../flag.txt

Nginx

Nginx is a popular web server that is commonly used to serve static content, reverse proxy, and load balance web applications. It is known for its high performance, scalability, and reliability.

Configuration Files

Nginx uses configuration files to define how it should handle incoming requests. The main configuration file is typically located at /etc/nginx/nginx.conf. Additional configuration files can be included using the include directive.

Virtual Hosts

Nginx supports virtual hosts, allowing you to host multiple websites on a single server. Each virtual host is defined in a separate configuration file and can have its own set of directives.

Reverse Proxy

Nginx can be used as a reverse proxy to distribute incoming requests to multiple backend servers. This is useful for load balancing and improving performance.

To configure Nginx as a reverse proxy, you need to define a server block with the proxy_pass directive pointing to the backend server.

Load Balancing

Nginx can also be used as a load balancer to distribute incoming requests across multiple backend servers. It supports various load balancing algorithms, such as round-robin, least connections, and IP hash.

To configure Nginx as a load balancer, you need to define an upstream block with the backend servers and a server block with the proxy_pass directive pointing to the upstream servers.

SSL/TLS Termination

Nginx can terminate SSL/TLS connections, allowing you to offload the SSL/TLS encryption and decryption process from your backend servers. This can improve performance and simplify the configuration of your web applications.

To configure SSL/TLS termination, you need to define a server block with the listen directive specifying the SSL/TLS port and the ssl_certificate and ssl_certificate_key directives pointing to the SSL/TLS certificate and private key files.

Security Considerations

When configuring Nginx, it is important to consider security best practices. Some important considerations include:

  • Restricting access to sensitive files and directories
  • Implementing secure SSL/TLS configurations
  • Protecting against common web vulnerabilities, such as cross-site scripting (XSS) and SQL injection
  • Regularly updating Nginx and its modules to patch security vulnerabilities

By following these best practices, you can help ensure the security and integrity of your web applications.

/path/images/../flag.txt

A configuração correta será:

location /imgs/ {
alias /path/images/;
}

Portanto, se você encontrar algum servidor Nginx, você deve verificar essa vulnerabilidade. Além disso, você pode descobri-la se perceber que a força bruta de arquivos/diretórios está se comportando de forma estranha.

Mais informações: https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/

Testes do 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

Restrição de caminho insegura

Verifique a página a seguir para aprender como contornar diretivas como:

location = /admin {
deny all;
}

location = /admin/ {
deny all;
}

Uso inseguro de variáveis

Um exemplo de uma configuração vulnerável do Nginx é:

location / {
return 302 https://example.com$uri;
}

Os caracteres de nova linha para solicitações HTTP são \r (retorno de carro) e \n (avanço de linha). A codificação de URL dos caracteres de nova linha resulta na seguinte representação dos caracteres %0d%0a. Quando esses caracteres são incluídos em uma solicitação como http://localhost/%0d%0aDetectify:%20clrf para um servidor com a configuração incorreta, o servidor responderá com um novo cabeçalho chamado Detectify, pois a variável $uri contém os caracteres de nova linha decodificados da 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

Saiba mais sobre os riscos de injeção de CRLF e divisão de resposta em https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/.

Qualquer variável

Em alguns casos, os dados fornecidos pelo usuário podem ser tratados como uma variável do Nginx. Não está claro por que isso pode estar acontecendo, mas não é tão incomum ou fácil de testar, como visto neste relatório H1. Se pesquisarmos a mensagem de erro, podemos ver que ela é encontrada no módulo de filtro SSI, revelando assim que isso se deve ao SSI.

Uma maneira de testar isso é definir um valor de cabeçalho referer:

$ curl -H Referer: bar http://localhost/foo$http_referer | grep foobar

Escaneamos essa configuração incorreta e encontramos várias instâncias onde um usuário poderia imprimir o valor das variáveis do Nginx. O número de instâncias vulneráveis encontradas diminuiu, o que pode indicar que isso foi corrigido.

Leitura bruta da resposta do backend

Com o proxy_pass do Nginx, há a possibilidade de interceptar erros e cabeçalhos HTTP criados pelo backend. Isso é muito útil se você quiser ocultar mensagens de erro e cabeçalhos internos para que sejam tratados pelo Nginx. O Nginx automaticamente servirá uma página de erro personalizada se o backend responder com uma. Mas e se o Nginx não entender que é uma resposta HTTP?

Se um cliente enviar uma solicitação HTTP inválida para o Nginx, essa solicitação será encaminhada como está para o backend, e o backend responderá com seu conteúdo bruto. Em seguida, o Nginx não entenderá a resposta HTTP inválida e a encaminhará diretamente para o cliente. Imagine um aplicativo uWSGI como este:

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!"]

E com as seguintes diretivas no Nginx:

http {
error_page 500 /html/error.html;
proxy_intercept_errors on;
proxy_hide_header Secret-Header;
}

proxy_intercept_errors servirá uma resposta personalizada se o backend tiver um status de resposta maior que 300. Em nossa aplicação uWSGI acima, enviaremos um Erro 500 que será interceptado pelo Nginx.

proxy_hide_header é bastante autoexplicativo; ele ocultará qualquer cabeçalho HTTP especificado do cliente.

Se enviarmos uma solicitação GET normal, o Nginx retornará:

HTTP/1.1 500 Internal Server Error
Server: nginx/1.10.3
Content-Type: text/html
Content-Length: 34
Connection: close

Mas se enviarmos uma solicitação HTTP inválida, como:

GET /? XTTP/1.1
Host: 127.0.0.1
Connection: close

Obteremos a seguinte resposta:

XTTP/1.1 500 Error
Content-Type: text/html
Secret-Header: secret-info

Secret info, should not be visible!

merge_slashes definido como off

A diretiva merge_slashes é definida como "on" por padrão, o que é um mecanismo para comprimir duas ou mais barras em uma única, então /// se tornaria /. Se o Nginx for usado como um proxy reverso e a aplicação que está sendo proxy for vulnerável a inclusão local de arquivos, o uso de barras extras na solicitação poderia deixar espaço para exploração. Isso é descrito em detalhes por Danny Robinson e Rotem Bar.

Encontramos 33 arquivos de configuração do Nginx com merge_slashes definido como "off".

default não é especificado para a diretiva map

Parece ser um caso comum quando map é usado para algum tipo de controle de autorização. Um exemplo simplificado poderia 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";
}
...
}

De acordo com o manual:

valor padrão
define o valor resultante se o valor de origem não corresponder a nenhuma das variantes especificadas. Quando o valor padrão não é especificado, o valor resultante padrão será uma string vazia.

É fácil esquecer do valor padrão. Portanto, o malfeitor pode contornar esse "controle de autorização" simplesmente acessando um caso inexistente dentro de /map-poc como https://targethost.com/map-poc/outra-área-privada.

DNS Spoofing no Nginx

De acordo com este post: http://blog.zorinaq.com/nginx-resolver-vulns/ Pode ser possível falsificar registros DNS para o Nginx se você souber o servidor DNS que o Nginx está usando (e puder interceptar de alguma forma a comunicação, portanto, isso não é válido se 127.0.0.1 for usado) e o domínio que está sendo solicitado.

O Nginx pode especificar um servidor DNS a ser usado com:

resolver     8.8.8.8;

Diretivas proxy_pass e internal

A diretiva proxy_pass pode ser usada para redirecionar internamente solicitações para outros servidores internos ou externos.
A diretiva internal é usada para deixar claro para o Nginx que a localização só pode ser acessada internamente.

O uso dessas diretivas não é uma vulnerabilidade, mas você deve verificar como elas estão configuradas.

proxy_set_header Upgrade & Connection

Se o servidor nginx estiver configurado para passar os cabeçalhos Upgrade e Connection, um ataque de Smuggling h2c pode ser realizado para acessar endpoints protegidos/internos.

{% hint style="danger" %} Essa vulnerabilidade permitiria que um invasor estabelecesse uma conexão direta com o endpoint proxy_pass (http://backend:9999 neste caso), cujo conteúdo não seria verificado pelo nginx. {% endhint %}

Exemplo de configuração vulnerável para roubar /flag aqui:

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" %} Observe que mesmo que o proxy_pass esteja apontando para um caminho específico, como http://backend:9999/socket.io, a conexão será estabelecida com http://backend:9999, então você pode acessar qualquer outro caminho dentro desse endpoint interno. Portanto, não importa se um caminho é especificado na URL do proxy_pass. {% endhint %}

Experimente você mesmo

A Detectify criou um repositório no GitHub onde você pode usar o Docker para configurar seu próprio servidor de teste Nginx vulnerável com algumas das configurações incorretas discutidas neste artigo e tentar encontrá-las por conta própria!

https://github.com/detectify/vulnerable-nginx

Ferramentas de Análise Estática

GIXY

Gixy é uma ferramenta para analisar a configuração do Nginx. O objetivo principal do Gixy é prevenir a configuração incorreta de segurança e automatizar a detecção de falhas.

Nginxpwner

Nginxpwner é uma ferramenta simples para procurar configurações incorretas e vulnerabilidades comuns do Nginx.

Referências

DragonJAR Security Conference es un evento internacional de ciberseguridad 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/" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥