# Bypassing SOP with Iframes - 2 {{#include ../../banners/hacktricks-training.md}} ## Iframes in SOP-2 Στη [**λύση**](https://github.com/project-sekai-ctf/sekaictf-2022/tree/main/web/obligatory-calc/solution) για αυτήν την [**πρόκληση**](https://github.com/project-sekai-ctf/sekaictf-2022/tree/main/web/obligatory-calc)**,** [**@Strellic\_**](https://twitter.com/Strellic_) προτείνει μια παρόμοια μέθοδο με την προηγούμενη ενότητα. Ας το ελέγξουμε. Σε αυτήν την πρόκληση, ο επιτιθέμενος πρέπει να **bypass** αυτό: ```javascript 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`** με **``** (σημειώστε ότι το Sanitizer API -[εδώ](https://wicg.github.io/sanitizer-api/index.html#dom-clobbering)- δεν είναι ρυθμισμένο για να προστατεύει από επιθέσεις DOM clobbering στην προεπιλεγμένη του κατάσταση). - Επομένως, μπορείτε να καταστρέψετε το **`document.getElementById("calc")`** με **`
`**. Τότε, το **`window.calc`** θα είναι **`undefined`**. - Τώρα, χρειαζόμαστε το **`e.source`** να είναι **`undefined`** ή **`null`** (επειδή χρησιμοποιείται το `==` αντί για το `===`, **`null == undefined`** είναι **`True`**). Το να το αποκτήσετε είναι "εύκολο". Αν δημιουργήσετε ένα **iframe** και **στείλετε** ένα **postMessage** από αυτό και αμέσως **αφαιρέσετε** το iframe, το **`e.origin`** θα είναι **`null`**. Ελέγξτε τον παρακάτω κώδικα ```javascript 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`** σε σελίδες με προέλευση **`null`** προκαλεί ένα **σφάλμα**. Αυτό θα κάνει την τιμή του **`window.token`** να είναι **`undefined`**. Η τελική λύση από [**@terjanq**](https://twitter.com/terjanq) είναι η [**εξής**](https://gist.github.com/terjanq/0bc49a8ef52b0e896fca1ceb6ca6b00e#file-calc-html): ```html ``` {{#include ../../banners/hacktricks-training.md}}