mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
207 lines
11 KiB
Markdown
207 lines
11 KiB
Markdown
# Poluição de Parâmetros | Injeção de JSON
|
|
|
|
{{#include ../banners/hacktricks-training.md}}
|
|
|
|
## Visão Geral da Poluição de Parâmetros HTTP (HPP)
|
|
|
|
A Poluição de Parâmetros HTTP (HPP) é uma técnica onde atacantes manipulam parâmetros HTTP para alterar o comportamento de uma aplicação web de maneiras não intencionais. Essa manipulação é feita adicionando, modificando ou duplicando parâmetros HTTP. O efeito dessas manipulações não é diretamente visível para o usuário, mas pode alterar significativamente a funcionalidade da aplicação no lado do servidor, com impactos observáveis no lado do cliente.
|
|
|
|
### Exemplo de Poluição de Parâmetros HTTP (HPP)
|
|
|
|
Uma URL de transação de um aplicativo bancário:
|
|
|
|
- **URL Original:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000`
|
|
|
|
Ao inserir um parâmetro `from` adicional:
|
|
|
|
- **URL Manipulada:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000&from=accountC`
|
|
|
|
A transação pode ser incorretamente cobrada para `accountC` em vez de `accountA`, demonstrando o potencial da HPP para manipular transações ou outras funcionalidades, como redefinições de senha, configurações de 2FA ou solicitações de chave de API.
|
|
|
|
#### **Análise de Parâmetros Específica da Tecnologia**
|
|
|
|
- A forma como os parâmetros são analisados e priorizados depende da tecnologia web subjacente, afetando como a HPP pode ser explorada.
|
|
- Ferramentas como [Wappalyzer](https://addons.mozilla.org/en-US/firefox/addon/wappalyzer/) ajudam a identificar essas tecnologias e seus comportamentos de análise.
|
|
|
|
### Exploração de HPP em PHP
|
|
|
|
**Caso de Manipulação de OTP:**
|
|
|
|
- **Contexto:** Um mecanismo de login que requer uma Senha de Uso Único (OTP) foi explorado.
|
|
- **Método:** Ao interceptar a solicitação de OTP usando ferramentas como Burp Suite, os atacantes duplicaram o parâmetro `email` na solicitação HTTP.
|
|
- **Resultado:** O OTP, destinado ao email inicial, foi enviado para o segundo endereço de email especificado na solicitação manipulada. Essa falha permitiu acesso não autorizado ao contornar a medida de segurança pretendida.
|
|
|
|
Esse cenário destaca uma falha crítica no backend da aplicação, que processou o primeiro parâmetro `email` para a geração de OTP, mas usou o último para entrega.
|
|
|
|
**Caso de Manipulação de Chave de API:**
|
|
|
|
- **Cenário:** Um aplicativo permite que os usuários atualizem sua chave de API através de uma página de configurações de perfil.
|
|
- **Vetor de Ataque:** Um atacante descobre que, ao adicionar um parâmetro `api_key` adicional à solicitação POST, pode manipular o resultado da função de atualização da chave de API.
|
|
- **Técnica:** Utilizando uma ferramenta como Burp Suite, o atacante cria uma solicitação que inclui dois parâmetros `api_key`: um legítimo e um malicioso. O servidor, processando apenas a última ocorrência, atualiza a chave de API para o valor fornecido pelo atacante.
|
|
- **Resultado:** O atacante ganha controle sobre a funcionalidade da API da vítima, potencialmente acessando ou modificando dados privados de forma não autorizada.
|
|
|
|
Esse exemplo reforça ainda mais a necessidade de um manuseio seguro de parâmetros, especialmente em recursos tão críticos quanto a gestão de chaves de API.
|
|
|
|
### Análise de Parâmetros: Flask vs. PHP
|
|
|
|
A forma como as tecnologias web lidam com parâmetros HTTP duplicados varia, afetando sua suscetibilidade a ataques HPP:
|
|
|
|
- **Flask:** Adota o primeiro valor de parâmetro encontrado, como `a=1` em uma string de consulta `a=1&a=2`, priorizando a instância inicial em relação a duplicatas subsequentes.
|
|
- **PHP (no Apache HTTP Server):** Por outro lado, prioriza o último valor de parâmetro, optando por `a=2` no exemplo dado. Esse comportamento pode inadvertidamente facilitar explorações de HPP ao honrar o parâmetro manipulado do atacante em vez do original.
|
|
|
|
## Poluição de parâmetros por tecnologia
|
|
|
|
Os resultados foram obtidos de [https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89](https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89)
|
|
|
|
### PHP 8.3.11 E Apache 2.4.62 <a href="#id-9523" id="id-9523"></a>
|
|
|
|
<figure><img src="../images/image (1255).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*l_Pf2JNCYhmfAvfk7UTEbQ.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*l_Pf2JNCYhmfAvfk7UTEbQ.jpeg</a></p></figcaption></figure>
|
|
|
|
1. Ignorar qualquer coisa após %00 no nome do parâmetro.
|
|
2. Tratar name\[] como array.
|
|
3. \_GET não significa Método GET.
|
|
4. Preferir o último parâmetro.
|
|
|
|
### Ruby 3.3.5 e WEBrick 1.8.2
|
|
|
|
<figure><img src="../images/image (1257).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*kKxtZ8qEmgTIMS81py5hhg.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*kKxtZ8qEmgTIMS81py5hhg.jpeg</a></p></figcaption></figure>
|
|
|
|
1. Usa os delimitadores & e ; para dividir parâmetros.
|
|
2. Não reconhece name\[].
|
|
3. Preferir o primeiro parâmetro.
|
|
|
|
### Spring MVC 6.0.23 E Apache Tomcat 10.1.30 <a href="#dd68" id="dd68"></a>
|
|
|
|
<figure><img src="../images/image (1258).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*llG22MF1gPTYZYFVCmCiVw.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*llG22MF1gPTYZYFVCmCiVw.jpeg</a></p></figcaption></figure>
|
|
|
|
1. POST RequestMapping == PostMapping & GET RequestMapping == GetMapping.
|
|
2. POST RequestMapping & PostMapping reconhecem name\[].
|
|
3. Preferir name se name E name\[] existirem.
|
|
4. Concatenar parâmetros, e.g., first,last.
|
|
5. POST RequestMapping & PostMapping reconhecem parâmetros de consulta com Content-Type.
|
|
|
|
### **NodeJS** 20.17.0 **E** Express 4.21.0 <a href="#id-6d72" id="id-6d72"></a>
|
|
|
|
<figure><img src="../images/image (1259).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*JzNkLOSW7orcHXswtMHGMA.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*JzNkLOSW7orcHXswtMHGMA.jpeg</a></p></figcaption></figure>
|
|
|
|
1. Reconhece name\[].
|
|
2. Concatenar parâmetros, e.g., first,last.
|
|
|
|
### GO 1.22.7 <a href="#id-63dc" id="id-63dc"></a>
|
|
|
|
<figure><img src="../images/image (1260).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*NVvN1N8sL4g_Gi796FzlZA.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*NVvN1N8sL4g_Gi796FzlZA.jpeg</a></p></figcaption></figure>
|
|
|
|
1. NÃO reconhece name\[].
|
|
2. Preferir o primeiro parâmetro.
|
|
|
|
### Python 3.12.6 E Werkzeug 3.0.4 E Flask 3.0.3 <a href="#b853" id="b853"></a>
|
|
|
|
<figure><img src="../images/image (1261).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*Se5467PFFjIlmT3O7KNlWQ.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*Se5467PFFjIlmT3O7KNlWQ.jpeg</a></p></figcaption></figure>
|
|
|
|
1. NÃO reconhece name\[].
|
|
2. Preferir o primeiro parâmetro.
|
|
|
|
### Python 3.12.6 E Django 4.2.15 <a href="#id-8079" id="id-8079"></a>
|
|
|
|
<figure><img src="../images/image (1262).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*rf38VXut5YhAx0ZhUzgT8Q.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*rf38VXut5YhAx0ZhUzgT8Q.jpeg</a></p></figcaption></figure>
|
|
|
|
1. NÃO reconhece name\[].
|
|
2. Preferir o último parâmetro.
|
|
|
|
### Python 3.12.6 E Tornado 6.4.1 <a href="#id-2ad8" id="id-2ad8"></a>
|
|
|
|
<figure><img src="../images/image (1263).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*obCn7xahDc296JZccXM2qQ.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*obCn7xahDc296JZccXM2qQ.jpeg</a></p></figcaption></figure>
|
|
|
|
1. NÃO reconhece name\[].
|
|
2. Preferir o último parâmetro.
|
|
|
|
## Injeção de JSON
|
|
|
|
### Chaves duplicadas
|
|
```ini
|
|
obj = {"test": "user", "test": "admin"}
|
|
```
|
|
A interface pode acreditar na primeira ocorrência, enquanto o backend usa a segunda ocorrência da chave.
|
|
|
|
### Colisão de Chaves: Truncamento de Caracteres e Comentários
|
|
|
|
Certos caracteres não serão interpretados corretamente pela interface, mas o backend os interpretará e usará essas chaves, isso pode ser útil para **contornar certas restrições**:
|
|
```json
|
|
{"test": 1, "test\[raw \x0d byte]": 2}
|
|
{"test": 1, "test\ud800": 2}
|
|
{"test": 1, "test"": 2}
|
|
{"test": 1, "te\st": 2}
|
|
```
|
|
Observe como, nesses casos, o front end pode pensar que `test == 1` e o backend pensará que `test == 2`.
|
|
|
|
Isso também pode ser usado para contornar restrições de valor, como:
|
|
```json
|
|
{"role": "administrator\[raw \x0d byte]"}
|
|
{"role":"administrator\ud800"}
|
|
{"role": "administrator""}
|
|
{"role": "admini\strator"}
|
|
```
|
|
### **Usando Truncamento de Comentários**
|
|
```ini
|
|
obj = {"description": "Duplicate with comments", "test": 2, "extra": /*, "test": 1, "extra2": */}
|
|
```
|
|
Aqui usaremos o serializador de cada parser para visualizar sua respectiva saída.
|
|
|
|
Serializer 1 (por exemplo, a biblioteca GoJay do GoLang) produzirá:
|
|
|
|
- `description = "Duplicate with comments"`
|
|
- `test = 2`
|
|
- `extra = ""`
|
|
|
|
Serializer 2 (por exemplo, a biblioteca JSON-iterator do Java) produzirá:
|
|
|
|
- `description = "Duplicate with comments"`
|
|
- `extra = "/*"`
|
|
- `extra2 = "*/"`
|
|
- `test = 1`
|
|
|
|
Alternativamente, o uso direto de comentários também pode ser eficaz:
|
|
```ini
|
|
obj = {"description": "Comment support", "test": 1, "extra": "a"/*, "test": 2, "extra2": "b"*/}
|
|
```
|
|
A biblioteca GSON do Java:
|
|
```json
|
|
{ "description": "Comment support", "test": 1, "extra": "a" }
|
|
```
|
|
A biblioteca simdjson do Ruby:
|
|
```json
|
|
{ "description": "Comment support", "test": 2, "extra": "a", "extra2": "b" }
|
|
```
|
|
### **Precedência Inconsistente: Desserialização vs. Serialização**
|
|
```ini
|
|
obj = {"test": 1, "test": 2}
|
|
|
|
obj["test"] // 1
|
|
obj.toString() // {"test": 2}
|
|
```
|
|
### Float e Inteiro
|
|
|
|
O número
|
|
```undefined
|
|
999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
|
|
```
|
|
pode ser decodificado em múltiplas representações, incluindo:
|
|
```undefined
|
|
999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
|
|
9.999999999999999e95
|
|
1E+96
|
|
0
|
|
9223372036854775807
|
|
```
|
|
Que pode criar inconsistências
|
|
|
|
## Referências
|
|
|
|
- [https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654](https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654)
|
|
- [https://github.com/google/google-ctf/tree/master/2023/web-under-construction/solution](https://github.com/google/google-ctf/tree/master/2023/web-under-construction/solution)
|
|
- [https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89](https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89)
|
|
- [https://bishopfox.com/blog/json-interoperability-vulnerabilities](https://bishopfox.com/blog/json-interoperability-vulnerabilities)
|
|
|
|
|
|
{{#include ../banners/hacktricks-training.md}}
|