Cookies Hacking
Last updated
Last updated
Groupe de sécurité Try Hard
Les cookies sont accompagnés de plusieurs attributs qui contrôlent leur comportement dans le navigateur de l'utilisateur. Voici un aperçu de ces attributs dans une voix plus passive :
La date d'expiration d'un cookie est déterminée par l'attribut Expires
. En revanche, l'attribut Max-age
définit le temps en secondes avant qu'un cookie ne soit supprimé. Optez pour Max-age
car il reflète des pratiques plus modernes.
Les hôtes recevant un cookie sont spécifiés par l'attribut Domain
. Par défaut, cela est défini sur l'hôte qui a émis le cookie, sans inclure ses sous-domaines. Cependant, lorsque l'attribut Domain
est explicitement défini, il englobe également les sous-domaines. Cela rend la spécification de l'attribut Domain
une option moins restrictive, utile pour les scénarios où le partage de cookies entre les sous-domaines est nécessaire. Par exemple, en définissant Domain=mozilla.org
, les cookies sont accessibles sur ses sous-domaines comme developer.mozilla.org
.
Un chemin d'URL spécifique qui doit être présent dans l'URL demandée pour que l'en-tête Cookie
soit envoyé est indiqué par l'attribut Path
. Cet attribut considère le caractère /
comme un séparateur de répertoire, permettant des correspondances dans les sous-répertoires également.
Lorsque deux cookies portent le même nom, celui choisi pour l'envoi est basé sur :
Le cookie correspondant au chemin le plus long dans l'URL demandée.
Le cookie le plus récemment défini si les chemins sont identiques.
L'attribut SameSite
dicte si les cookies sont envoyés sur des requêtes provenant de domaines tiers. Il offre trois paramètres :
Strict : Restreint l'envoi du cookie sur des requêtes tierces.
Lax : Autorise l'envoi du cookie avec des requêtes GET initiées par des sites tiers.
None : Autorise l'envoi du cookie à partir de n'importe quel domaine tiers.
N'oubliez pas que lors de la configuration des cookies, la compréhension de ces attributs peut aider à garantir qu'ils se comportent comme prévu dans différents scénarios.
Type de Requête | Code Exemple | Cookies Envoyés Lorsque |
Lien | <a href="..."></a> | NotSet*, Lax, None |
Prerender | <link rel="prerender" href=".."/> | NotSet*, Lax, None |
Formulaire GET | <form method="GET" action="..."> | NotSet*, Lax, None |
Formulaire POST | <form method="POST" action="..."> | NotSet*, None |
iframe | <iframe src="..."></iframe> | NotSet*, None |
AJAX | $.get("...") | NotSet*, None |
Image | <img src="..."> | NetSet*, None |
Tableau de Invicti et légèrement modifié. Un cookie avec l'attribut SameSite aidera à atténuer les attaques CSRF où une session connectée est nécessaire.
*Notez qu'à partir de Chrome80 (fév/2019), le comportement par défaut d'un cookie sans attribut SameSite sera lax (https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/). Notez temporairement, après l'application de ce changement, les cookies sans politique SameSite dans Chrome seront traités comme None pendant les 2 premières minutes puis comme Lax pour les requêtes POST intersites de niveau supérieur.
Cela empêche le client d'accéder au cookie (via Javascript par exemple : document.cookie
)
Si la page envoie les cookies en réponse à une requête (par exemple dans une page PHPinfo), il est possible d'exploiter la XSS pour envoyer une requête à cette page et voler les cookies de la réponse (consultez un exemple sur https://hackcommander.github.io/posts/2022/11/12/bypass-httponly-via-php-info-page/.
Cela peut être contourné avec des requêtes TRACE HTTP car la réponse du serveur (si cette méthode HTTP est disponible) reflétera les cookies envoyés. Cette technique est appelée Suivi intersites.
Cette technique est évitée par les navigateurs modernes en ne permettant pas l'envoi d'une requête TRACE depuis JS. Cependant, certains contournements à cela ont été trouvés dans des logiciels spécifiques comme l'envoi de \r\nTRACE
au lieu de TRACE
à IE6.0 SP2.
Une autre méthode est l'exploitation de vulnérabilités zero/day des navigateurs.
Il est possible de remplacer les cookies HttpOnly en effectuant une attaque de débordement de Cookie Jar :
Il est possible d'utiliser une attaque de Smuggling de Cookies pour exfiltrer ces cookies
La requête enverra le cookie uniquement dans une requête HTTP si la requête est transmise sur un canal sécurisé (typiquement HTTPS).
Les cookies préfixés par __Secure-
doivent être définis avec le drapeau secure
sur les pages sécurisées par HTTPS.
Pour les cookies préfixés par __Host-
, plusieurs conditions doivent être remplies :
Ils doivent être définis avec le drapeau secure
.
Ils doivent provenir d'une page sécurisée par HTTPS.
Ils sont interdits de spécifier un domaine, empêchant leur transmission aux sous-domaines.
Le chemin de ces cookies doit être défini sur /
.
Il est important de noter que les cookies préfixés par __Host-
ne sont pas autorisés à être envoyés aux superdomaines ou aux sous-domaines. Cette restriction aide à isoler les cookies d'application. Ainsi, l'utilisation du préfixe __Host-
pour tous les cookies d'application peut être considérée comme une bonne pratique pour renforcer la sécurité et l'isolation.
Ainsi, l'une des protections des cookies préfixés par __Host-
est d'empêcher leur écrasement par des sous-domaines. Empêchant par exemple les attaques de Cookie Tossing. Dans la présentation Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities (article) il est présenté qu'il était possible de définir des cookies préfixés par __HOST- depuis un sous-domaine, en trompant l'analyseur, par exemple, en ajoutant "=" au début ou au début et à la fin...:
Ou en PHP il était possible d'ajouter d'autres caractères au début du nom du cookie qui allaient être remplacés par des caractères de soulignement, permettant d'écraser les cookies __HOST-
:
Si un cookie personnalisé contient des données sensibles, vérifiez-le (surtout si vous participez à un CTF), car il pourrait être vulnérable.
Les données sensibles intégrées dans les cookies doivent toujours être examinées. Les cookies encodés en Base64 ou des formats similaires peuvent souvent être décodés. Cette vulnérabilité permet aux attaquants de modifier le contenu du cookie et d'usurper l'identité d'autres utilisateurs en encodant leurs données modifiées dans le cookie.
Cette attaque consiste à voler le cookie d'un utilisateur pour accéder de manière non autorisée à son compte au sein d'une application. En utilisant le cookie volé, un attaquant peut usurper l'utilisateur légitime.
Dans ce scénario, un attaquant trompe une victime pour qu'elle utilise un cookie spécifique pour se connecter. Si l'application ne génère pas un nouveau cookie lors de la connexion, l'attaquant, possédant le cookie original, peut usurper la victime. Cette technique repose sur la victime se connectant avec un cookie fourni par l'attaquant.
Si vous avez trouvé un XSS dans un sous-domaine ou que vous contrôlez un sous-domaine, lisez :
Cookie TossingIci, l'attaquant convainc la victime d'utiliser le cookie de session de l'attaquant. La victime, croyant être connectée à son propre compte, effectuera involontairement des actions dans le contexte du compte de l'attaquant.
Si vous avez trouvé un XSS dans un sous-domaine ou que vous contrôlez un sous-domaine, lisez :
Cookie TossingCliquez sur le lien précédent pour accéder à une page expliquant les failles possibles dans les JWT.
Les JSON Web Tokens (JWT) utilisés dans les cookies peuvent également présenter des vulnérabilités. Pour des informations approfondies sur les failles potentielles et comment les exploiter, l'accès au document lié sur le piratage des JWT est recommandé.
Cette attaque force un utilisateur connecté à exécuter des actions non désirées sur une application web à laquelle il est actuellement authentifié. Les attaquants peuvent exploiter les cookies qui sont automatiquement envoyés avec chaque requête vers le site vulnérable.
(Vérifiez les détails supplémentaires dans la recherche originale) Les navigateurs permettent la création de cookies sans nom, ce qui peut être démontré en JavaScript comme suit:
Le résultat dans l'en-tête cookie envoyé est a=v1; test value; b=v2;
. De manière intrigante, cela permet la manipulation des cookies si un cookie avec un nom vide est défini, contrôlant potentiellement d'autres cookies en définissant le cookie vide sur une valeur spécifique:
Cela conduit le navigateur à envoyer un en-tête de cookie interprété par chaque serveur web comme un cookie nommé a
avec une valeur b
.
Dans Chrome, si un point de code de substitution Unicode fait partie d'un cookie défini, document.cookie
devient corrompu, renvoyant ensuite une chaîne vide :
Cela se traduit par document.cookie
produisant une chaîne vide, indiquant une corruption permanente.
(Vérifiez plus de détails dans la recherche originale) Plusieurs serveurs web, y compris ceux de Java (Jetty, TomCat, Undertow) et Python (Zope, cherrypy, web.py, aiohttp, bottle, webob), gèrent mal les chaînes de cookies en raison du support obsolète de RFC2965. Ils lisent une valeur de cookie entre guillemets doubles comme une seule valeur même si elle inclut des points-virgules, qui devraient normalement séparer les paires clé-valeur:
(Vérifiez les détails supplémentaires dans la recherche originale) L'analyse incorrecte des cookies par les serveurs, notamment Undertow, Zope et ceux utilisant http.cookie.SimpleCookie
et http.cookie.BaseCookie
de Python, crée des opportunités pour des attaques d'injection de cookies. Ces serveurs ne parviennent pas à délimiter correctement le début de nouveaux cookies, permettant aux attaquants de falsifier des cookies :
Undertow attend un nouveau cookie immédiatement après une valeur entre guillemets sans point-virgule.
Zope recherche une virgule pour commencer l'analyse du cookie suivant.
Les classes de cookies de Python commencent l'analyse sur un caractère d'espace.
Cette vulnérabilité est particulièrement dangereuse dans les applications web reposant sur une protection CSRF basée sur les cookies, car elle permet aux attaquants d'injecter des cookies de jeton CSRF falsifiés, contournant potentiellement les mesures de sécurité. Le problème est aggravé par la gestion des noms de cookies en double par Python, où la dernière occurrence remplace les précédentes. Cela soulève également des préoccupations pour les cookies __Secure-
et __Host-
dans des contextes non sécurisés et pourrait entraîner des contournements d'autorisation lorsque les cookies sont transmis à des serveurs back-end susceptibles de falsification.
Le cookie est le même à chaque fois que vous vous connectez.
Déconnectez-vous et essayez d'utiliser le même cookie.
Essayez de vous connecter avec 2 appareils (ou navigateurs) sur le même compte en utilisant le même cookie.
Vérifiez si le cookie contient des informations et essayez de le modifier.
Essayez de créer plusieurs comptes avec des noms d'utilisateur presque identiques et vérifiez s'il y a des similitudes.
Vérifiez l'option "se souvenir de moi" si elle existe pour voir comment elle fonctionne. Si elle existe et peut être vulnérable, utilisez toujours le cookie de se souvenir de moi sans aucun autre cookie.
Vérifiez si le cookie précédent fonctionne même après avoir changé le mot de passe.
Si le cookie reste le même (ou presque) lorsque vous vous connectez, cela signifie probablement que le cookie est lié à un champ de votre compte (probablement le nom d'utilisateur). Ensuite, vous pouvez :
Essayez de créer beaucoup de comptes avec des noms d'utilisateur très similaires et essayez de deviner comment fonctionne l'algorithme.
Essayez de forcer le nom d'utilisateur. Si le cookie ne sauvegarde que comme méthode d'authentification pour votre nom d'utilisateur, vous pouvez créer un compte avec le nom d'utilisateur "Bmin" et forcer chaque bit de votre cookie car l'un des cookies que vous essayerez appartiendra à "admin".
Essayez l'Oracle de Remplissage (vous pouvez décrypter le contenu du cookie). Utilisez padbuster.
Oracle de Remplissage - Exemples de Padbuster
Padbuster fera plusieurs tentatives et vous demandera quelle condition est l'erreur (celle qui n'est pas valide).
Ensuite, il commencera à décrypter le cookie (cela peut prendre plusieurs minutes).
Si l'attaque a réussi, vous pourriez essayer de crypter une chaîne de votre choix. Par exemple, si vous vouliez crypter user=administrateur
Cet exemple vous donnera le cookie correctement chiffré et encodé avec la chaîne user=administrator à l'intérieur.
CBC-MAC
Peut-être qu'un cookie pourrait avoir une certaine valeur et être signé en utilisant le CBC. Ensuite, l'intégrité de la valeur est la signature créée en utilisant le CBC avec la même valeur. Comme il est recommandé d'utiliser un vecteur nul comme IV, ce type de vérification d'intégrité pourrait être vulnérable.
L'attaque
Obtenir la signature du nom d'utilisateur administ = t
Obtenir la signature du nom d'utilisateur rator\x00\x00\x00 XOR t = t'
Définir dans le cookie la valeur administrator+t' (t' sera une signature valide de (rator\x00\x00\x00 XOR t) XOR t = rator\x00\x00\x00
ECB
Si le cookie est chiffré en utilisant ECB, il pourrait être vulnérable. Lorsque vous vous connectez, le cookie que vous recevez doit être toujours le même.
Comment détecter et attaquer :
Créez 2 utilisateurs avec des données presque identiques (nom d'utilisateur, mot de passe, e-mail, etc.) et essayez de découvrir un certain motif à l'intérieur du cookie donné.
Créez un utilisateur appelé par exemple "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" et vérifiez s'il y a un motif dans le cookie (comme ECB chiffre avec la même clé chaque bloc, les mêmes octets chiffrés pourraient apparaître si le nom d'utilisateur est chiffré).
Il devrait y avoir un motif (avec la taille d'un bloc utilisé). Ainsi, en sachant comment un tas de "a" est chiffré, vous pouvez créer un nom d'utilisateur : "a"*(taille du bloc)+"admin". Ensuite, vous pourriez supprimer le motif chiffré d'un bloc de "a" du cookie. Et vous aurez le cookie de l'utilisateur "admin".
Try Hard Security Group