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

270 lines
16 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><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* 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**](https://github.com/sponsors/carlospolop)!
* 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)
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e para o** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
<figure><img src="../../.gitbook/assets/image (1) (1) (2) (4).png" alt=""><figcaption></figcaption></figure>
[**DragonJAR Security Conference é um evento internacional de cibersegurança**](https://www.dragonjarcon.org/) 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 <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 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 <a href="#alias-lfi-misconfiguration" id="alias-lfi-misconfiguration"></a>
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/](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 <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 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/](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](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 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:
```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` 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](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 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](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".
## 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-resol**ver-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 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**](../../pentesting-web/h2c-smuggling.md) 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](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 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](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 objetivo principal do Gixy é prevenir a configuração incorreta de segurança 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/image (1) (1) (2) (4).png" alt=""><figcaption></figcaption></figure>
[**DragonJAR Security Conference é um evento internacional de cibersegurança**](https://www.dragonjarcon.org/) 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/" %}
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* 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**](https://github.com/sponsors/carlospolop)!
* Descubra [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe suas dicas de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud).
</details>