mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-22 11:03:24 +00:00
290 lines
18 KiB
Markdown
290 lines
18 KiB
Markdown
# Nginx
|
||
|
||
<details>
|
||
|
||
<summary><strong>Aprenda hacking na AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
Outras maneiras de apoiar o HackTricks:
|
||
|
||
* Se você quiser ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
||
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
|
||
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Compartilhe seus truques de hacking enviando PRs para os** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||
|
||
</details>
|
||
|
||
<figure><img src="../../.gitbook/assets/image (2) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
**Configuração instantaneamente disponível para avaliação de vulnerabilidades e teste de penetração**. 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 dar a eles mais tempo para aprofundar, abrir shells e se divertir.
|
||
|
||
{% embed url="https://pentest-tools.com/" %}
|
||
|
||
## Localização raiz ausente <a href="#missing-root-location" id="missing-root-location"></a>
|
||
|
||
## **Essenciais da Configuração do Diretório Raiz do Nginx**
|
||
|
||
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. Esta 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`) está definida. Não há configuração para a localização raiz (`location / {...}`). Esta omissão significa que a diretiva raiz se aplica globalmente, permitindo que solicitações ao caminho raiz `/` acessem arquivos em `/etc/nginx`.
|
||
|
||
Uma consideração de segurança crítica surge desta 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, no entanto, ainda poderia permitir acesso não intencional a outros arquivos críticos, incluindo outros arquivos de configuração, logs de acesso e até credenciais criptografadas usadas para autenticação básica HTTP.
|
||
|
||
## Configuração de Má Configuração de LFI de Alias <a href="#alias-lfi-misconfiguration" id="alias-lfi-misconfiguration"></a>
|
||
|
||
Nos arquivos de configuração do Nginx, uma inspeção minuciosa é necessária para as diretivas "location". Uma vulnerabilidade conhecida como Inclusão de Arquivo Local (LFI) pode ser inadvertidamente introduzida por meio de uma configuração que se assemelha à seguinte:
|
||
```
|
||
location /imgs {
|
||
alias /path/images/;
|
||
}
|
||
```
|
||
Esta configuração é propensa a ataques de LFI devido ao servidor interpretar solicitações como `/imgs../flag.txt` como uma tentativa de acessar arquivos fora do diretório pretendido, efetivamente resolvendo para `/caminho/imagens/../flag.txt`. Essa falha permite que os 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 do Acunetix:
|
||
```
|
||
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 <a href="#uso-de-variavel-inseguro" id="uso-de-variavel-inseguro"></a>
|
||
|
||
Verifique a página a seguir para aprender como contornar diretivas como:
|
||
```plaintext
|
||
location = /admin {
|
||
deny all;
|
||
}
|
||
|
||
location = /admin/ {
|
||
deny all;
|
||
}
|
||
```
|
||
## Uso de variáveis inseguras / Divisão de Requisições HTTP <a href="#uso-de-variaveis-inseguras" id="uso-de-variaveis-inseguras"></a>
|
||
|
||
{% hint style="danger" %}
|
||
As variáveis vulneráveis `$uri` e `$document_uri` podem ser corrigidas substituindo-as por `$request_uri`.
|
||
|
||
Uma expressão regular também pode ser vulnerável, como:
|
||
|
||
`location ~ /docs/([^/])? { … $1 … }` - Vulnerável
|
||
|
||
`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 (retorno de carro) e \n (avanço de linha) significam novos caracteres de linha em solicitações HTTP, e suas formas codificadas em URL são representadas como `%0d%0a`. Incluir esses caracteres em uma solicitação (por exemplo, `http://localhost/%0d%0aDetectify:%20clrf`) para um servidor mal configurado resulta no servidor emitindo um novo cabeçalho chamado `Detectify`. Isso ocorre porque a variável $uri decodifica os caracteres de nova linha codificados em URL, resultando em 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 de injeção de 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/).
|
||
|
||
Também 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 solicitações:
|
||
|
||
- `https://example.com/%20X` - Qualquer código HTTP
|
||
- `https://example.com/%20H` - 400 Solicitação Inválida
|
||
|
||
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 Solicitação Inválida
|
||
|
||
Algumas configurações vulneráveis encontradas apresentadas nessa palestra foram:
|
||
|
||
- Observe como **`$uri`** é definido como está na URL final
|
||
```
|
||
location ^~ /lite/api/ {
|
||
proxy_pass http://lite-backend$uri$is_args$args;
|
||
}
|
||
```
|
||
* Observe 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;
|
||
}
|
||
```
|
||
### Qualquer variável
|
||
|
||
Foi descoberto que os **dados fornecidos pelo usuário** podem ser tratados como uma **variável Nginx** em certas circunstâncias. A causa desse comportamento ainda é um pouco elusiva, mas não é rara nem simples 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 sobre a 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 os Includes do Lado do Servidor (SSI) como a causa raiz.
|
||
|
||
Para **detectar essa configuração incorreta**, o seguinte comando pode ser executado, que envolve definir um cabeçalho de referência para testar a impressão da variável:
|
||
```bash
|
||
$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’
|
||
```
|
||
As varreduras para essa configuração incorreta em sistemas revelaram várias instâncias onde variáveis do Nginx poderiam ser impressas por um usuário. No entanto, uma diminuição no número de instâncias vulneráveis sugere que os esforços para corrigir esse problema foram em parte bem-sucedidos.
|
||
|
||
## Leitura bruta da resposta do backend
|
||
|
||
O Nginx oferece um recurso por meio do `proxy_pass` que permite a interceptação de erros e cabeçalhos HTTP produzidos pelo backend, com o objetivo de ocultar mensagens de erro e cabeçalhos internos. Isso é realizado pelo Nginx servindo páginas de erro personalizadas em resposta a erros do backend. No entanto, surgem desafios quando o Nginx encontra uma solicitação HTTP inválida. Tal solicitação é encaminhada para o backend conforme recebida, e a resposta bruta do backend é então enviada diretamente ao cliente sem 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, são usadas diretivas específicas na configuração do Nginx:
|
||
```
|
||
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 ao Nginx servir uma resposta personalizada para respostas do backend com um código de status maior que 300. Isso garante que, para o nosso exemplo de aplicação uWSGI, uma resposta de `Erro 500` 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 segurança.
|
||
|
||
Quando uma solicitação `GET` válida é feita, o Nginx a processa normalmente, retornando uma resposta de erro padrão sem revelar quaisquer cabeçalhos secretos. No entanto, uma solicitação HTTP inválida contorna esse mecanismo, resultando na exposição de respostas do backend em bruto, incluindo cabeçalhos secretos e mensagens de erro.
|
||
|
||
## merge\_slashes definido como off
|
||
|
||
Por padrão, a diretiva **`merge_slashes` do Nginx** é definida como **`on`**, o que comprime múltiplas barras inclinadas em uma URL em uma única barra. Essa funcionalidade, enquanto simplifica o processamento de URL, pode inadvertidamente ocultar vulnerabilidades em aplicações atrás do Nginx, especialmente aquelas propensas a ataques de inclusão de arquivos locais (LFI). Os 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 proxy reverso.
|
||
|
||
Para mitigar tais riscos, é recomendado **desativar a diretiva `merge_slashes`** para aplicações suscetíveis a essas vulnerabilidades. Isso garante que o Nginx encaminhe as 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).
|
||
|
||
### **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 poderia resultar em acesso não autorizado. 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 um **URI indefinido** dentro de `/map-poc`. [O manual do Nginx](https://nginx.org/en/docs/http/ngx\_http\_map\_module.html) recomenda 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 conhece o **servidor DNS** usado pelo Nginx e consegue interceptar suas consultas DNS, eles podem 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;
|
||
```
|
||
### **Diretivas `proxy_pass` e `internal`**
|
||
|
||
A diretiva **`proxy_pass`** é utilizada para redirecionar solicitações para outros servidores, interna ou externamente. A diretiva **`internal`** garante que determinados locais sejam acessíveis apenas dentro do Nginx. Embora essas diretivas não sejam vulnerabilidades por si só, sua configuração requer uma análise cuidadosa para evitar lapsos 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 Smuggling h2c**](../../pentesting-web/h2c-smuggling.md) poderia ser realizado para acessar endpoints protegidos/internos.
|
||
|
||
{% hint style="danger" %}
|
||
Essa 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 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` estivesse 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 por si 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 si 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 por configurações incorretas e vulnerabilidades comuns no 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/image (2) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
**Configuração instantaneamente disponível para avaliação de vulnerabilidades e teste de penetração**. Execute um pentest completo de qualquer lugar com mais de 20 ferramentas e recursos que vão desde a reconstrução até a geração de relatórios. Não substituímos os pentesters - desenvolvemos ferramentas personalizadas, módulos de detecção e exploração para dar-lhes mais tempo para aprofundar, abrir shells e se divertir.
|
||
|
||
{% embed url="https://pentest-tools.com/" %}
|
||
|
||
<details>
|
||
|
||
<summary><strong>Aprenda hacking na AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
Outras maneiras de apoiar o HackTricks:
|
||
|
||
* Se você quiser ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
||
* Obtenha o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com)
|
||
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Compartilhe seus 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>
|