Browser Extension Pentesting Methodology
Basic Information
Οι επεκτάσεις προγράμματος περιήγησης είναι γραμμένες σε JavaScript και φορτώνονται από τον περιηγητή στο παρασκήνιο. Έχει το DOM της αλλά μπορεί να αλληλεπιδρά με τα DOM άλλων ιστότοπων. Αυτό σημαίνει ότι μπορεί να θέσει σε κίνδυνο την εμπιστευτικότητα, την ακεραιότητα και τη διαθεσιμότητα (CIA) άλλων ιστότοπων.
Main Components
Οι διάταξεις των επεκτάσεων φαίνονται καλύτερες όταν απεικονίζονται και αποτελούνται από τρία στοιχεία. Ας δούμε κάθε στοιχείο σε βάθος.
Content Scripts
Κάθε script περιεχομένου έχει άμεση πρόσβαση στο DOM μιας μοναδικής ιστοσελίδας και είναι έτσι εκτεθειμένο σε πιθανώς κακόβουλη είσοδο. Ωστόσο, το script περιεχομένου δεν περιέχει δικαιώματα εκτός από την ικανότητα να στέλνει μηνύματα στον πυρήνα της επέκτασης.
Extension Core
Ο πυρήνας της επέκτασης περιέχει τα περισσότερα από τα προνόμια/πρόσβαση της επέκτασης, αλλά ο πυρήνας της επέκτασης μπορεί να αλληλεπιδρά μόνο με το περιεχόμενο του ιστού μέσω του XMLHttpRequest και των scripts περιεχομένου. Επίσης, ο πυρήνας της επέκτασης δεν έχει άμεση πρόσβαση στη μηχανή φιλοξενίας.
Native Binary
Η επέκταση επιτρέπει μια εγγενή δυαδική που μπορεί να πρόσβαση στη μηχανή φιλοξενίας με τα πλήρη προνόμια του χρήστη. Η εγγενής δυαδική αλληλεπιδρά με τον πυρήνα της επέκτασης μέσω του τυπικού Netscape Plugin Application Programming Interface (NPAPI) που χρησιμοποιείται από το Flash και άλλα πρόσθετα προγράμματος περιήγησης.
Boundaries
Για να αποκτήσει τα πλήρη προνόμια του χρήστη, ένας επιτιθέμενος πρέπει να πείσει την επέκταση να περάσει κακόβουλη είσοδο από το script περιεχομένου στον πυρήνα της επέκτασης και από τον πυρήνα της επέκτασης στην εγγενή δυαδική.
Κάθε στοιχείο της επέκτασης είναι χωρισμένο το ένα από το άλλο με ισχυρά προστατευτικά όρια. Κάθε στοιχείο εκτελείται σε μια ξεχωριστή διαδικασία λειτουργικού συστήματος. Τα scripts περιεχομένου και οι πυρήνες επεκτάσεων εκτελούνται σε διαδικασίες sandbox που δεν είναι διαθέσιμες στους περισσότερους υπηρεσίες λειτουργικού συστήματος.
Επιπλέον, τα scripts περιεχομένου είναι χωρισμένα από τις σχετικές ιστοσελίδες τους εκτελώντας σε μια ξεχωριστή στοίβα JavaScript. Το script περιεχομένου και η ιστοσελίδα έχουν πρόσβαση στο ίδιο υποκείμενο DOM, αλλά οι δύο ποτέ δεν ανταλλάσσουν δείκτες JavaScript, αποτρέποντας τη διαρροή λειτουργικότητας JavaScript.
manifest.json
manifest.json
Μια επέκταση Chrome είναι απλώς ένας φάκελος ZIP με μια .crx file extension. Ο πυρήνας της επέκτασης είναι το manifest.json
αρχείο στη ρίζα του φακέλου, το οποίο καθορίζει τη διάταξη, τα δικαιώματα και άλλες επιλογές διαμόρφωσης.
Example:
content_scripts
content_scripts
Τα περιεχόμενα σενάρια φορτώνονται όποτε ο χρήστης μεταβαίνει σε μια αντίστοιχη σελίδα, στην περίπτωσή μας οποιαδήποτε σελίδα που ταιριάζει με την https://example.com/*
έκφραση και δεν ταιριάζει με την *://*/*/business*
κανονική έκφραση. Εκτελούνται όπως τα δικά της σενάρια της σελίδας και έχουν αυθαίρετη πρόσβαση στο Document Object Model (DOM) της σελίδας.
Για να συμπεριλάβετε ή να αποκλείσετε περισσότερες διευθύνσεις URL, είναι επίσης δυνατή η χρήση include_globs
και exclude_globs
.
Αυτό είναι ένα παράδειγμα περιεχομένου script που θα προσθέσει ένα κουμπί εξήγησης στη σελίδα όταν χρησιμοποιεί το storage API για να ανακτήσει την τιμή message
από την αποθήκευση της επέκτασης.
Ένα μήνυμα αποστέλλεται στις σελίδες της επέκτασης από το περιεχόμενο του script όταν αυτό το κουμπί πατηθεί, μέσω της χρήσης του runtime.sendMessage() API. Αυτό οφείλεται στον περιορισμό του περιεχομένου του script στην άμεση πρόσβαση σε APIs, με το storage
να είναι μία από τις λίγες εξαιρέσεις. Για λειτουργίες πέρα από αυτές τις εξαιρέσεις, τα μηνύματα αποστέλλονται στις σελίδες της επέκτασης με τις οποίες μπορούν να επικοινωνούν τα περιεχόμενα scripts.
Ανάλογα με τον περιηγητή, οι δυνατότητες του περιεχομένου του script μπορεί να διαφέρουν ελαφρώς. Για τους περιηγητές που βασίζονται σε Chromium, η λίστα δυνατοτήτων είναι διαθέσιμη στην τεκμηρίωση Chrome Developers, και για τον Firefox, το MDN χρησιμεύει ως η κύρια πηγή. Είναι επίσης αξιοσημείωτο ότι τα περιεχόμενα scripts έχουν τη δυνατότητα να επικοινωνούν με τα background scripts, επιτρέποντάς τους να εκτελούν ενέργειες και να μεταφέρουν απαντήσεις πίσω.
Για την προβολή και την αποσφαλμάτωση των περιεχομένων scripts στο Chrome, το μενού εργαλείων προγραμματιστών του Chrome μπορεί να προσπελαστεί από Επιλογές > Περισσότερα εργαλεία > Εργαλεία προγραμματιστών Ή πατώντας Ctrl + Shift + I.
Αφού εμφανιστούν τα εργαλεία προγραμματιστών, πρέπει να κάνετε κλικ στην καρτέλα Πηγή, ακολουθούμενη από την καρτέλα Περιεχόμενα Scripts. Αυτό επιτρέπει την παρακολούθηση των εκτελούμενων περιεχομένων scripts από διάφορες επεκτάσεις και τη ρύθμιση σημείων διακοπής για την παρακολούθηση της ροής εκτέλεσης.
Εισαγόμενα περιεχόμενα scripts
Σημειώστε ότι Τα Περιεχόμενα Scripts δεν είναι υποχρεωτικά καθώς είναι επίσης δυνατή η δυναμική εισαγωγή scripts και η προγραμματική εισαγωγή τους σε ιστοσελίδες μέσω του tabs.executeScript
. Αυτό παρέχει στην πραγματικότητα περισσότερους λεπτομερείς ελέγχους.
Για την προγραμματική εισαγωγή ενός περιεχομένου script, απαιτείται η επέκταση να έχει δικαιώματα φιλοξενίας για τη σελίδα στην οποία θα εισαχθούν τα scripts. Αυτά τα δικαιώματα μπορεί να εξασφαλιστούν είτε ζητώντας τα εντός του μανιφέστ της επέκτασης είτε προσωρινά μέσω του activeTab.
Παράδειγμα επέκτασης βασισμένης σε activeTab
Εισαγωγή ενός αρχείου JS με κλικ:
Εισάγετε μια συνάρτηση με κλικ:
Παράδειγμα με δικαιώματα scripting
Για να συμπεριλάβετε ή να αποκλείσετε περισσότερες διευθύνσεις URL, είναι επίσης δυνατή η χρήση include_globs
και exclude_globs
.
Περιεχόμενο Scripts run_at
run_at
Το πεδίο run_at
ελέγχει πότε τα αρχεία JavaScript εισάγονται στη σελίδα web. Η προτιμώμενη και προεπιλεγμένη τιμή είναι το "document_idle"
.
Οι δυνατές τιμές είναι:
document_idle
: Όποτε είναι δυνατόνdocument_start
: Μετά από οποιαδήποτε αρχεία απόcss
, αλλά πριν από οποιαδήποτε άλλη DOM κατασκευαστεί ή εκτελεστεί οποιοδήποτε άλλο σενάριο.document_end
: Άμεσα μετά την ολοκλήρωση της DOM, αλλά πριν φορτωθούν υπο-πόροι όπως εικόνες και πλαίσια.
Μέσω manifest.json
manifest.json
Μέσω service-worker.js
background
background
Τα μηνύματα που αποστέλλονται από τα περιεχόμενα σενάρια γίνονται δεκτά από τη σελίδα φόντου, η οποία διαδραματίζει κεντρικό ρόλο στην συντονισμένη λειτουργία των στοιχείων της επέκτασης. Σημαντικά, η σελίδα φόντου παραμένει καθ' όλη τη διάρκεια ζωής της επέκτασης, λειτουργώντας διακριτικά χωρίς άμεση αλληλεπίδραση του χρήστη. Διαθέτει το δικό της Document Object Model (DOM), επιτρέποντας πολύπλοκες αλληλεπιδράσεις και διαχείριση καταστάσεων.
Βασικά Σημεία:
Ρόλος Σελίδας Φόντου: Λειτουργεί ως το κέντρο ελέγχου για την επέκταση, εξασφαλίζοντας την επικοινωνία και τον συντονισμό μεταξύ των διαφόρων τμημάτων της επέκτασης.
Επιμονή: Είναι μια πάντα παρούσα οντότητα, αόρατη στον χρήστη αλλά αναπόσπαστο μέρος της λειτουργικότητας της επέκτασης.
Αυτόματη Δημιουργία: Εάν δεν οριστεί ρητά, ο περιηγητής θα δημιουργήσει αυτόματα μια σελίδα φόντου. Αυτή η αυτόματα δημιουργημένη σελίδα θα περιλαμβάνει όλα τα σενάρια φόντου που καθορίζονται στο μανιφέστο της επέκτασης, εξασφαλίζοντας την απρόσκοπτη λειτουργία των εργασιών φόντου της επέκτασης.
Η ευκολία που παρέχει ο περιηγητής στην αυτόματη δημιουργία μιας σελίδας φόντου (όταν δεν δηλώνεται ρητά) εξασφαλίζει ότι όλα τα απαραίτητα σενάρια φόντου είναι ενσωματωμένα και λειτουργικά, απλοποιώντας τη διαδικασία ρύθμισης της επέκτασης.
Example background script:
Χρησιμοποιεί το runtime.onMessage API για να ακούει μηνύματα. Όταν ληφθεί ένα μήνυμα "explain"
, χρησιμοποιεί το tabs API για να ανοίξει μια σελίδα σε μια νέα καρτέλα.
Για να αποσφαλματώσετε το background script, μπορείτε να μεταβείτε στις λεπτομέρειες της επέκτασης και να επιθεωρήσετε τον service worker, αυτό θα ανοίξει τα εργαλεία προγραμματιστή με το background script:
Σελίδες επιλογών και άλλες
Οι επεκτάσεις προγράμματος περιήγησης μπορούν να περιέχουν διάφορους τύπους σελίδων:
Σελίδες δράσης εμφανίζονται σε ένα αναδυόμενο μενού όταν κάνετε κλικ στο εικονίδιο της επέκτασης.
Σελίδες που η επέκταση θα φορτώσει σε μια νέα καρτέλα.
Σελίδες επιλογών: Αυτή η σελίδα εμφανίζεται πάνω από την επέκταση όταν κάνετε κλικ. Στο προηγούμενο manifest, στην περίπτωσή μου, μπόρεσα να αποκτήσω πρόσβαση σε αυτή τη σελίδα στο
chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca
ή κάνοντας κλικ:
Σημειώστε ότι αυτές οι σελίδες δεν είναι μόνιμες όπως οι σελίδες background, καθώς φορτώνουν δυναμικά περιεχόμενο κατά την ανάγκη. Παρά τούτο, μοιράζονται ορισμένες δυνατότητες με τη σελίδα background:
Επικοινωνία με Content Scripts: Παρόμοια με τη σελίδα background, αυτές οι σελίδες μπορούν να λαμβάνουν μηνύματα από content scripts, διευκολύνοντας την αλληλεπίδραση εντός της επέκτασης.
Πρόσβαση σε APIs συγκεκριμένα για την επέκταση: Αυτές οι σελίδες απολαμβάνουν πλήρη πρόσβαση σε APIs συγκεκριμένα για την επέκταση, υπό την προϋπόθεση των αδειών που ορίζονται για την επέκταση.
permissions
& host_permissions
permissions
& host_permissions
permissions
και host_permissions
είναι καταχωρήσεις από το manifest.json
που θα υποδείξουν ποιες άδειες έχει η επέκταση του προγράμματος περιήγησης (αποθήκευση, τοποθεσία...) και σε ποιες ιστοσελίδες.
Καθώς οι επεκτάσεις προγράμματος περιήγησης μπορεί να είναι τόσο προνομιούχες, μια κακόβουλη ή μια που έχει παραβιαστεί θα μπορούσε να επιτρέψει στον επιτιθέμενο διαφορετικούς τρόπους να κλέψει ευαίσθητες πληροφορίες και να κατασκοπεύσει τον χρήστη.
Ελέγξτε πώς λειτουργούν αυτές οι ρυθμίσεις και πώς θα μπορούσαν να καταχραστούν στο:
BrowExt - permissions & host_permissionscontent_security_policy
content_security_policy
Μια πολιτική ασφαλείας περιεχομένου μπορεί επίσης να δηλωθεί μέσα στο manifest.json
. Εάν υπάρχει μία καθορισμένη, θα μπορούσε να είναι ευάλωτη.
Η προεπιλεγμένη ρύθμιση για τις σελίδες επεκτάσεων προγράμματος περιήγησης είναι μάλλον περιοριστική:
Για περισσότερες πληροφορίες σχετικά με το CSP και τις πιθανές παρακάμψεις, ελέγξτε:
Content Security Policy (CSP) Bypassweb_accessible_resources
web_accessible_resources
Για να έχει μια ιστοσελίδα πρόσβαση σε μια σελίδα μιας Επέκτασης Περιηγητή, μια σελίδα .html
για παράδειγμα, αυτή η σελίδα πρέπει να αναφέρεται στο πεδίο web_accessible_resources
του manifest.json
.
Για παράδειγμα:
Αυτές οι σελίδες είναι προσβάσιμες σε URL όπως:
In public extensions the extension-id είναι προσβάσιμο:
Ωστόσο, αν η παράμετρος manifest.json
use_dynamic_url
χρησιμοποιείται, αυτό το id μπορεί να είναι δυναμικό.
Σημειώστε ότι ακόμη και αν μια σελίδα αναφέρεται εδώ, μπορεί να είναι προστατευμένη από ClickJacking χάρη στην Πολιτική Ασφαλείας Περιεχομένου. Έτσι, πρέπει επίσης να το ελέγξετε (τμήμα frame-ancestors) πριν επιβεβαιώσετε ότι είναι δυνατή μια επίθεση ClickJacking.
Η δυνατότητα πρόσβασης σε αυτές τις σελίδες καθιστά αυτές τις σελίδες πιθανώς ευάλωτες σε ClickJacking:
BrowExt - ClickJackingΗ επιτρεπόμενη φόρτωση αυτών των σελίδων μόνο από την επέκταση και όχι από τυχαίες διευθύνσεις URL θα μπορούσε να αποτρέψει επιθέσεις ClickJacking.
Σημειώστε ότι οι σελίδες από web_accessible_resources
και άλλες σελίδες της επέκτασης είναι επίσης ικανές να επικοινωνούν με σενάρια φόντου. Έτσι, αν μία από αυτές τις σελίδες είναι ευάλωτη σε XSS, θα μπορούσε να ανοίξει μια μεγαλύτερη ευπάθεια.
Επιπλέον, σημειώστε ότι μπορείτε να ανοίξετε μόνο σελίδες που αναφέρονται σε web_accessible_resources
μέσα σε iframes, αλλά από μια νέα καρτέλα είναι δυνατή η πρόσβαση σε οποιαδήποτε σελίδα στην επέκταση γνωρίζοντας το ID της επέκτασης. Επομένως, αν βρεθεί XSS που εκμεταλλεύεται τις ίδιες παραμέτρους, θα μπορούσε να εκμεταλλευτεί ακόμη και αν η σελίδα δεν είναι ρυθμισμένη σε web_accessible_resources
.
externally_connectable
externally_connectable
Σύμφωνα με τα docs, Η ιδιότητα "externally_connectable"
του manifest δηλώνει ποια extensions και ιστοσελίδες μπορούν να συνδεθούν με την επέκτασή σας μέσω runtime.connect και runtime.sendMessage.
Αν το
externally_connectable
κλειδί δεν δηλώνεται στο manifest της επέκτασής σας ή δηλώνεται ως"ids": ["*"]
, όλες οι επεκτάσεις μπορούν να συνδεθούν, αλλά καμία ιστοσελίδα δεν μπορεί να συνδεθεί.Αν καθοριστούν συγκεκριμένα IDs, όπως στο
"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]
, μόνο αυτές οι εφαρμογές μπορούν να συνδεθούν.Αν καθοριστούν matches, αυτές οι διαδικτυακές εφαρμογές θα μπορούν να συνδεθούν:
Αν έχει καθοριστεί ως κενό:
"externally_connectable": {}
, καμία εφαρμογή ή ιστότοπος δεν θα μπορεί να συνδεθεί.
Οι λιγότερες επεκτάσεις και διευθύνσεις URL που αναφέρονται εδώ, τόσο μικρότερη θα είναι η επιφάνεια επίθεσης.
Αν μια ιστοσελίδα ευάλωτη σε XSS ή takeover αναφέρεται σε externally_connectable
, ένας επιτιθέμενος θα μπορεί να στείλει μηνύματα απευθείας στο background script, παρακάμπτοντας εντελώς το Content Script και το CSP του.
Επομένως, αυτή είναι μια πολύ ισχυρή παράκαμψη.
Επιπλέον, αν ο πελάτης εγκαταστήσει μια κακόβουλη επέκταση, ακόμη και αν δεν επιτρέπεται να επικοινωνήσει με την ευάλωτη επέκταση, θα μπορούσε να εισάγει δεδομένα XSS σε μια επιτρεπόμενη ιστοσελίδα ή να καταχραστεί τις APIs WebRequest
ή DeclarativeNetRequest
για να χειριστεί αιτήματα σε έναν στοχευμένο τομέα, αλλάζοντας το αίτημα μιας σελίδας για ένα αρχείο JavaScript. (Σημειώστε ότι το CSP στη στοχευμένη σελίδα θα μπορούσε να αποτρέψει αυτές τις επιθέσεις). Αυτή η ιδέα προέρχεται από αυτή τη γραφή.
Περίληψη επικοινωνίας
Επέκταση <--> WebApp
Για να επικοινωνήσουν το περιεχόμενο script και η ιστοσελίδα, συνήθως χρησιμοποιούνται μηνύματα post. Επομένως, στην εφαρμογή ιστού θα βρείτε συνήθως κλήσεις στη συνάρτηση window.postMessage
και στο περιεχόμενο script ακροατές όπως window.addEventListener
. Σημειώστε ωστόσο, ότι η επέκταση θα μπορούσε επίσης να επικοινωνήσει με την εφαρμογή ιστού στέλνοντας ένα Post Message (και επομένως η ιστοσελίδα θα πρέπει να το περιμένει) ή απλώς να κάνει την ιστοσελίδα να φορτώσει ένα νέο script.
Μέσα στην επέκταση
Συνήθως η συνάρτηση chrome.runtime.sendMessage
χρησιμοποιείται για να στείλει ένα μήνυμα μέσα στην επέκταση (συνήθως διαχειρίζεται από το background
script) και για να το λάβει και να το διαχειριστεί δηλώνεται ένας ακροατής καλώντας chrome.runtime.onMessage.addListener
.
Είναι επίσης δυνατό να χρησιμοποιηθεί chrome.runtime.connect()
για να υπάρχει μια μόνιμη σύνδεση αντί να στέλνονται μεμονωμένα μηνύματα, είναι δυνατό να χρησιμοποιηθεί για να στείλει και λάβει μηνύματα όπως στο παρακάτω παράδειγμα:
Last updated