SameSite Lax bypass via method override
Laboratorio de Portswigger sobre CSRF
Certificaciones
- eWPT
- eWPTXv2
- OSWE
- BSCP
Descripción
Para resolver
este laboratorio
, debemos explotar la vulnerabilidad de CSRF
en la función de cambio de correo electrónico
. Necesitaremos usar el Exploit server
que nos proporcionan para hostear
nuestro ataque
. Podemos iniciar sesión
en nuestra propia cuenta
utilizando las credenciales wiener:peter
. Las restricciones predeterminadas de SameSite
difieren entre navegadores
. Como la víctima
usa Chrome
, se recomienda usar Chrome
o Chromium
para probar el exploit
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
Pulsamos sobre My account
y nos logueamos
con las credenciales wiener:peter
Vemos que hay un botón
para cambiar
el email
Si nos dirigimos a la extensión Logger ++
de Burpsuite
vemos que al loguearnos
se nos setea
una cookie
pero no tiene el atributo SameSite
Si nos abrimos
las herramientas de desarrollador
vemos que la cookie
no tiene ese atributo
, por lo tanto si estamos usando Chrome
, se aplicarán las restricciones Lax SameSite por defecto
. Las restricciones SameSite=Lax
significan que los navegadores
enviarán la cookie
en solicitudes entre sitios web
, pero solo si la solicitud utiliza el método GET
y si la solicitud es el resultado de una navegación de nivel superior, es decir, que requiere interacción por parte del usuario
, como hacer click en un enlace
En la práctica, los servidores no siempre son estrictos con respecto a si reciben una solicitud GET o POST en un determinado endpoint
, incluso en aquellos que esperan
el envío
de un formulario
. Si además utilizan restricciones Lax
para sus cookies de sesión
, ya sea de forma explícita o debido al comportamiento predeterminado del navegador
, aún podríamos realizar un ataque CSRF
provocando que el navegador
de la víctima emita una solicitud GET
. Siempre que la solicitud implique una navegación de nivel superior
. Por ejemplo:
1
<script> document.location = 'https://vulnerable-website.com/account/transfer-payment?recipient=hacker&amount=1000000'; </script>
Incluso si no se permite una solicitud GET
ordinaria, algunos frameworks
proporcionan formas de sobrescribir
el método
especificado. Por ejemplo, Symfony
admite el parámetro _method
en formularios
, el cual tiene prioridad sobre el método
normal para propósitos de enrutamiento
. Otros frameworks
admiten una variedad de parámetros
similares para sobrescribir
el método
de la solicitud
1
2
3
4
5
<form action="https://vulnerable-website.com/account/transfer-payment" method="POST">
<input type="hidden" name="_method" value="GET">
<input type="hidden" name="recipient" value="hacker">
<input type="hidden" name="amount" value="1000000">
</form>
Si inspeccionamos
la forma
en la que se envía
el formulario
para cambiar el correo electrónico
, vemos esto
Anteriormente hemos visto que se está utilizando SameSite
con el valor por defecto Lax
, por lo tanto, si conseguimos hacer una petición GET
que sea de navegación superior
, podríamos lograr llevar a cabo un ataque CSRF
. Si capturamos la petición
para cambiar nuestro email
, vemos que se transmite por POST
Si pulsamos click derecho > Change request method
convertimos la petición
a GET
, sin embargo, nos dice que no acepta este método
Como hemos dicho antes algunos frameworks
proporcionan formas de sobrescribir
el método
especificado. Con Symfony
tenemos el método _method
para sobrescribir
el método
de la petición
, por lo tanto, si hacemos una petición
por GET
a /my-account/change-email?email=test%40gmail.com&_method=POST
y sobrescribimos
el método
con _method
la petición
es exitosa
Podemos crear payloads
si tenemos Burpsuite Professional
pulsando click derecho > Engagements tools > Generate CSRF PoC
Se nos genera este payload
, aunque es funcional, en la mayoría de ocasiones vamos a tener que retocarlo
un poco para mejorar
su desempeño
En mi caso prefiero hacer los payloads
de forma manual
1
2
3
4
5
6
7
8
9
10
11
<html>
<body>
<form action="https://0a1300120392b3a2822110240029009e.web-security-academy.net/my-account/change-email" method="GET">
<input type="hidden" name="_method" value="POST">
<input type="hidden" name="email" value="pwned@gmail.com">
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
Otra alternativa
sería usar este otro payload
1
2
3
4
5
6
7
<html>
<body>
<script>
document.location = 'https://0a1300120392b3a2822110240029009e.web-security-academy.net/my-account/change-email?email=pwned@gmail.com&_method=POST';
</script>
</body>
</html>
Nos abrimos
el Exploit server
y pegamos cualquiera de los payloads
anteriores
Si pulsamos en View exploit
vemos como nos cambia
el email
. Independientemente
del payload
usado, 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