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

310 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Nginx
{% hint style="success" %}
Aprenda e pratique Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Aprenda e pratique Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
</details>
{% endhint %}
<figure><img src="/.gitbook/assets/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
**Obtenha a perspectiva de um hacker sobre seus aplicativos web, rede e nuvem**
**Encontre e relate vulnerabilidades críticas e exploráveis com impacto real nos negócios.** Use nossas mais de 20 ferramentas personalizadas para mapear a superfície de ataque, encontrar problemas de segurança que permitem escalar privilégios e usar exploits automatizados para coletar evidências essenciais, transformando seu trabalho árduo em relatórios persuasivos.
{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}
## Missing root location <a href="#missing-root-location" id="missing-root-location"></a>
Ao configurar o servidor Nginx, a **diretiva root** desempenha um papel crítico ao definir o diretório base a partir do qual os arquivos são servidos. Considere o exemplo abaixo:
```bash
server {
root /etc/nginx;
location /hello.txt {
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8080/;
}
}
```
Nesta configuração, `/etc/nginx` é designado como o diretório raiz. Essa configuração permite o acesso a arquivos dentro do diretório raiz especificado, como `/hello.txt`. No entanto, é crucial notar que apenas uma localização específica (`/hello.txt`) é definida. Não há configuração para a localização raiz (`location / {...}`). Essa omissão significa que a diretiva raiz se aplica globalmente, permitindo que solicitações para o caminho raiz `/` acessem arquivos sob `/etc/nginx`.
Uma consideração crítica de segurança surge dessa configuração. Uma simples solicitação `GET`, como `GET /nginx.conf`, poderia expor informações sensíveis ao servir o arquivo de configuração do Nginx localizado em `/etc/nginx/nginx.conf`. Definir a raiz para um diretório menos sensível, como `/etc`, poderia mitigar esse risco, mas ainda pode permitir acesso não intencional a outros arquivos críticos, incluindo outros arquivos de configuração, logs de acesso e até mesmo credenciais criptografadas usadas para autenticação básica HTTP.
## Alias LFI Misconfiguration <a href="#alias-lfi-misconfiguration" id="alias-lfi-misconfiguration"></a>
Nos arquivos de configuração do Nginx, uma inspeção cuidadosa é necessária para as diretivas "location". Uma vulnerabilidade conhecida como Local File Inclusion (LFI) pode ser inadvertidamente introduzida através de uma configuração que se assemelha ao seguinte:
```
location /imgs {
alias /path/images/;
}
```
Esta configuração é suscetível a ataques LFI devido ao servidor interpretar solicitações como `/imgs../flag.txt` como uma tentativa de acessar arquivos fora do diretório pretendido, resolvendo efetivamente para `/path/images/../flag.txt`. Essa falha permite que atacantes recuperem arquivos do sistema de arquivos do servidor que não deveriam ser acessíveis via web.
Para mitigar essa vulnerabilidade, a configuração deve ser ajustada para:
```
location /imgs/ {
alias /path/images/;
}
```
Mais informações: [https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/](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 <a href="#unsafe-variable-use" id="unsafe-variable-use"></a>
Verifique a página a seguir para aprender como contornar diretivas 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 variáveis / Divisão de Requisições HTTP <a href="#unsafe-variable-use" id="unsafe-variable-use"></a>
{% hint style="danger" %}
Variáveis vulneráveis `$uri` e `$document_uri` e isso pode ser corrigido substituindo-as por `$request_uri`.
Uma regex também pode ser vulnerável como:
`location ~ /docs/([^/])? { … $1 … }` - Vulnerável&#x20;
`location ~ /docs/([^/\s])? { … $1 … }` - Não vulnerável (verificando espaços)
`location ~ /docs/(.*)? { … $1 … }` - Não vulnerável
{% endhint %}
Uma vulnerabilidade na configuração do Nginx é demonstrada pelo exemplo abaixo:
```
location / {
return 302 https://example.com$uri;
}
```
Os caracteres \r (Carriage Return) e \n (Line Feed) significam caracteres de nova linha em requisições HTTP, e suas formas codificadas em URL são representadas como `%0d%0a`. Incluir esses caracteres em uma requisição (por exemplo, `http://localhost/%0d%0aDetectify:%20clrf`) para um servidor mal configurado resulta no servidor emitindo um novo cabeçalho chamado `Detectify`. Isso acontece porque a variável $uri decodifica os caracteres de nova linha codificados em URL, levando a um cabeçalho inesperado na resposta:
```
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 da injeção CRLF e divisão de resposta em [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/).
Além disso, essa técnica é [**explicada nesta palestra**](https://www.youtube.com/watch?v=gWQyWdZbdoY\&list=PL0xCSYnG\_iTtJe2V6PQqamBF73n7-f1Nr\&index=77) com alguns exemplos vulneráveis e mecanismos de detecção. Por exemplo, para detectar essa má configuração de uma perspectiva de caixa-preta, você poderia usar essas requisições:
* `https://example.com/%20X` - Qualquer código HTTP
* `https://example.com/%20H` - 400 Bad Request
Se vulnerável, o primeiro retornará como "X" é qualquer método HTTP e o segundo retornará um erro, pois H não é um método válido. Assim, o servidor receberá algo como: `GET / H HTTP/1.1` e isso acionará o erro.
Outros exemplos de detecção seriam:
* `http://company.tld/%20HTTP/1.1%0D%0AXXXX:%20x` - Qualquer código HTTP
* `http://company.tld/%20HTTP/1.1%0D%0AHost:%20x` - 400 Bad Request
Algumas configurações vulneráveis encontradas apresentadas nessa palestra foram:
* Note como **`$uri`** é definido como está na URL final.
```
location ^~ /lite/api/ {
proxy_pass http://lite-backend$uri$is_args$args;
}
```
* Note como novamente **`$uri`** está na URL (desta vez dentro de um parâmetro)
```
location ~ ^/dna/payment {
rewrite ^/dna/([^/]+) /registered/main.pl?cmd=unifiedPayment&context=$1&native_uri=$uri break;
proxy_pass http://$back;
```
* Agora no AWS S3
```
location /s3/ {
proxy_pass https://company-bucket.s3.amazonaws.com$uri;
}
```
### Any variable
Foi descoberto que **dados fornecidos pelo usuário** podem ser tratados como uma **variável Nginx** sob certas circunstâncias. A causa desse comportamento permanece um tanto elusiva, mas não é rara nem fácil de verificar. Essa anomalia foi destacada em um relatório de segurança no HackerOne, que pode ser visualizado [aqui](https://hackerone.com/reports/370094). Uma investigação mais aprofundada na mensagem de erro levou à identificação de sua ocorrência dentro do [módulo de filtro SSI do código-fonte do Nginx](https://github.com/nginx/nginx/blob/2187586207e1465d289ae64cedc829719a048a39/src/http/modules/ngx_http_ssi_filter_module.c#L365), apontando Server Side Includes (SSI) como a causa raiz.
Para **detectar essa má configuração**, o seguinte comando pode ser executado, que envolve definir um cabeçalho referer para testar a impressão de variáveis:
```bash
$ curl -H Referer: bar http://localhost/foo$http_referer | grep foobar
```
Scans for this misconfiguration across systems revealed multiple instances where Nginx variables could be printed by a user. However, a decrease in the number of vulnerable instances suggests that efforts to patch this issue have been somewhat successful.
## Leitura da resposta bruta do backend
Nginx oferece um recurso através de `proxy_pass` que permite a interceptação de erros e cabeçalhos HTTP produzidos pelo backend, visando ocultar mensagens de erro internas e cabeçalhos. Isso é realizado pelo Nginx servindo páginas de erro personalizadas em resposta a erros do backend. No entanto, desafios surgem quando o Nginx encontra uma solicitação HTTP inválida. Tal solicitação é encaminhada para o backend como recebida, e a resposta bruta do backend é então enviada diretamente ao cliente sem a intervenção do Nginx.
Considere um cenário de exemplo envolvendo uma aplicação uWSGI:
```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!"]
```
Para gerenciar isso, diretivas específicas na configuração do Nginx são usadas:
```
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): Esta diretiva permite que o Nginx sirva uma resposta personalizada para respostas de backend com um código de status maior que 300. Isso garante que, para nosso exemplo de aplicação uWSGI, uma resposta de `500 Error` seja interceptada e tratada pelo Nginx.
* [**proxy\_hide\_header**](http://nginx.org/en/docs/http/ngx\_http\_proxy\_module.html#proxy\_hide\_header): Como o nome sugere, esta diretiva oculta cabeçalhos HTTP especificados do cliente, melhorando a privacidade e a segurança.
Quando uma solicitação `GET` válida é feita, o Nginx a processa normalmente, retornando uma resposta de erro padrão sem revelar cabeçalhos secretos. No entanto, uma solicitação HTTP inválida contorna esse mecanismo, resultando na exposição de respostas brutas do backend, incluindo cabeçalhos secretos e mensagens de erro.
## merge\_slashes definido como off
Por padrão, a **diretiva `merge_slashes` do Nginx** está definida como **`on`**, o que comprime múltiplas barras (slashes) em uma URL em uma única barra. Este recurso, embora simplifique o processamento de URLs, pode inadvertidamente ocultar vulnerabilidades em aplicações atrás do Nginx, particularmente aquelas suscetíveis a ataques de inclusão de arquivos locais (LFI). Especialistas em segurança **Danny Robinson e Rotem Bar** destacaram os riscos potenciais associados a esse comportamento padrão, especialmente quando o Nginx atua como um reverse-proxy.
Para mitigar tais riscos, é recomendável **desativar a diretiva `merge_slashes`** para aplicações suscetíveis a essas vulnerabilidades. Isso garante que o Nginx encaminhe solicitações para a aplicação sem alterar a estrutura da URL, não mascarando assim quaisquer problemas de segurança subjacentes.
Para mais informações, consulte [Danny Robinson e Rotem Bar](https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d).
### **Cabeçalhos de Resposta Maclicious**
Como mostrado em [**este artigo**](https://mizu.re/post/cors-playground), existem certos cabeçalhos que, se presentes na resposta do servidor web, mudarão o comportamento do proxy Nginx. Você pode verificá-los [**na documentação**](https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/):
* `X-Accel-Redirect`: Indica ao Nginx para redirecionar internamente uma solicitação para um local especificado.
* `X-Accel-Buffering`: Controla se o Nginx deve ou não armazenar em buffer a resposta.
* `X-Accel-Charset`: Define o conjunto de caracteres para a resposta ao usar X-Accel-Redirect.
* `X-Accel-Expires`: Define o tempo de expiração para a resposta ao usar X-Accel-Redirect.
* `X-Accel-Limit-Rate`: Limita a taxa de transferência para respostas ao usar X-Accel-Redirect.
Por exemplo, o cabeçalho **`X-Accel-Redirect`** causará um **redirecionamento** interno no Nginx. Portanto, ter uma configuração do Nginx com algo como **`root /`** e uma resposta do servidor web com **`X-Accel-Redirect: .env`** fará com que o Nginx envie o conteúdo de **`/.env`** (Path Traversal).
### **Valor Padrão na Diretiva Map**
Na **configuração do Nginx**, a diretiva `map` frequentemente desempenha um papel no **controle de autorização**. Um erro comum é não especificar um valor **padrão**, o que pode levar a acessos não autorizados. Por exemplo:
```yaml
http {
map $uri $mappocallow {
/map-poc/private 0;
/map-poc/secret 0;
/map-poc/public 1;
}
}
```
```yaml
server {
location /map-poc {
if ($mappocallow = 0) {return 403;}
return 200 "Hello. It is private area: $mappocallow";
}
}
```
Sem um `default`, um **usuário malicioso** pode contornar a segurança acessando uma **URI indefinida** dentro de `/map-poc`. [O manual do Nginx](https://nginx.org/en/docs/http/ngx\_http\_map\_module.html) aconselha definir um **valor padrão** para evitar tais problemas.
### **Vulnerabilidade de Spoofing de DNS**
O spoofing de DNS contra o Nginx é viável sob certas condições. Se um atacante souber o **servidor DNS** usado pelo Nginx e puder interceptar suas consultas DNS, ele pode falsificar registros DNS. No entanto, esse método é ineficaz se o Nginx estiver configurado para usar **localhost (127.0.0.1)** para resolução de DNS. O Nginx permite especificar um servidor DNS da seguinte forma:
```yaml
resolver 8.8.8.8;
```
### **`proxy_pass` e Diretrizes `internal`**
A diretriz **`proxy_pass`** é utilizada para redirecionar solicitações para outros servidores, seja internamente ou externamente. A diretriz **`internal`** garante que certos locais sejam acessíveis apenas dentro do Nginx. Embora essas diretrizes não sejam vulnerabilidades por si mesmas, sua configuração requer uma análise cuidadosa para evitar falhas de segurança.
## proxy\_set\_header Upgrade & Connection
Se o servidor nginx estiver configurado para passar os cabeçalhos Upgrade e Connection, um [**ataque de H2C Smuggling**](../../pentesting-web/h2c-smuggling.md) pode ser realizado para acessar endpoints protegidos/internos.
{% hint style="danger" %}
Essa vulnerabilidade permitiria que um atacante **estabelecesse uma conexão direta com o endpoint `proxy_pass`** (`http://backend:9999` neste caso) cujo conteúdo não será verificado pelo nginx.
{% endhint %}
Exemplo de configuração vulnerável para roubar `/flag` de [aqui](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" %}
Note 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 %}
## 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 configurações incorretas discutidas neste artigo e tentar encontrá-las você mesmo!
[https://github.com/detectify/vulnerable-nginx](https://github.com/detectify/vulnerable-nginx)
## Ferramentas de Análise Estática
### [GIXY](https://github.com/yandex/gixy)
Gixy é uma ferramenta para analisar a configuração do Nginx. O principal objetivo do Gixy é prevenir configurações de segurança incorretas e automatizar a detecção de falhas.
### [Nginxpwner](https://github.com/stark0de/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/**](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/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
**Obtenha a perspectiva de um hacker sobre seus aplicativos web, rede e nuvem**
**Encontre e relate vulnerabilidades críticas e exploráveis com impacto real nos negócios.** Use nossas mais de 20 ferramentas personalizadas para mapear a superfície de ataque, encontrar problemas de segurança que permitem escalar privilégios e usar exploits automatizados para coletar evidências essenciais, transformando seu trabalho árduo em relatórios persuasivos.
{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}
{% hint style="success" %}
Aprenda e pratique Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Aprenda e pratique Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe truques de hacking enviando PRs para os repositórios do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
{% endhint %}