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

15 KiB
Raw Blame History

Nginx

Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras formas de apoiar o HackTricks:

Configuração imediatamente disponível para avaliação de vulnerabilidade & pentesting. Execute um pentest completo de qualquer lugar com mais de 20 ferramentas & recursos que vão desde reconhecimento até relatórios. Não substituímos pentesters - desenvolvemos ferramentas personalizadas, módulos de detecção & exploração para lhes dar mais tempo para investigar mais a fundo, explorar vulnerabilidades e se divertir.

{% embed url="https://pentest-tools.com/" %}

Localização da 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 um local para / (location / {...}), apenas para /hello.txt. Por causa disso, a diretiva root será definida globalmente, o que significa que solicitações para / levarão você ao caminho local /etc/nginx.

Uma solicitação tão simples quanto GET /nginx.conf revelaria o conteúdo do arquivo de configuração do Nginx armazenado em /etc/nginx/nginx.conf. Se o root for definido 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é credenciais criptografadas para autenticação básica HTTP.

Configuração Incorreta de Alias LFI

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

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

Há uma vulnerabilidade LFI porque:

/imgs../flag.txt

Transforma-se em:

/path/images/../flag.txt

A configuração correta será:

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

Portanto, se você encontrar algum servidor Nginx, deve verificar essa vulnerabilidade. Além disso, você pode descobri-la se perceber que o brute force de arquivos/diretórios está se comportando de maneira estranha.

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

Testes da 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 inseguro

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

location = /admin {
deny all;
}

location = /admin/ {
deny all;
}

{% content-ref url="../../pentesting-web/proxy-waf-protections-bypass.md" %} proxy-waf-protections-bypass.md {% endcontent-ref %}

Uso inseguro de variáveis

Um exemplo de 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 (Alimentaçã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 má configuração, o servidor responderá com um novo cabeçalho chamado Detectify, uma vez que a variável $uri contém os caracteres de nova linha decodificados por 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 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, dados fornecidos pelo usuário podem ser tratados como uma variável do Nginx. Não está claro por que isso pode acontecer, mas não é tão incomum ou fácil de testar, como visto neste relatório H1. Se procurarmos pela 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

Realizamos a varredura para essa má configuração 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 da resposta do backend bruta

Com o proxy_pass do Nginx, existe a possibilidade de interceptar erros e cabeçalhos HTTP criados pelo backend. Isso é muito útil se você quiser ocultar mensagens de erro internas e cabeçalhos para que sejam, em vez disso, tratados pelo Nginx. O Nginx servirá automaticamente 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. Então, o Nginx não entenderá a resposta HTTP inválida e simplesmente a encaminhará para o cliente. Imagine uma aplicação uWSGI assim:

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 superior a 300. Na nossa aplicação uWSGI acima, enviaremos um Erro 500 que seria interceptado pelo Nginx.

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

Se enviarmos uma requisiçã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

Receberemos 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, que é um mecanismo para comprimir duas ou mais barras para frente em uma, então /// se tornaria /. Se o Nginx for usado como um proxy reverso e a aplicação que está sendo proxyada for vulnerável a inclusão de arquivos locais, usar barras extras na solicitação poderia deixar espaço para explorá-la. 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 padrão não é especificado, o
valor resultante padrão será uma string vazia.

É fácil esquecer do valor default. Assim, um malfeitor pode contornar esse "controle de autorização" simplesmente acessando um caso inexistente dentro de /map-poc como https://targethost.com/map-poc/another-private-area.

DNS Spoofing 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 você pode interceptar de alguma forma a comunicação, então 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 para usar 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 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 h2c Smuggling poderia ser realizado para acessar endpoints protegidos/internos.

{% hint style="danger" %} Esta vulnerabilidade permitiria a um atacante estabelecer uma conexão direta com o endpoint proxy_pass (http://backend:9999 neste caso) cujo conteúdo não vai ser verificado pelo nginx. {% endhint %}

Exemplo de configuração vulnerável para roubar /flag de 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 se o proxy_pass estiver 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 entrar em contato com qualquer outro caminho dentro desse ponto final interno. Portanto, não importa se um caminho é especificado na URL do proxy_pass. {% endhint %}

Tente 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 más configurações discutidas neste artigo e tentar encontrá-las você mesmo!

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

Ferramentas de Análise Estática

GIXY

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

Nginxpwner

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

Referências

Configuração imediatamente disponível para avaliação de vulnerabilidade e pentesting. Execute um pentest completo de qualquer lugar com mais de 20 ferramentas e recursos que vão desde reconhecimento até relatórios. Não substituímos pentesters - desenvolvemos ferramentas personalizadas, módulos de detecção e exploração para lhes dar mais tempo para investigar mais a fundo, explorar sistemas e se divertir.

{% embed url="https://pentest-tools.com/" %}

Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks: