16 KiB
Nginx
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Você trabalha em uma empresa de cibersegurança? Você quer ver sua empresa anunciada no HackTricks? ou você quer ter acesso à última versão do PEASS ou baixar o HackTricks em PDF? Confira os PLANOS DE ASSINATURA!
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Adquira o swag oficial do PEASS & HackTricks
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-me no Twitter 🐦@carlospolopm.
- Compartilhe suas técnicas de hacking enviando PRs para o repositório hacktricks e para o repositório hacktricks-cloud.
DragonJAR Security Conference é um evento internacional de cibersegurança com mais de uma década que será realizado nos dias 7 e 8 de setembro de 2023 em Bogotá, Colômbia. É um evento de grande conteúdo técnico onde são apresentadas as últimas pesquisas em espanhol que atrai hackers e pesquisadores de todo o mundo.
Registre-se agora no link abaixo e não perca esta grande conferência!:
{% embed url="https://www.dragonjarcon.org/" %}
Falta de localização raiz
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 tem 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 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 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é credenciais criptografadas para autenticação básica HTTP.
Configuração incorreta de LFI de alias
Dentro da configuração do Nginx, procure as declarações "location", se alguma delas parecer:
location /imgs {
alias /path/images/;
}
Existe uma vulnerabilidade de LFI porque:
/imgs../flag.txt
O seguinte é conteúdo de um livro de hacking sobre técnicas de hacking. O conteúdo a seguir é do arquivo network-services-pentesting/pentesting-web/nginx.md. Traduza o texto em inglês relevante para o português e retorne a tradução mantendo a sintaxe markdown. Não traduza coisas como código, nomes de técnicas de hacking, palavras de hacking, nomes de plataformas em nuvem/SaaS (como Workspace, aws, gcp...), a palavra 'leak', pentesting e tags markdown. Além disso, não adicione nada extra além da tradução e da sintaxe markdown.
/path/images/../flag.txt
A configuração correta será:
location /imgs/ {
alias /path/images/;
}
Portanto, se você encontrar algum servidor Nginx, verifique essa vulnerabilidade. Além disso, você pode descobri-la se perceber que a força bruta 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 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
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 configuração incorreta, o servidor responderá com um novo cabeçalho chamado Detectify
, já que 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 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 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 referenciador:
$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’
Nós escaneamos 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 de resposta de backend bruta
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 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 a encaminhará para o cliente. Imagine uma aplicação uWSGI como esta:
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 seria 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
Nós 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 em uma, então ///
se tornaria /
. Se o Nginx for usado como um proxy reverso e a aplicação que está sendo proxy for vulnerável à inclusão local de arquivos, o uso de 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".
O padrão 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 assim:
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 o valor default
. Então, um malfeitor pode burlar 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 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 contatar 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 sozinho!
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
- https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/
- http://blog.zorinaq.com/nginx-resolver-vulns/
- https://github.com/yandex/gixy/issues/115
DragonJAR Security Conference é um evento internacional de cibersegurança com mais de uma década que será realizado em 7 e 8 de setembro de 2023 em Bogotá, Colômbia. É um evento de grande conteúdo técnico onde as últimas pesquisas em espanhol são apresentadas, atraindo hackers e pesquisadores de todo o mundo.
Registre-se agora no seguinte link e não perca esta grande conferência!:
{% embed url="https://www.dragonjarcon.org/" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Você trabalha em uma empresa de cibersegurança? Você quer ver sua empresa anunciada no HackTricks? ou você quer ter acesso à última versão do PEASS ou baixar o HackTricks em PDF? Verifique os PLANOS DE ASSINATURA!
- Descubra The PEASS Family, nossa coleção exclusiva de NFTs
- Adquira o swag oficial do PEASS & HackTricks
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-me no Twitter 🐦@carlospolopm.
- Compartilhe suas dicas de hacking enviando PRs para o repositório hacktricks e hacktricks-cloud repo.