hacktricks/pentesting-web/hacking-with-cookies/README.md

20 KiB

Hacking de Cookies

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Encuentra las vulnerabilidades que más importan para que puedas solucionarlas más rápido. Intruder rastrea tu superficie de ataque, realiza escaneos proactivos de amenazas, encuentra problemas en toda tu pila tecnológica, desde APIs hasta aplicaciones web y sistemas en la nube. Pruébalo gratis hoy.

{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}


Atributos de las Cookies

Expires y Max-Age

  • Expires establece una fecha de caducidad para cuando se elimina una cookie.
  • Max-age establece el tiempo en segundos para cuando se eliminará una cookie (utiliza esto, ya no estamos en 2009).

Dominio

El atributo Domain especifica qué hosts pueden recibir una cookie. Si no se especifica, el atributo se establece por defecto en el mismo host que estableció la cookie, excluyendo subdominios. Si se especifica Domain, entonces siempre se incluyen los subdominios. Por lo tanto, especificar Domain es menos restrictivo que omitirlo. Sin embargo, puede ser útil cuando los subdominios necesitan compartir información sobre un usuario.

Por ejemplo, si estableces Domain=mozilla.org, las cookies están disponibles en subdominios como developer.mozilla.org. Pero si no lo haces, la cookie no se enviará a los subdominios.

Si un subdominio sub.example.com establece una cookie con el atributo domain de .example.com, se enviará en las solicitudes al dominio padre.

Ruta

El atributo Path indica una ruta URL que debe existir en la URL solicitada para enviar la cabecera Cookie. El carácter %x2F ("/") se considera un separador de directorios, y también se consideran las subcarpetas.

Orden

Cuando 2 cookies tienen el mismo nombre, se envía la que:

  • Tiene la ruta más larga que coincide con la ruta de la URL.
  • Es la más reciente si ambas tienen la misma ruta.

SameSite

Esto indicará al navegador si la cookie puede ser enviada desde otros dominios. Tiene 3 valores posibles:

  • Strict: La cookie no se enviará junto con una solicitud de sitios web de terceros.
  • Lax: La cookie se enviará junto con la solicitud GET iniciada por sitios web de terceros.
  • None: La cookie se envía desde cualquier dominio de terceros.
Tipo de Solicitud Código de Ejemplo Cookies Enviadas Cuando
Enlace <a href="..."></a> No establecido*, Lax, None
Pre-renderizado <link rel="prerender" href=".."/> No establecido*, Lax, None
Formulario GET <form method="GET" action="..."> No establecido*, Lax, None
Formulario POST <form method="POST" action="..."> No establecido*, None
iframe <iframe src="..."></iframe> No establecido*, None
AJAX $.get("...") No establecido*, None
Imagen <img src="..."> No establecido*, None

Tabla de Invicti y ligeramente modificada.
Una cookie con el atributo SameSite mitigará los ataques CSRF donde se necesita una sesión iniciada.

*Ten en cuenta que a partir de Chrome80 (feb/2019), el comportamiento predeterminado de una cookie sin un atributo samesite será laxo (https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/).
Ten en cuenta que temporalmente, después de aplicar este cambio, las cookies sin una política SameSite en Chrome se tratarán como None durante los primeros 2 minutos y luego como Lax para las solicitudes POST de nivel superior entre sitios.

Bandera de las Cookies

HttpOnly

Esto evita que el cliente acceda a la cookie (por ejemplo, a través de Javascript: document.cookie)

