hacktricks/pentesting-web/postmessage-vulnerabilities/blocking-main-page-to-steal-postmessage.md
2023-06-03 13:10:46 +00:00

3.8 KiB

Bloquer la page principale pour voler des postmessages

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

Gagner des RC avec des iframes

Selon ce writeup de Terjanq, les documents blob créés à partir d'origines nulles sont isolés pour des raisons de sécurité, ce qui signifie que si vous maintenez occupée la page principale, la page iframe sera exécutée.

En gros, dans ce défi, une iframe isolée est exécutée et juste après qu'elle soit chargée, la page parent va envoyer un message post avec le flag.
Cependant, cette communication postmessage est vulnérable à XSS (l'iframe peut exécuter du code JS).

Par conséquent, l'objectif de l'attaquant est de laisser le parent créer l'iframe, mais avant de laisser la page parent envoyer les données sensibles (flag) le garder occupé et envoyer la charge utile à l'iframe. Pendant que le parent est occupé, l'iframe exécute la charge utile qui sera du JS qui écoutera le message postmessage du parent et divulguera le flag.
Enfin, l'iframe a exécuté la charge utile et la page parent cesse d'être occupée, donc elle envoie le flag et la charge utile le divulgue.

Mais comment pourriez-vous faire en sorte que le parent soit occupé juste après avoir généré l'iframe et juste pendant qu'il attend que l'iframe soit prête à envoyer les données sensibles ? Fondamentalement, vous devez trouver une action asynchrone que vous pourriez faire exécuter au parent. Par exemple, dans ce défi, le parent écoutait les postmessages comme ceci :

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

Il était possible d'envoyer un grand entier dans un postmessage qui sera converti en chaîne de caractères dans cette comparaison, ce qui prendra du temps:

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

Et afin d'être précis et d'envoyer ce postmessage juste après que l'iframe soit créé mais avant qu'il ne soit prêt à recevoir les données du parent, vous devrez jouer avec les millisecondes d'un setTimeout.