DOM XSS in jQuery selector sink using a hashchange event
Laboratorio de Portswigger sobre XSS
Certificaciones
- eWPT
- eWPTXv2
- OSWE
- BSCP
Descripción
Este laboratorio contiene una vulnerabilidad de XSS basado en DOM en la página de inicio. Utiliza la función $( ) de jQuery para desplazarse automáticamente a una publicación, cuyo título se pasa a través de la propiedad location.hash. Para resolver este laboratorio, debemos entregar un exploit a la víctima que llame a la función print() en su navegador
Guía de XSS
Antes de completar este laboratorio es recomendable leerse esta guía de XSS https://justice-reaper.github.io/posts/XSS-Guide/
Resolución
Al acceder a la web nos sale esto
Si inspeccionamos el código fuente vemos que se usa la librería jquery y también se usa hashchange https://developer.mozilla.org/es/docs/Web/API/Window/hashchange_event
Lo que hace este script es que al poner #nombreArtículo, la web scrollea hasta ese artículo https://0ac9000c03e41501911af9af00fe003d.web-security-academy.net/#Festivals
La consola de Firefox arroja más información que la de Chrome, por lo tanto es la que voy a usar. Si accedemos a https://0aed00c104135b718554db5c00a10038.web-security-academy.net/#The%20Cool%20Parent y en el inspector de Firefox nos abrimos la consola, podemos ver el funcionamiento del script. Esta instrucción window.location.hash.slice(1) obtiene el texto que hay después de el #
Si accedemos a https://0aed00c104135b718554db5c00a10038.web-security-academy.net/#The%20Cool%20Parent vemos que el decodeURIComponent lo que hace es urldecodear este parámetro de la url que hay después del #
Vemos que si existe nos devuelve un objeto de longitud 1
Si accedemos a https://0aed00c104135b718554db5c00a10038.web-security-academy.net/#NoExiste vemos que nos sigue devolviendo un objeto, aunque la longitud sea 0, debido a que no existe ese apartado en la web
El objeto existe aunque su longitud sea 0, esto es en parte, es la vulnerabilidad. Tal como está ahora solo devolverá un error, lo cual no es demasiado grave
Si introducimos etiquetas en la cadena, vemos que si se crea un objeto el cual tiene longitud 1, esta es la segunda parte de la vulnerabilidad
Para ver esto debemos ampliar el element h1, no puede verse el elemento del DOM <h1> porque aún no está asociado a nada. Como se puede ver, su parentElement es nulo. Para que nuestro elemento <h1> sea visible en la página, necesitamos asociar el elemento a un parentElement
Para adjuntar el <h1> a un parentElement debemos localizar un donde queremos insertarlo primero, para ello nos abrimos el código fuente de la página y vemos un div con el id academyLabHeader
El parentElement va a ser el div cuyo id es academyLabHeader y a ese div le adjuntamos como elemento hijo el objeto <h1>
Si ha funcionado todo correctamente veremos en la parte superior izquierda un <h1>hola</h1> el cual está siendo interpretado
Como está siendo interpretado podemos probar con una etiqueta img a ver si podemos ejecutar código javascript, para ello accedemos a https://0a3f000603002aa5819f20e900ac00bc.web-security-academy.net/#<img src=noExiste onerror="alert(4)">
Aún no hemos completado el laboratorio, para ello debemos dirigirnos al exploit server, insertar este payload en el body y pulsar sobre Store. Lo que estamos haciendo aquí es crear un iframe que almacene la web en su interior, si se carga correctamente llamamos al evento onload que además del src del iframe intentará cargar la imagen, la cual al no existir provocará un error
1
<iframe src="https://0a200078039f286d827179f200ba000a.web-security-academy.net/#" onload="this.src+='<img src=x onerror=print()>'"></iframe>
De esta forma si accedemos a https://exploit-0a4400240313282a82a2786601b00027.exploit-server.net/exploit o pulsamos sobre View exploit nos saldrá un print y un iframe. Para completar el laboratorio debemos pulsar sobre Deliver exploit to victim















