> For the complete documentation index, see [llms.txt](https://blog.s1rn3tz.ovh/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://blog.s1rn3tz.ovh/pentest-web/race-conditions.md).

# Race conditions

## Description

Originellement, la situation de concurrence (race-condition) est une situation caractérisée par un résultat différent selon l'ordre dans lequel agissent les acteurs du système. Le terme est plutôt employé à propos de programmes informatiques et de systèmes électroniques. C'est généralement considéré comme un défaut car source de panne ou de blocage.

Une condition de concurrence se produit lorsque deux sections de code conçues pour être exécuté dans une même séquence sont exécutés hors séquence.

La concurrence a deux types : le multitraitement et le multithreading. Le multitraitement fait référence à l'utilisation de plusieurs unités centrales de traitement (CPU), le matériel dans un ordinateur qui exécute des instructions, pour effectuer des simulations calculs fastidieux. D'autre part, le multithreading est la capacité pour un seul processeur de fournir plusieurs threads ou des exécutions simultanées.

Organiser la séquence d'exécution de plusieurs threads s'appelle du scheduling. Différents systèmes utilisent différents algorithmes de planification, selon leurs priorités de performance. Par exemple, certains systèmes peuvent programmer leur tâches en exécutant d'abord les tâches les plus prioritaires, tandis qu'un autre système pourrait exécuter ses tâches en donnant du temps de calcul à tour de rôle, quel que soit priorité.

Cette planification flexible est précisément ce qui provoque des conditions de concurrence. Elles se produisent lorsque les développeurs n'adhèrent pas à certains principes de concurrence.

## Exploitation

### Trouver des fonctionnalitées souvent sensibles aux race conditions

Parmis les fonctionnalitées qu'on retrouve souvent dans ce type d'attaques on trouve:

* Les fonctionnalitées de contrôle d'accès
* Les fonctionnalitées effectuant des décomptes ou touchant plus vagement à des chiffres/nombres (votes, scores, transferts d'argent, montants de cartes cadeau, ...)

On va ensuite copier la requête dans burp suite en faisant un clic droit et en séléctionnant "copy as curl command".

### Envoyer la requête simultanément

### Bash + curl

La seconde étape vise à envoyer la même requête exactement au même moment pour voir s'il est possible de contourner la vérifiacation de pour l'une des deux requêtes.

Exemple:

On a un compte en banque possédant 100€, notre but est de savoir si on peut envoyer plus d'argent que ce que nous avons réellement.

On va donc envoyer la requête de transfert plusieurs fois aussi rapidement que possible avec la requête copiée dans l'étape précédente.

Ce qui nous donnera quelque chose comme:

```
curl ... & curl ... & curl ... & curl ... & curl ... & curl ... & curl ... & curl ... & curl ... & curl ... &
```

{% hint style="info" %}
**&**: permet de lancer une commande en background (les commandes curl sont envoyées en même temps et pas les unes après les autres).
{% endhint %}

{% hint style="warning" %}
Il faut garder en tête que pour tester une race condition, il faut que la requête envoyée ne soit pas répétable (ici, si notre compte contient exactement 100€, si on tente d'envoyer 500€ l'opération sera refusée et inversement si on envoie 10€ l'opération sera autorisée 10 fois ce qui n'est pas le but.
{% endhint %}

### Burp Group Tab

![](https://3571537825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOIXudYEdnnE8JjXBrL0o%2Fuploads%2FnfTDNBljXnJTcDH55yIh%2Fimage.png?alt=media\&token=af34accf-7d53-444b-9243-17896e9f7884)

![](https://3571537825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOIXudYEdnnE8JjXBrL0o%2Fuploads%2FehZy0l4yt1EoV2Tsdl5j%2Fimage.png?alt=media\&token=d2a4db85-a676-40b5-8b06-a13be8146abe)

### Turbo Intruder

Bypass de rate limit

1. Envoyer la requête dans Turbo intruder avec "%s" à la place de l'élément à remplacer
2. Choisir le script qui se rapproche le plus du besoin dans la liste déroulante
3. Modifier le script selon le contexte (wordlists.clipboard, boucles, conditions etc)

#### HTTP/3 avec Turbo Repeater

Pour les serveurs supportant le HTTP/3, Turbo Intruder dispose désormais d’un moteur `HTTP3` et d’un moteur `AUTO` permettant d’adapter les requêtes au protocole et aux conditions réseau.

Turbo Intruder intègre deux techniques destinées à améliorer les tests de concurrence :

* **Single Datagram Attack** : exploite les propriétés de transmission des datagrammes pour synchroniser des requêtes concurrentes.
* **Server-Side Race Orchestration via QPACK Blocked Streams** : utilise les mécanismes de blocage des flux associés à QPACK pour mieux contrôler l’ordonnancement des requêtes côté serveur.

Ces techniques sont accessibles avec le moteur `HTTP3`. Le paramètre `gateMode` permet de sélectionner le mode de synchronisation. La valeur `auto` laisse Turbo Intruder choisir une technique compatible avec les capacités du serveur.

Exemple de script:

```
def queueRequests(target, wordlists):
    engine = RequestEngine(
        endpoint=target.endpoint,
        concurrentConnections=1,
        engine=Engine.HTTP3,
        gateMode='auto'
    )

    # Préparer 20 requêtes sur la même opération
    for i in range(20):
        engine.queue(target.req, gate='race1')

    # Libérer les requêtes synchronisées
    engine.openGate('race1')


def handleResponse(req, interesting):
    # Conserver les réponses pour les analyser
    table.add(req)
```

#### Explication des paramètres

* `engine=Engine.HTTP3` : sélectionne le moteur HTTP/3 de Turbo Intruder.
* `concurrentConnections=1` : utilise une seule connexion configurée pour cet essai ; cela ne signifie pas qu’une seule requête sera exécutée à la fois.
* `gateMode='auto'` : laisse Turbo Intruder choisir la technique de synchronisation compatible avec le serveur.
* `gate='race1'` : associe les requêtes au même groupe de synchronisation.
* `openGate('race1')` : déclenche la libération du groupe préparé.
* `table.add(req)` : ajoute chaque réponse à la table de résultats.
