CSRF where token is tied to non-session cookie
Laboratorio de Portswigger sobre CSRF
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