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 στο παιδί για να διαρρεύσετε τα δεδομένα πριν αυτά ληφθούν:
Blocking main page to steal postmessageΕάν μπορείτε να iframe μια ιστοσελίδα χωρίς X-Frame-Header που περιέχει άλλο iframe, μπορείτε να αλλάξετε τη θέση αυτού του child iframe, έτσι ώστε αν λαμβάνει ένα postmessage που αποστέλλεται χρησιμοποιώντας ένα wildcard, ένας επιτιθέμενος θα μπορούσε να αλλάξει την προέλευση αυτού του iframe σε μια σελίδα που ελέγχει και να κλέψει το μήνυμα:
Steal postmessage modifying iframe locationΣε σενάρια όπου τα δεδομένα που αποστέλλονται μέσω του postMessage
εκτελούνται από JS, μπορείτε να iframe την σελίδα και να εκμεταλλευτείτε την προτοτυπική ρύπανση/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)