Resultado de imagen de intigriti bug bounty

El pasado fin de semana se realizó por parte de Intigriti un curioso CTF sobre Cross-site Scripting cuya resolución presentaremos en este blog a continuación

Le sobran presentaciones a la infección de código ejecutado por el cliente, o XSS pero una referencia a la Wikipedia nunca viene de más, ¿no?
Puestos a dejar documentacióntambién os dejo un vídeo de LiveOverflow sobre el mismo tema de una lista de reducción muy interesante.

Entonces, el reto 😀

Se nos presenta de la siguiente forma, un enlace, que está enviándole un Base64.

Okey, y vemos el código

La primera parte el script pone un valor por defecto al parámetro que recibe por la URL, ese Base64 corresponde con el archivo de la imagen que se nos muestra en la pagina.

Por otra parte el código hace una GET request XMLHttpRequest

Cuando se ejecute la petición y si esta es ejecutada correctamente, es decir , que el código de respuesta sea 200 sacará por pantalla el código que nos muestra la imagen tal y como lo vemos en la web del reto.

Aquí tenemos por tanto el primer «detalle» a tener en cuenta en el CTF: El parámetro que reciba tiene que ser una dirección de un servidor web al que le pueda hacer el XMLHttpRequest.

Ojito aquí, pillaros un VPS de prueba o lo que sea pero tener en cuenta que tenéis que tener CORS activado. Si no tenéis forma de conseguir uno, recread el codigo en vuestra máquina local.

Dentro de la etiqueta del enlace que forma la imagen, tenemos el campo alt donde se llama a la función atob aplicado al parámetro que revise por la URL.

Si solo tenemos en cuenta el código que se muestra dentro del document.write el XSS se hace solo. Hay que enviarle como parametro el cierre de la sintaxis HTML del link e inyectar nuestro código, en Base64, cosa que ya nos temíamos viendo como se presentaba el CTF, para que pase la función atob. Podemos hacenos el ejemplo en local y ver que funciona 😀

Pero claro, este contexto se dará solo y cuando se establezca la request anteriormente mencionada.
Como vemos en el mismo código, la dirección a la que dirige la petición es el mismo parámetro que le enviamos.
Por tanto. Tendremos que enviarle un parámetro que, al mismo tiempo, de un 200 code en la XMLHttpRequest y tenga adjunto el Base64 con el cierre de la etiqueta y el código inyectado. Con todo esto no olvidarse de que pasamos por la función atob. Y que esta de el resultado correcto es requisito para que lleguemos a la posibilidad de solucionar el reto.

Por partes.

Como hemos mencionado antes si cuentas con un VPS puedes instalar Apache (o cualquier servicio web, se que os gusta mucho nginx) y activar CORS request, será este donde enviaremos nuestra request.

Prueba inicialmente simplemente a pasar por parametro la dirección tal cual. El propio debuger del navegador os permitirá ver que esta request se está resolviendo
correctamente.

 

También podremos fijarnos en que la consola del browser nos esta mostrando un error en la funcion atob. Por tanto aunque intentemos meterle ahí el codigo javascript, junto a la dirección, este no funcionará.

Los caracteres que nos estan dando problemas en la funcion atob , son los «.» de la direccion y las «/» del «http://…».

Para evitar usar los puntos que conformas la dirección IP es sencillo. Estamos acostumbrados a ver las IPs representada por el valor numérico de sus quatro octetos de bits. Pero esta se le pueden mas otras representaciones como la decimal, o incluso la binaria.

Usado un conversor de IP de su valor «dot-octet» en su valor decimal, y hemos comprobado que realiza correctamente la request pasando de forma satisfactoria la funcion atob.

Por otra parte para eviatr usar el «:» del «http://…», en html/js cuando estamos haciendo una petición a un recurso web mediante HTTP, este puede ser llamado directamente con los caracteres «//» siendo:

http://paginaweb.es => //paginaweb.es

De esta forma usando la estructura //<VALOR NUMÉRICO IP SERVIDOR>, esta NO dará el error en la función atob.

A continuación tenemos que emplear la misma idea para la infección
Como hemos visto al inicio sobra con cerrar la etiqueta del enlace que engloba a la imagen y empezar a inyectar código a partir de ahí….«><script>alert(1)</script>

Seguimos con las mismas condiciones de antes, que por una parte la request se resuelva correctamente y que por otra que la funcion atob resuleva correctamente el parámetro que recive por la URI

Para la primera es sencillo, si ya tenemos preparado nuestro servidor web, crearemos en el mismo un archivo con el mismo nombre del payload que le pasaremos.

Usando el mencionado anteriormente y previa codificación en Base64 para hacer la prueba tenemos algo como:

«><script>alert(1)</script> ==> BASE64 ENCODED ==> Ij48c2NyaXB0PmFsZXJ0KDEpPC9zY3JpcHQ+

PAYLOAD : //<VALOR NUMÉRICO IP SERVIDOR>/Ij48c2NyaXB0PmFsZXJ0KDEpPC9zY3JpcHQ+

Sin embargo vamos que volvemos a tener problemas con la funcion atob.
El carácter de la barra «/» es un poco especialito en cuanto a la codificación en Base64 y dependiendo de como sea la integridad de la entrada a codificar esta funcionará correctamente y en correspondencia a nuestro reto o no.

Para este CTF mostramos un par de casos:

El concepto fundamental es que la función atob si que interpretará las barras bien, siempre que entre estas haya un numero par de caracteres ya que en base 64 no se permite un solo carácter codificado restante en el último cuádruple o un relleno de 3 caracteres

El navegador interpretará si recibe muchas «/» en una uri como el mismo directorio (el directorio ‘.’) si le pasamos 4 barras, por ejemplo, algo tipo:

//<VALOR NUMERICO IP SERVIDOR>////Ij48c2NyaXB0PmFsZXJ0KDEpPC9zY3JpcHQ+

Podemos ver en el ejemplo del video como funciona correctamente.

Otro metodo, podria ser poner dos caracteres normales entre las barras, ojo! tendremos que crear un directorio con el nombre de esos caracteres para que funcione correctamente.

Si nada te ha funcionado, quizas es porque estas usando el otro puerto web.

Y con esto poco mas, un reto chulo, para aprender y poner en practica detalles de Hacking Web.  Muchas gracias a la gente del blog y a Ainschtain por ayudarme con el reto ^.^

Un saludo y hasta la próxima.

@j0moz4love is in the net

¿Me ayudas a compartirlo?
Última modificación: 9 junio 2019

Autor

Comentarios

Comenta o responde a los comentarios

Tu dirección de correo no será publicada.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.