3.8 KiB
Bloqueando la página principal para robar postmessage
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- ¿Trabajas en una empresa de ciberseguridad? ¿Quieres ver tu empresa anunciada en HackTricks? ¿O quieres tener acceso a la última versión de PEASS o descargar HackTricks en PDF? ¡Consulta los PLANES DE SUSCRIPCIÓN!
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Obtén el swag oficial de PEASS y HackTricks
- Únete al 💬 grupo de Discord o al grupo de telegram o sígueme en Twitter 🐦@carlospolopm.
- Comparte tus trucos de hacking enviando PR al repositorio de hacktricks y al repositorio de hacktricks-cloud.
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
.