Utilisez [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) pour construire et **automatiser des workflows** grâce aux outils communautaires **les plus avancés**.\
<summary><strong>Apprenez le hacking AWS de zéro à héros avec</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)!
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Partagez vos astuces de hacking en soumettant des PR aux dépôts github** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
Le principal problème pour abuser des conditions de course est que vous avez besoin que les requêtes soient traitées en parallèle avec un très court intervalle de temps (généralement >1ms). Dans la section suivante, différentes solutions sont proposées pour rendre cela possible.
L'utilisation d'un seul paquet TCP **élimine complètement l'effet du jitter réseau**, ce qui a clairement un potentiel pour les attaques par condition de course aussi. Cependant, **deux requêtes ne suffisent pas pour une attaque de course fiable** à cause du **jitter côté serveur** - variations dans le temps de traitement des requêtes de l'application causées par des variables incontrôlables comme la contention CPU.
Mais, en utilisant la technique de '**synchronisation du dernier octet**' avec HTTP/1.1, il est possible de pré-envoyer la majeure partie des données en retenant un petit fragment de chaque requête, puis de 'compléter' **20-30 requêtes avec un seul paquet TCP**.
* Si la requête n'a pas de corps, envoyez tous les en-têtes, mais ne définissez pas le drapeau END\_STREAM. Retenez un cadre de données vide avec END\_STREAM défini.
* Si la requête a un corps, envoyez les en-têtes et toutes les données du corps sauf le dernier octet et le drapeau END\_STREAM. Retenez un cadre de données contenant le dernier octet.
* Envoyez un paquet ping pour réchauffer la connexion locale. Si vous ne faites pas cela, la pile réseau du système d'exploitation placera le premier cadre final dans un paquet séparé.
Notez que cela **ne fonctionne pas pour les fichiers statiques** sur certains serveurs, mais les fichiers statiques ne sont pas pertinents pour les attaques par condition de course.
Il est important de noter que de nombreuses applications sont situées derrière un serveur frontal, et celles-ci peuvent décider de transférer certaines requêtes via des connexions existantes vers le back-end, et de créer de nouvelles connexions pour d'autres.
En conséquence, il est important de ne pas attribuer un timing de requête incohérent au comportement de l'application, tel que des mécanismes de verrouillage qui ne permettent qu'à un seul thread d'accéder à une ressource à la fois. De plus, le routage des requêtes frontales est souvent effectué sur une base par connexion, donc vous pourriez être en mesure d'améliorer le timing des requêtes en effectuant un réchauffement de connexion côté serveur - **envoyer quelques requêtes insignifiantes dans votre connexion avant de réaliser l'attaque** (cela consiste juste à envoyer plusieurs requêtes avant de commencer l'attaque réelle).
Certains frameworks tentent de prévenir la corruption accidentelle des données en utilisant une forme de **verrouillage des requêtes**. Par exemple, le module de gestion de session natif de **PHP** ne traite **qu'une requête par session à la fois**.
Il est extrêmement important de repérer ce type de comportement car il peut sinon masquer des vulnérabilités trivialement exploitables. Si vous remarquez que toutes vos requêtes sont traitées séquentiellement, essayez d'envoyer chacune d'elles en utilisant un token de session différent.
En utilisant Turbo Intruder, vous pouvez introduire un court délai côté client. Cependant, comme cela implique de diviser vos requêtes d'attaque réelles en plusieurs paquets TCP, vous ne pourrez pas utiliser la technique d'attaque par paquet unique. En conséquence, sur des cibles à fort jitter, l'attaque est peu susceptible de fonctionner de manière fiable, quel que soit le délai que vous définissez.
Les serveurs Web retardent souvent le traitement des requêtes si trop sont envoyées trop rapidement. En envoyant un grand nombre de requêtes factices pour déclencher intentionnellement la limite de taux ou de ressources, vous pourriez être en mesure de provoquer un délai côté serveur approprié. Cela rend l'attaque par paquet unique viable même lorsque l'exécution retardée est requise.
Pour plus d'informations sur cette technique, consultez le rapport original sur [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)
* **Turbo Intruder - Attaque par paquet unique HTTP2 (1 point de terminaison)** : Vous pouvez envoyer la requête à **Turbo Intruder** (`Extensions` -> `Turbo Intruder` -> `Envoyer à Turbo Intruder`), vous pouvez changer dans la requête la valeur que vous souhaitez forcer pour **`%s`** comme dans `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s` puis sélectionnez le **`examples/race-single-packer-attack.py`** dans le menu déroulant :
* **Tubo Intruder - Attaque en un seul paquet HTTP2 (Plusieurs points de terminaison)** : Si vous devez envoyer une requête à 1 point de terminaison puis plusieurs à d'autres points de terminaison pour déclencher le RCE, vous pouvez modifier le script `race-single-packet-attack.py` avec quelque chose comme :
* Pour un **dépassement de limite**, vous pourriez simplement ajouter **la même requête 50 fois** dans le groupe.
* Pour le **préchauffage de connexion**, vous pourriez **ajouter** au **début** du **groupe** quelques **requêtes** vers une partie non statique du serveur web.
* Pour **retarder** le processus **entre** le traitement **d'une requête et une autre** en 2 étapes de sous-états, vous pourriez **ajouter des requêtes supplémentaires entre** les deux requêtes.
* Pour un RC **multi-point d'accès**, vous pourriez commencer par envoyer la **requête** qui **va vers l'état caché** puis **50 requêtes** juste après qui **exploitent l'état caché**.
Avant les recherches précédentes, voici quelques charges utiles utilisées qui tentaient simplement d'envoyer les paquets aussi rapidement que possible pour provoquer un RC.
* **Repeater :** Consultez les exemples de la section précédente.
* **Intruder :** Envoyez la **requête** à **Intruder**, réglez le **nombre de threads** sur **30** dans le **menu Options**, sélectionnez comme charge utile **Null payloads** et générez **30**.
C'est le type le plus basique de condition de concurrence où les **vulnérabilités****apparaissent** dans des endroits qui **limitent le nombre de fois où vous pouvez effectuer une action**. Comme utiliser plusieurs fois le même code de réduction dans une boutique en ligne. Un exemple très simple peut être trouvé dans [**ce rapport**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43) ou dans [**ce bug**](https://hackerone.com/reports/759247).
D'autres RC plus compliqués exploiteront les **sous-états dans l'état de la machine** qui pourraient permettre à un attaquant d'**abuser** d'états auxquels il n'était **jamais censé avoir accès**, mais il existe une **petite fenêtre** pour que l'attaquant y accède.
La première étape consiste à identifier tous les points de terminaison qui écrivent dessus, ou lisent des données à partir de celui-ci et utilisent ensuite ces données pour quelque chose d'important. Par exemple, les utilisateurs peuvent être stockés dans une table de base de données qui est modifiée par l'inscription, les modifications de profil, l'initiation de réinitialisation de mot de passe et la complétion de réinitialisation de mot de passe.
Nous pouvons utiliser trois questions clés pour écarter les points de terminaison qui sont peu susceptibles de provoquer des collisions. Pour chaque objet et les points de terminaison associés, demandez :
Les données stockées dans une structure de données persistante côté serveur sont idéales pour l'exploitation. Certains points de terminaison stockent leur état entièrement côté client, comme les réinitialisations de mot de passe qui fonctionnent en envoyant un JWT par email - ceux-ci peuvent être ignorés en toute sécurité.
Les applications stockent souvent un certain état dans la session utilisateur. Celles-ci sont souvent quelque peu protégées contre les sous-états - plus à ce sujet plus tard.
Les opérations qui modifient des données existantes (telles que changer l'adresse email principale d'un compte) ont un potentiel de collision important, tandis que les actions qui ajoutent simplement à des données existantes (telles que l'ajout d'une adresse email supplémentaire) sont peu susceptibles d'être vulnérables à autre chose que des attaques de dépassement de limite.
La plupart des points de terminaison opèrent sur un enregistrement spécifique, qui est recherché à l'aide d'une 'clé', telle qu'un nom d'utilisateur, un jeton de réinitialisation de mot de passe ou un nom de fichier. Pour une attaque réussie, nous avons besoin de deux opérations qui utilisent la même clé. Par exemple, imaginez deux implémentations plausibles de réinitialisation de mot de passe :
À ce stade, il est temps de **lancer des attaques RC** sur les points de terminaison potentiellement intéressants pour essayer de trouver des résultats inattendus par rapport aux réponses habituelles. **Tout écart par rapport à la réponse attendue**, comme un changement dans une ou plusieurs réponses, ou un effet secondaire comme un contenu d'email différent ou un changement visible dans votre session pourrait être un indice indiquant que quelque chose ne va pas.
Lorsque vous envoyez un lot de requêtes, vous pouvez constater qu'une paire de requêtes initiales déclenche un état final vulnérable, mais que les requêtes ultérieures l'écrasent/le rendent invalide et que l'état final n'est pas exploitable. Dans ce scénario, vous voudrez éliminer toutes les requêtes inutiles - deux devraient suffire pour exploiter la plupart des vulnérabilités. Cependant, réduire à deux requêtes rendra l'attaque plus sensible au timing, vous devrez donc peut-être réessayer l'attaque plusieurs fois ou l'automatiser.
Parfois, vous ne trouverez pas de conditions de concurrence, mais les **techniques pour envoyer des requêtes avec un timing précis** peuvent encore révéler la présence d'autres vulnérabilités.
Un tel exemple est lorsque des **horodatages de haute résolution sont utilisés au lieu de chaînes aléatoires sécurisées cryptographiquement** pour générer des jetons de sécurité.
Considérez un **jeton de réinitialisation de mot de passe qui est seulement randomisé en utilisant un horodatage**. Dans ce cas, il pourrait être possible de **déclencher deux réinitialisations de mot de passe pour deux utilisateurs différents**, qui utilisent tous les deux le **même jeton**. Tout ce que vous avez à faire est de synchroniser les requêtes pour qu'elles génèrent le même horodatage.
Pour confirmer par exemple la situation précédente, vous pourriez simplement demander **2 jetons de réinitialisation de mot de passe en même temps** (en utilisant une attaque par paquet unique) et vérifier s'ils sont les **mêmes**.
Vérifiez l'[**exemple dans ce laboratoire**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities).
[**Vérifiez ce laboratoire**](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation) pour voir comment **payer** dans un magasin et **ajouter un article supplémentaire** que vous **n'aurez pas à payer**.
L'idée est de **vérifier une adresse email et de la changer pour une autre en même temps** pour découvrir si la plateforme vérifie la nouvelle changée.
Selon [**ce compte-rendu**](https://portswigger.net/research/smashing-the-state-machine) Gitlab était vulnérable à une prise de contrôle de cette manière car il pourrait **envoyer** le **jeton de vérification d'email d'un email à l'autre email**.
Vous pouvez également vérifier [**ce laboratoire**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) pour en savoir plus à ce sujet.
Si **2 écritures différentes** sont utilisées pour **ajouter** des **informations** dans une **base de données**, il existe une petite portion de temps où **seules les premières données ont été écrites** dans la base de données. Par exemple, lors de la création d'un utilisateur, le **nom d'utilisateur** et le **mot de passe** pourraient être **écrits** et **ensuite le jeton** pour confirmer le compte nouvellement créé est écrit. Cela signifie que pendant un court moment, le **jeton pour confirmer un compte est nul**.
Par conséquent, **enregistrer un compte et envoyer plusieurs requêtes avec un jeton vide** (`token=` ou `token[]=` ou toute autre variation) pour confirmer le compte immédiatement pourrait permettre de **confirmer un compte** où vous ne contrôlez pas l'email.
Comme vous pouvez le voir, il s'agit en fait d'une **séquence multi-étapes dans la durée d'une seule requête**. Plus important encore, elle passe par un sous-état dans lequel **l'utilisateur a temporairement une session valide connectée**, **mais l'authentification multifacteur n'est pas encore appliquée**. Un attaquant pourrait potentiellement exploiter cela en envoyant une demande de connexion avec une demande à un point de terminaison sensible et authentifié.
Il existe plusieurs [**fournisseurs OAuth**](https://en.wikipedia.org/wiki/List_of_OAuth_providers). Ces services vous permettent de créer une application et d'authentifier les utilisateurs que le fournisseur a enregistrés. Pour ce faire, le **client** devra **autoriser votre application** à accéder à certaines de leurs données à l'intérieur du **fournisseur OAuth**.\
Jusqu'ici, juste une connexion classique avec Google/LinkedIn/GitHub... où une page s'affiche disant : "_L'application \<InsertCoolName> souhaite accéder à vos informations, voulez-vous l'autoriser ?_"
Le **problème** apparaît lorsque vous **l'acceptez** et que cela envoie automatiquement un **`authorization_code`** à l'application malveillante. Ensuite, cette **application abuse d'une condition de concurrence dans le fournisseur de services OAuth pour générer plus d'un AT/RT** (_Token d'Authentification/Token de Rafraîchissement_) à partir du **`authorization_code`** pour votre compte. En gros, elle va abuser du fait que vous avez accepté que l'application accède à vos données pour **créer plusieurs comptes**. Ensuite, si vous **arrêtez d'autoriser l'application à accéder à vos données, une paire d'AT/RT sera supprimée, mais les autres resteront valides**.
Une fois que vous avez **obtenu un RT valide**, vous pourriez essayer de **l'abuser pour générer plusieurs AT/RT** et **même si l'utilisateur annule les permissions** pour que l'application malveillante accède à ses données, **plusieurs RT resteront valides**.
Dans [**WS_RaceCondition_PoC**](https://github.com/redrays-io/WS_RaceCondition_PoC), vous pouvez trouver un PoC en Java pour envoyer des messages WebSocket en **parallèle** pour abuser des **conditions de concurrence également dans les WebSockets**.
<summary><strong>Apprenez le hacking AWS de zéro à héros avec</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)!
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Partagez vos astuces de hacking en soumettant des PR aux dépôts GitHub** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
Utilisez [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) pour construire et **automatiser des workflows** facilement, alimentés par les outils communautaires **les plus avancés**.\