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

289 lines
15 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
<details>
<summary><strong>Aprenda hacking no 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 formas de apoiar o HackTricks:
* Se você quer ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**material oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao grupo [**telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para os repositórios github do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
<figure><img src="/.gitbook/assets/image (2).png" alt=""><figcaption></figcaption></figure>
**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 <a href="#missing-root-location" id="missing-root-location"></a>
```
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 <a href="#alias-lfi-misconfiguration" id="alias-lfi-misconfiguration"></a>
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/](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 seguinte página 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 <a href="#unsafe-variable-use" id="unsafe-variable-use"></a>
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/](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](https://hackerone.com/reports/370094). Se procurarmos pela mensagem de erro, podemos ver que ela é encontrada no [módulo de filtro SSI](https://github.com/nginx/nginx/blob/2187586207e1465d289ae64cedc829719a048a39/src/http/modules/ngx_http_ssi_filter_module.c#L365), 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:
```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!"]
```
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](http://nginx.org/en/docs/http/ngx\_http\_proxy\_module.html#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](http://nginx.org/en/docs/http/ngx\_http\_proxy\_module.html#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](http://nginx.org/en/docs/http/ngx\_http\_core\_module.html#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](https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d).
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](https://nginx.org/en/docs/http/ngx_http_map_module.html):
> 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/](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**](../../pentesting-web/h2c-smuggling.md) 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](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" %}
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](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 más configurações de segurança e automatizar a detecção de falhas.
### [Nginxpwner](https://github.com/stark0de/nginxpwner)
Nginxpwner é uma ferramenta simples para procurar más configurações 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/image (2).png" alt=""><figcaption></figcaption></figure>
**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/" %}
<details>
<summary><strong>Aprenda hacking no 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 [**material oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao grupo [**telegram**](https://t.me/peass) ou **siga**-me no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Compartilhe suas dicas de hacking enviando PRs para os repositórios github do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>