hacktricks/pentesting-web/race-condition.md

343 lines
25 KiB
Markdown
Raw Normal View History

2023-06-03 13:10:46 +00:00
# Condition de course
2022-04-28 16:01:33 +00:00
<figure><img src="../.gitbook/assets/image (3) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
2022-08-31 22:35:39 +00:00
\
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**.\
Obtenez l'accès aujourd'hui :
2022-08-31 22:35:39 +00:00
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
2022-04-28 16:01:33 +00:00
<details>
<summary><strong>Apprenez le hacking AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
2022-04-28 16:01:33 +00:00
Autres moyens de soutenir HackTricks :
* 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)!
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* Découvrez [**La Famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection d'[**NFTs**](https://opensea.io/collection/the-peass-family) exclusifs
* **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).
2022-04-28 16:01:33 +00:00
</details>
## Exploiter une condition de course
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 une très courte différence de temps (généralement >1ms). Dans la section suivante, différentes solutions sont proposées pour rendre cela possible.
<figure><img src="../.gitbook/assets/image (5) (1) (1).png" alt=""><figcaption></figcaption></figure>
### Attaque par un seul paquet (HTTP/2) / Synchronisation du dernier octet (HTTP/1.1)
HTTP2 permet d'envoyer **2 requêtes dans une seule connexion TCP** (alors qu'en HTTP/1.1 elles doivent être séquentielles).\
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**.
Pour **pré-envoyer la majeure partie de chaque requête** :
* 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. Retenez un cadre de données contenant le dernier octet.
Ensuite, **préparez-vous à envoyer les cadres finaux** :
* Attendez 100ms pour vous assurer que les cadres initiaux ont été envoyés.
* Assurez-vous que TCP\_NODELAY est désactivé - il est crucial que l'algorithme de Nagle regroupe les cadres finaux.
* 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é.
Enfin, envoyez les cadres retenus. Vous devriez pouvoir vérifier qu'ils ont atterri dans un seul paquet en utilisant Wireshark.
{% hint style="info" %}
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.
{% endhint %}
En utilisant cette technique, vous pouvez faire en sorte que 20-30 requêtes arrivent simultanément au serveur - indépendamment du jitter réseau :
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
**Adaptation à l'architecture cible**
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 serveur de fond, 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 à un comportement d'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 de régulariser le timing des requêtes en effectuant un réchauffement de connexion côté serveur - **envoyant 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).
#### Mécanismes de verrouillage basés sur la session <a href="#session-based-locking-mechanisms" id="session-based-locking-mechanisms"></a>
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.
#### **Abuser des limites de taux ou de ressources**
Si le réchauffement de connexion ne fait aucune différence, il existe diverses solutions à ce problème.
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 un seul paquet. 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.
<figure><img src="../.gitbook/assets/image (2) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
Au lieu de cela, vous pourriez être en mesure de résoudre ce problème en abusant d'une fonctionnalité de sécurité courante.
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 un seul paquet viable même lorsque l'exécution retardée est requise.
<figure><img src="../.gitbook/assets/image (3) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
{% hint style="warning" %}
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)
{% endhint %}
#### Exemples d'attaque
* **Turbo Intruder - Attaque par un seul paquet 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 **`examples/race-single-packer-attack.py`** dans le menu déroulant :
<figure><img src="../.gitbook/assets/image (4) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
Si vous allez **envoyer différentes valeurs**, vous pourriez modifier le code avec celui qui utilise une liste de mots du presse-papiers :
```python
passwords = wordlists.clipboard
for password in passwords:
engine.queue(target.req, password, gate='race1')
```
{% hint style="warning" %}
Si le web ne supporte pas HTTP2 (seulement HTTP1.1), utilisez `Engine.THREADED` ou `Engine.BURP` au lieu de `Engine.BURP2`.
{% endhint %}
* **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 :
```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)
```
* Il est également disponible dans **Repeater** via la nouvelle option '**Envoyer le groupe en parallèle**' dans Burp Suite.
* 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é**.
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
### BF Brut
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** à **30** dans le **menu Options**, sélectionnez comme charge utile **Null payloads** et générez **30**.
* **Turbo Intruder**
```python
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
pipeline=False
)
a = ['Session=<session_id_1>','Session=<session_id_2>','Session=<session_id_3>']
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**
2022-10-11 22:51:42 +00:00
```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
2022-10-11 22:51:42 +00:00
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)
2022-10-11 22:51:42 +00:00
asyncio.run(main())
```
## **Méthodologie RC**
### Dépassement de limite / TOCTOU
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).
Il existe de nombreuses variations de ce type d'attaque, y compris :
* Utiliser plusieurs fois une carte cadeau
* Noter plusieurs fois un produit
* Retirer ou transférer de l'argent au-delà du solde de votre compte
* Réutiliser une seule solution CAPTCHA
* Contourner une limite de taux anti-force brute
### **Sous-états cachés**
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.
1. **Prédire les sous-états cachés et intéressants potentiels**
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 :
* **Comment l'état est-il stocké ?**
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 e-mail - 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.
* **Modifions-nous ou ajoutons-nous ?**
Les opérations qui modifient des données existantes (telles que le changement de l'adresse e-mail principale d'un compte) ont un potentiel de collision important, tandis que les actions qui ajoutent simplement aux données existantes (telles que l'ajout d'une adresse e-mail supplémentaire) sont peu susceptibles d'être vulnérables à autre chose que des attaques de dépassement de limite.
* **Sur quoi l'opération est-elle basée ?**
2022-10-11 22:51:42 +00:00
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 :
<figure><img src="../.gitbook/assets/image (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
2. **Chercher des indices**
À 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ésultats habituels. **Tout écart par rapport à la réponse attendue**, tel qu'un changement dans une ou plusieurs réponses, ou un effet secondaire comme un contenu d'e-mail différent ou un changement visible dans votre session pourrait être un indice indiquant que quelque chose ne va pas.
3. **Prouver le concept**
La dernière étape consiste à **prouver le concept et à le transformer en une attaque viable**.
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/l'invalident et que l'état final est inexploitable. 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.
### Attaques sensibles au temps
Parfois, vous ne trouverez peut-être 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.
{% hint style="warning" %}
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**.
{% endhint %}
Consultez [**l'exemple dans ce laboratoire**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities).
## Études de cas sur les sous-états cachés
### Payer & ajouter un article
[**Consultez 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**.
### Confirmer d'autres e-mails
L'idée est de **vérifier une adresse e-mail et de la changer pour une autre en même temps** pour découvrir si la plateforme vérifie la nouvelle changée.
### Changer d'e-mail en 2 adresses e-mails basées sur les cookies
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'e-mail d'un e-mail à l'autre e-mail**.
Vous pouvez également consulter [**ce laboratoire**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) pour en savoir plus à ce sujet.
### États de base de données cachés / Contournement de confirmation
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'e-mail.
Consultez [**ce laboratoire**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) pour voir un exemple.
### Contourner la 2FA
Le pseudo-code suivant montre comment un site Web pourrait être vulnérable à une variation de course de cette attaque :
```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
```
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 (MFA) 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é.
### Persistance éternelle OAuth2
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 au sein du **fournisseur OAuth**.\
Jusqu'ici, c'est juste une connexion classique avec Google/LinkedIn/GitHub... où une page vous demande : "_L'application \<InsertCoolName> souhaite accéder à vos informations, voulez-vous l'autoriser ?_"
#### Condition de concurrence dans `authorization_code`
Le **problème** apparaît lorsque vous **l'acceptez** et qu'un **`authorization_code`** est automatiquement envoyé à l'application malveillante. Ensuite, cette **application exploite 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é l'application pour accéder à 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**.
#### Condition de concurrence dans `Refresh Token`
Une fois que vous avez **obtenu un RT valide**, vous pourriez essayer de **l'exploiter 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**.
## **RC dans WebSockets**
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 exploiter les **conditions de concurrence également dans les WebSockets**.
2023-06-03 13:10:46 +00:00
## Références
* [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)
2022-04-28 16:01:33 +00:00
<details>
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Autres moyens de soutenir HackTricks :
2022-04-28 16:01:33 +00:00
* 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)!
* Obtenez le [**merchandising officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* Découvrez [**La Famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection d'[**NFTs**](https://opensea.io/collection/the-peass-family) exclusifs
* **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 piratage en soumettant des PR aux dépôts GitHub** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
2022-04-28 16:01:33 +00:00
</details>
<figure><img src="../.gitbook/assets/image (3) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
2022-08-31 22:35:39 +00:00
\
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**.\
Obtenez l'accès aujourd'hui :
2022-04-28 16:01:33 +00:00
2022-08-31 22:35:39 +00:00
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}