Bypasses

  • Si la página está enviando las cookies como respuesta de una solicitud (por ejemplo, en una página de PHPinfo), es posible abusar de XSS para enviar una solicitud a esta página y robar las cookies de la respuesta (ver un ejemplo en https://hackcommander.github.io/pentesting-article-1/)
  • Esto se puede evitar con solicitudes TRACE HTTP como respuesta del servidor (si este método HTTP está disponible), se reflejarán las cookies enviadas. Esta técnica se llama Cross-Site Tracking.
  • Los navegadores modernos evitan esta técnica al no permitir el envío de una solicitud TRACE desde JS. Sin embargo, se han encontrado algunas formas de evadir 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 de día cero de los navegadores.
  • Es posible sobrescribir cookies HttpOnly realizando un ataque de desbordamiento de Cookie Jar:

{% content-ref url="cookie-jar-overflow.md" %} cookie-jar-overflow.md {% endcontent-ref %}

Secure

La solicitud solo enviará la cookie en una solicitud HTTP si la solicitud se transmite a través de un canal seguro (normalmente HTTPS).

Prefijos de las Cookies

Prefijo __Secure-: debe establecerse con la bandera secure desde una página segura (HTTPS).

Prefijo __Host-: debe establecerse con la bandera secure, debe ser desde una página segura (HTTPS), no debe tener un dominio especificado (y por lo tanto, no se envían a subdominios) y la ruta debe ser /.

Las cookies con prefijo __Host- no se pueden enviar a superdominios (cookies de subdominios a dominios) o subdominios (cookies de dominios a subdominios), por lo que si desea aislar las cookies de su aplicación, no es mala idea agregar el prefijo __Host- a todo.

Ataques a las Cookies

Si encuentra algún tipo de cookie personalizada que contiene datos sensibles (ID de sesión, nombre de usuario, correos electrónicos, etc.), definitivamente debería intentar explotarla.

Si la cookie utiliza alguna codificación base (como Base64) o similar, es posible que pueda decodificarla, cambiar el contenido e usurpar usuarios arbitrarios.

Secuestro de sesión

Robar una cookie y usarla para hacerse pasar por el usuario dentro de una aplicación.

Fijación de sesión

El atacante obtiene una cookie de una página web y envía un enlace a la víctima para que inicie sesión utilizando la misma cookie. Si la cookie no cambia cuando un usuario inicia sesión, esto podría ser útil porque el atacante podría hacerse pasar por el usuario a través de una cookie.

Si encuentra un XSS en un subdominio o controla un subdominio, lea:

{% content-ref url="cookie-tossing.md" %} cookie-tossing.md {% endcontent-ref %}

Donación de sesión

El atacante envía su propia sesión a la víctima. La víctima verá que ya ha iniciado sesión y supondrá que está dentro de su cuenta, pero las acciones se realizarán dentro de la cuenta del atacante.

Si encuentra un XSS en un subdominio o controla un subdominio, lea:

{% content-ref url="cookie-tossing.md" %} cookie-tossing.md {% endcontent-ref %}

Haga clic en el enlace anterior para acceder a una página que explica posibles fallas en JWT.

Los navegadores permiten una cookie con un nombre vacío.

document.cookie = "a=v1"
document.cookie = "=test value;" // empty name
document.cookie = "b=v2"

Esto resulta en el encabezado de la cookie enviada:

a=v1; test value; b=v2;

Más interesante aún, si tienes un vector que de alguna manera te permite establecer la cookie vacía, puedes controlar cualquier otra cookie:

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

setCookie("", "a=b"); // this sets the empty cookie to a=b

Aunque internamente en el navegador esto se establece como una cookie sin nombre, resultará en el encabezado de la cookie enviada:

a=b;

Significado, cada servidor web lo interpretará como la cookie a establecida con el valor b.

Si hay un punto de código de sustituto Unicode en una cookie establecida, document.cookie se corromperá permanentemente y devolverá una cadena vacía.

document.cookie
// "a=b;"
document.cookie = "\ud800=meep";
document.cookie
// ""

Contrabando de Cookies

Varios servidores web, incluyendo los servidores Java Jetty, TomCat, Undertow y el framework web Python Zope, así como los servidores/frameworks web Python cherrypy, web.py, aiohttp server, bottle y webob, se encontraron analizando incorrectamente las cadenas de cookies debido al soporte residual para RFC2965, un mecanismo de citas de cookies desactualizado que utiliza RFC2616 para la definición de una cadena entre comillas.

Específicamente, estos servidores continúan leyendo una cadena de cookies cuando encuentran un valor de cookie entre comillas dobles (dquoted), incluso si se encuentra un punto y coma. Esto es problemático porque los puntos y comas deben separar los pares clave-valor en la cadena de cookies.

Por ejemplo, si un navegador envía tres cookies, RENDER_TEXT, JSESSIONID, y ASDF:

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

Estos servidores los interpretan como parte de un único valor de cookie en lugar de tres cookies separadas.

Esto conlleva un riesgo de seguridad: si un atacante obtiene acceso de scripting entre sitios (XSS), puede utilizar este error para filtrar cookies sensibles como las cookies HttpOnly.

Inyección de Cookies

Se ha descubierto que muchos servidores web, incluyendo Undertow de Java, Zope de Python y aquellos que utilizan http.cookie.SimpleCookie y http.cookie.BaseCookie de la biblioteca estándar de Python, analizan incorrectamente las cookies, utilizando delimitadores incorrectos para comenzar el siguiente par de nombre/valor de la cookie. Esto permite a un atacante falsificar múltiples cookies mientras solo controla un valor de cookie.

En el caso de Undertow, comienza a analizar la siguiente cookie inmediatamente después del final de un valor de cookie entre comillas, sin esperar un punto y coma:

LANGUAGE="en-us" CSRF_TOKEN="SPOOFED_VALUE"

Zope comienza a analizar la siguiente cookie en una coma:

LANGUAGE=en-us,CSRF_TOKEN=SPOOFED_VALUE

Y SimpleCookie y BaseCookie de Python comienzan inmediatamente a analizar la siguiente cookie en un carácter espacio:

LANGUAGE=en-us CSRF_TOKEN=SPOOFED_VALUE

Como resultado, servidores como cherrypy, web.py, servidor aiohttp, bottle y webob (Pyramid, TurboGears) son vulnerables a este tipo de ataque.

Este problema presenta importantes implicaciones de seguridad. Por ejemplo, si una aplicación web utiliza protección CSRF basada en cookies, un atacante puede inyectar una cookie falsificada de CSRF-token para evadir esta protección. Además, el último nombre duplicado de cookie en los paquetes http.cookie de Python anula a cualquier cookie anterior, lo que hace que este tipo de ataque sea especialmente fácil.

Además, el falsificado de cookies __Secure- y __Host- puede ser abusado en un contexto inseguro. Además, en una configuración donde las cookies se pasan a un servidor backend, la inyección de cookies podría llevar a bypasses de autorización si el servidor backend es susceptible a falsificaciones pero el servidor frontend no lo es.

Comprobaciones adicionales de cookies vulnerables

Comprobaciones básicas

  • La cookie es la misma cada vez que te logueas.
  • Cierra sesión e intenta usar la misma cookie.
  • Intenta iniciar sesión con 2 dispositivos (o navegadores) en la misma cuenta usando la misma cookie.
  • Verifica si la cookie tiene alguna información y trata de modificarla.
  • Intenta crear varias cuentas con nombres de usuario casi iguales y verifica si puedes ver similitudes.
  • Verifica si existe la opción de "recordarme" para ver cómo funciona. Si existe y podría ser vulnerable, siempre utiliza la cookie de recordarme sin ninguna otra cookie.
  • Verifica si la cookie anterior sigue funcionando incluso después de cambiar la contraseña.

Ataques avanzados a las cookies

Si la cookie permanece igual (o casi igual) cuando inicias sesión, esto probablemente significa que la cookie está relacionada con algún campo de tu cuenta (probablemente el nombre de usuario). Entonces puedes:

  • Intenta crear muchas cuentas con nombres de usuario muy similares e intenta adivinar cómo funciona el algoritmo.
  • Intenta atacar por fuerza bruta el nombre de usuario. Si la cookie solo se guarda como método de autenticación para tu nombre de usuario, entonces puedes crear una cuenta con el nombre de usuario "Bmin" y atacar por fuerza bruta cada bit de tu cookie porque una de las cookies que intentarás será la que pertenece a "admin".
  • Prueba el Padding Oracle (puedes descifrar el contenido de la cookie). Usa padbuster.

Padding Oracle - Ejemplos de Padbuster

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

Luego comenzará a descifrar la cookie (esto puede llevar varios minutos).

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

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

Esta ejecución te dará la cookie correctamente encriptada y codificada con la cadena user=administrator en su interior.

CBC-MAC

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

El ataque

  1. Obtén la firma del nombre de usuario administ = t
  2. Obtén la firma del nombre de usuario 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á encriptada usando ECB, podría ser vulnerable.
Cuando inicias sesión, la cookie que recibes siempre debe ser la misma.

Cómo detectar y atacar:

Crea 2 usuarios con datos casi idénticos (nombre de usuario, contraseña, correo electrónico, etc.) e intenta descubrir algún patrón dentro de la cookie proporcionada.

Crea un usuario llamado, por ejemplo, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" y verifica si hay algún patrón en la cookie (como ECB encripta con la misma clave cada bloque, los mismos bytes encriptados podrían aparecer si el nombre de usuario está encriptado).

Debería haber un patrón (con el tamaño de un bloque utilizado). Entonces, sabiendo cómo se encriptan un montón de "a", puedes crear un nombre de usuario: "a"*(tamaño del bloque)+"admin". Luego, puedes eliminar el patrón encriptado de un bloque de "a" de la cookie. Y tendrás la cookie del nombre de usuario "admin".

Referencias

Encuentra las vulnerabilidades que más importan para que puedas solucionarlas más rápido. Intruder rastrea tu superficie de ataque, realiza escaneos de amenazas proactivas, encuentra problemas en toda tu pila tecnológica, desde APIs hasta aplicaciones web y sistemas en la nube. Pruébalo gratis hoy.

{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