PostMessage Vulnerabilities
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
PostMessage χρησιμοποιεί την παρακάτω λειτουργία για να στείλει ένα μήνυμα:
Σημειώστε ότι το targetOrigin μπορεί να είναι ένα '*' ή μια διεύθυνση URL όπως https://company.com. Στο δεύτερο σενάριο, το μήνυμα μπορεί να σταλεί μόνο σε αυτή τη διεύθυνση (ακόμα κι αν η προέλευση του αντικειμένου παραθύρου είναι διαφορετική). Εάν χρησιμοποιηθεί το wildcard, τα μηνύματα θα μπορούσαν να σταλούν σε οποιαδήποτε διεύθυνση, και θα σταλούν στην προέλευση του αντικειμένου Window.
Όπως εξηγείται σε αυτή την αναφορά, αν βρείτε μια σελίδα που μπορεί να iframed (χωρίς προστασία X-Frame-Header
) και που στέλνει ευαίσθητο μήνυμα μέσω postMessage χρησιμοποιώντας ένα wildcard (*), μπορείτε να τροποποιήσετε την προέλευση του iframe και να leak το ευαίσθητο μήνυμα σε μια διεύθυνση που ελέγχετε.
Σημειώστε ότι αν η σελίδα μπορεί να iframed αλλά το targetOrigin είναι ρυθμισμένο σε μια διεύθυνση URL και όχι σε wildcard, αυτό το κόλπο δεν θα λειτουργήσει.
addEventListener
είναι η συνάρτηση που χρησιμοποιείται από το JS για να δηλώσει τη συνάρτηση που αναμένει postMessages
.
Ένας κώδικας παρόμοιος με τον παρακάτω θα χρησιμοποιηθεί:
Σημειώστε σε αυτή την περίπτωση πώς το πρώτο πράγμα που κάνει ο κώδικας είναι έλεγχος της προέλευσης. Αυτό είναι τρομερά σημαντικό κυρίως αν η σελίδα πρόκειται να κάνει οτιδήποτε ευαίσθητο με τις πληροφορίες που λαμβάνει (όπως η αλλαγή ενός κωδικού πρόσβασης). Αν δεν ελέγξει την προέλευση, οι επιτιθέμενοι μπορούν να κάνουν τα θύματα να στείλουν αυθαίρετα δεδομένα σε αυτά τα endpoints και να αλλάξουν τους κωδικούς πρόσβασης των θυμάτων (σε αυτό το παράδειγμα).
Για να βρείτε ακροατές γεγονότων στην τρέχουσα σελίδα μπορείτε να:
Αναζητήσετε τον κώδικα JS για window.addEventListener
και $(window).on
(έκδοση JQuery)
Εκτελέσετε στην κονσόλα εργαλείων προγραμματιστή: getEventListeners(window)
Μεταβείτε σε Elements --> Event Listeners στα εργαλεία προγραμματιστή του προγράμματος περιήγησης
Χρησιμοποιήστε μια επέκταση προγράμματος περιήγησης όπως https://github.com/benso-io/posta ή https://github.com/fransr/postMessage-tracker. Αυτές οι επεκτάσεις προγράμματος περιήγησης θα παρεμποδίσουν όλα τα μηνύματα και θα σας τα δείξουν.
Το χαρακτηριστικό event.isTrusted
θεωρείται ασφαλές καθώς επιστρέφει True
μόνο για γεγονότα που παράγονται από γνήσιες ενέργειες χρηστών. Αν και είναι δύσκολο να παρακαμφθεί αν έχει υλοποιηθεί σωστά, η σημασία του στους ελέγχους ασφαλείας είναι αξιοσημείωτη.
Η χρήση του indexOf()
για την επικύρωση προέλευσης σε γεγονότα PostMessage μπορεί να είναι επιρρεπής σε παράκαμψη. Ένα παράδειγμα που απεικονίζει αυτή την ευπάθεια είναι:
Η μέθοδος search()
από το String.prototype.search()
προορίζεται για κανονικές εκφράσεις, όχι για συμβολοσειρές. Η παράδοση οτιδήποτε άλλο εκτός από μια regexp οδηγεί σε έμμεση μετατροπή σε regex, καθιστώντας τη μέθοδο δυνητικά ανασφαλή. Αυτό συμβαίνει επειδή στο regex, μια τελεία (.) λειτουργεί ως χαρακτήρας μπαλαντέρ, επιτρέποντας την παράκαμψη της επικύρωσης με ειδικά κατασκευασμένα domains. Για παράδειγμα:
Η συνάρτηση match()
, παρόμοια με τη search()
, επεξεργάζεται regex. Αν το regex είναι κακώς δομημένο, μπορεί να είναι επιρρεπές σε παράκαμψη.
Η συνάρτηση escapeHtml
προορίζεται να καθαρίζει τις εισόδους με την απόδραση χαρακτήρων. Ωστόσο, δεν δημιουργεί ένα νέο αντικείμενο που έχει αποδράσει αλλά αντικαθιστά τις ιδιότητες του υπάρχοντος αντικειμένου. Αυτή η συμπεριφορά μπορεί να εκμεταλλευτεί. Ιδιαίτερα, αν ένα αντικείμενο μπορεί να χειριστεί έτσι ώστε η ελεγχόμενη ιδιότητά του να μην αναγνωρίζει το hasOwnProperty
, η escapeHtml
δεν θα λειτουργήσει όπως αναμένεται. Αυτό αποδεικνύεται στα παρακάτω παραδείγματα:
Αναμενόμενη Αποτυχία:
Παράκαμψη της απόδρασης:
Στο πλαίσιο αυτής της ευπάθειας, το αντικείμενο File
είναι ιδιαίτερα εκμεταλλεύσιμο λόγω της μόνο για ανάγνωση ιδιότητας name
. Αυτή η ιδιότητα, όταν χρησιμοποιείται σε πρότυπα, δεν καθαρίζεται από τη συνάρτηση escapeHtml
, οδηγώντας σε δυνητικούς κινδύνους ασφαλείας.
Η ιδιότητα document.domain
στην JavaScript μπορεί να οριστεί από ένα σενάριο για να συντομεύσει το domain, επιτρέποντας πιο χαλαρή επιβολή πολιτικής ίδιας προέλευσης εντός της ίδιας γονικής τοποθεσίας.
Όταν ενσωματώνετε μια ιστοσελίδα μέσα σε ένα sandboxed iframe χρησιμοποιώντας %%%%%%, είναι κρίσιμο να κατανοήσετε ότι η προέλευση του iframe θα οριστεί σε null. Αυτό είναι ιδιαίτερα σημαντικό όταν ασχολείστε με sandbox attributes και τις επιπτώσεις τους στην ασφάλεια και τη λειτουργικότητα.
Με την καθορισμένη allow-popups
στο sandbox attribute, οποιοδήποτε παράθυρο popup ανοίγει από μέσα στο iframe κληρονομεί τους περιορισμούς sandbox του γονέα του. Αυτό σημαίνει ότι εκτός αν περιληφθεί επίσης το χαρακτηριστικό allow-popups-to-escape-sandbox
, η προέλευση του παραθύρου popup ορίζεται επίσης σε null
, ευθυγραμμισμένη με την προέλευση του iframe.
Κατά συνέπεια, όταν ανοίγει ένα popup υπό αυτές τις συνθήκες και αποστέλλεται ένα μήνυμα από το iframe στο popup χρησιμοποιώντας postMessage
, και οι δύο πλευρές αποστολής και λήψης έχουν τις προελεύσεις τους ορισμένες σε null
. Αυτή η κατάσταση οδηγεί σε ένα σενάριο όπου e.origin == window.origin
αξιολογείται ως αληθές (null == null
), επειδή τόσο το iframe όσο και το popup μοιράζονται την ίδια τιμή προέλευσης null
.
Για περισσότερες πληροφορίες διαβάστε:
Bypassing SOP with Iframes - 1Είναι δυνατόν να ελέγξετε αν το μήνυμα προήλθε από το ίδιο παράθυρο στο οποίο ακούει το σενάριο (ιδιαίτερα ενδιαφέρον για Content Scripts από επεκτάσεις προγράμματος περιήγησης για να ελέγξετε αν το μήνυμα στάλθηκε από την ίδια σελίδα):
Μπορείτε να αναγκάσετε το e.source
ενός μηνύματος να είναι null δημιουργώντας ένα iframe που στέλνει το postMessage και διαγράφεται αμέσως.
Για περισσότερες πληροφορίες διαβάστε:
Bypassing SOP with Iframes - 2Για να εκτελέσετε αυτές τις επιθέσεις, ιδανικά θα πρέπει να μπορείτε να τοποθετήσετε τη σελίδα του θύματος μέσα σε ένα iframe
. Αλλά ορισμένα headers όπως το X-Frame-Header
μπορούν να αποτρέψουν αυτή τη συμπεριφορά.
Σε αυτές τις περιπτώσεις μπορείτε να χρησιμοποιήσετε μια λιγότερο διακριτική επίθεση. Μπορείτε να ανοίξετε μια νέα καρτέλα στην ευάλωτη διαδικτυακή εφαρμογή και να επικοινωνήσετε μαζί της:
Στην παρακάτω σελίδα μπορείτε να δείτε πώς θα μπορούσατε να κλέψετε δεδομένα ευαίσθητης postmessage που αποστέλλονται σε ένα child iframe μπλοκάροντας την κύρια σελίδα πριν στείλετε τα δεδομένα και εκμεταλλευόμενοι μια XSS στο παιδί για να leak the data πριν παραληφθούν:
Blocking main page to steal postmessageΑν μπορείτε να iframe μια ιστοσελίδα χωρίς X-Frame-Header που περιέχει άλλο iframe, μπορείτε να αλλάξετε την τοποθεσία αυτού του child iframe, οπότε αν λαμβάνει ένα postmessage που αποστέλλεται χρησιμοποιώντας ένα wildcard, ένας επιτιθέμενος θα μπορούσε να αλλάξει την προέλευση αυτού του iframe σε μια σελίδα που ελέγχει και να κλέψει το μήνυμα:
Steal postmessage modifying iframe locationΣε σενάρια όπου τα δεδομένα που αποστέλλονται μέσω του postMessage
εκτελούνται από JS, μπορείτε να iframe την σελίδα και να εκμεταλλευτείτε την prototype pollution/XSS στέλνοντας την εκμετάλλευση μέσω του postMessage
.
Μερικά από τα πολύ καλά εξηγημένα XSS μέσω postMessage
μπορούν να βρεθούν στο https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html
Παράδειγμα μιας εκμετάλλευσης για να εκμεταλλευτείτε Prototype Pollution και στη συνέχεια XSS μέσω ενός postMessage
σε ένα iframe
:
Για περισσότερες πληροφορίες:
Σύνδεσμος στη σελίδα σχετικά με προβλήματα πρωτοτύπου
Σύνδεσμος στη σελίδα σχετικά με XSS
Σύνδεσμος στη σελίδα σχετικά με προβλήματα πρωτοτύπου από την πλευρά του πελάτη σε XSS
Για εξάσκηση: https://github.com/yavolo/eventlistener-xss-recon
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)