hacktricks/pentesting-web/postmessage-vulnerabilities/blocking-main-page-to-steal-postmessage.md
carlospolop 63bd9641c0 f
2023-06-05 20:33:24 +02:00

3.8 KiB

Bloqueando la página principal para robar postmessage

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Ganando RCs con iframes

Según este writeup de Terjanq, los documentos de blob creados desde orígenes nulos están aislados por motivos de seguridad, lo que significa que si mantienes ocupada la página principal, se ejecutará la página iframe.

Básicamente, en ese desafío se ejecuta un iframe aislado y justo después de que se cargue, la página principal va a enviar un mensaje post con la bandera.
Sin embargo, esa comunicación postmessage es vulnerable a XSS (el iframe puede ejecutar código JS).

Por lo tanto, el objetivo del atacante es permitir que el padre cree el iframe, pero antes de permitir que la página principal envíe los datos sensibles (bandera) mantenerla ocupada y enviar el payload al iframe. Mientras el padre está ocupado, el iframe ejecuta el payload que será algún JS que escuchará el mensaje postmessage del padre y filtrará la bandera.
Finalmente, el iframe ha ejecutado el payload y la página principal deja de estar ocupada, por lo que envía la bandera y el payload la filtra.

Pero, ¿cómo podrías hacer que el padre esté ocupado justo después de generar el iframe y solo mientras espera a que el iframe esté listo para enviar los datos sensibles? Básicamente, necesitas encontrar una acción asíncrona que puedas hacer que el padre ejecute. Por ejemplo, en ese desafío, el padre estaba escuchando los postmessages como este:

window.addEventListener('message', (e) => {
    if (e.data == 'blob loaded') {
        $("#previewModal").modal();
    }
});

Así que era posible enviar un entero grande en un postmessage que se convertiría en una cadena en esa comparación, lo que llevaría algún tiempo:

const buffer = new Uint8Array(1e7);
win?.postMessage(buffer, '*', [buffer.buffer]);

Y para ser precisos y enviar ese postmessage justo después de que se cree el iframe pero antes de que esté listo para recibir los datos del padre, necesitarás jugar con los milisegundos de un setTimeout.