Полгода я выстраивал AiTM-кампании против Google-аккаунтов - Evilginx2, кастомные прокси, перехват сессий. Главная боль при работе с Google: куки ротируются агрессивнее, чем у любого другого IdP, refresh token живёт минуты, а Device Bound Session Credentials (DBSC) начинают привязывать сессию к TPM устройства жертвы. Перехватил сессию - через двадцать минут она мёртвая. И тут появляется техника, которую условно назвали vaultjacking. Суть: одна дополнительная модалка в стандартном AiTM-потоке - запрос шестизначного PIN от Google Password Manager - превращает одноразовый перехват сессии в полную выгрузку vault со всеми паролями и synced passkeys жертвы. На инфраструктуре оператора. С persistence, которая переживает смену пароля.
Бизнес-логика атаки: зачем атакующему vault целиком
Классический AiTM-фишинг Google-аккаунта даёт одну сессию - почту, диск, календарь. Ценно, но ограничено по времени и масштабу. Vaultjacking меняет арифметику: вместо одного аккаунта атакующий получает доступ ко всем сервисам, пароли и passkeys к которым жертва когда-либо сохраняла в Google Password Manager. Банкинг, корпоративный SSO, биржи, VPN-доступы - один фишинговый engagement, N учётных записей на выходе. Без rate limit, без повторных фишинговых кампаний на каждый отдельный сервис.Для red team операций последствия прямые: компрометация одного сотрудника, хранящего рабочие пароли в Chrome-профиле, потенциально открывает lateral movement в корпоративную инфраструктуру без единого payload на хосте жертвы. Blast radius сопоставим с дампом NTDS.dit - только вектор не через внутреннюю сеть, а через фишинг менеджера паролей.
[Применимо: внешний пентест, red team, любая инфраструктура, где сотрудники используют GPM для рабочих учётных данных]
Архитектура GPM: Security Domain и шестизначный gate
У каждого Google-аккаунта есть security domain. Устройства, присоединённые к этому домену, получают доступ ко всему синхронизированному хранилищу: паролям и synced passkeys. Расшифровка на каждом устройстве работает через Security Domain Secret (SDS) - криптографический ключ, который облачный сервис Google выдаёт устройству при успешном join к домену.
Процедура join нового устройства требует двух вещей:
- Валидный вход в Google-аккаунт (с прохождением MFA).
- Ввод шестизначного PIN от Google Password Manager.
chrome/browser/webauthn/enclave_manager.cc и components/trusted_vault/ - после прохождения обоих этапов облачный сервис выдаёт SDS без дополнительных проверок. Нет push-уведомления на существующие устройства. Нет запроса на подтверждение с телефона. Единственный сигнал - email "новый вход на Windows", идентичный стандартному уведомлению при любом входе в Chrome.Это архитектурное решение - осознанный выбор Google в пользу UX. Apple iCloud Keychain работает по-другому: push-to-existing-devices, каждое новое устройство должно быть одобрено с уже авторизованного. Google выбрал PIN с серверным rate-limiting, оценив фишабельность как приемлемый компромисс ради решения проблемы lost-device recovery. Именно отсутствие cross-device approval и делает vaultjacking возможным.
В актуальных версиях Chrome sync-payload включает не только пароли, но и приватные байты synced passkeys, созданных через Google Password Manager как платформенный аутентификатор. Passkeys, созданные на hardware-ключе (YubiKey и др.), в sync не попадают по дизайну CTAP2 - это non-exportable credentials. По описанию техники, она предположительно была протестирована end-to-end на живых GPM-аккаунтах, включая replay перехваченных passkeys против сторонних сервисов.
Полная цепочка vaultjacking: четыре шага к credential dump
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Отдельная тема - DBSC. Google развёртывает Device Bound Session Credentials, привязывающие сессионные куки к TPM устройства, на котором происходила аутентификация. DBSC не спасает от inline AiTM-перехвата в момент live-аутентификации, но ограничивает повторное использование украденных куки на другом устройстве - replay на VM оператора не работает. Поэтому атака не полагается на долгоживущие украденные куки, а регистрирует backdoor-passkey: passkey-аутентификация на VM оператора создаёт новую DBSC-привязанную сессию легитимно.
Join Security Domain и расшифровка vault
Требования к инфраструктуре оператора:- Windows VM (10 или 11) с виртуальным TPM (vTPM)
- Headless browser framework (Playwright, Puppeteer)
- Сетевой доступ к
enclave.ua5v.com(cloud authenticator Google) - AiTM-прокси с поддержкой DBSC (если Google включил DBSC для целевого аккаунта)
Результат - полный дамп в SQLite-базе Chrome:
Python:
# После join к Security Domain Chrome
# на VM оператора расшифровывает sync payload через SDS
# и пишет пароли в Login Data (SQLite).
# password_value хранится как BLOB, зашифрованный os_crypt -
# для расшифровки нужен encrypted_key из Local State + DPAPI.
import sqlite3, os
path = os.path.expandvars(
r'%LOCALAPPDATA%\Google\Chrome\User Data\Default\Login Data'
)
db = sqlite3.connect(path)
for row in db.execute(
'SELECT origin_url, username_value FROM logins'
):
print(f'[+] {row[0]} - {row[1]}')
# Для password_value: извлечь encrypted_key из Local State,
# расшифровать через CryptUnprotectData / AES-GCM
Маппинг на MITRE ATT&CK и место в kill chain
Vaultjacking - не отдельная техника, а цепочка из нескольких TTPs, перекрывающих initial access и credential access.| Шаг атаки | MITRE ATT&CK | Тактика |
|---|---|---|
| Доставка жертвы на AiTM-прокси | Spearphishing Link (T1566.002) | Initial Access |
| Перехват PIN через спуфнутую модалку | GUI Input Capture (T1056.002) | Collection, Credential Access |
| Перехват сессионных куки | Steal Web Session Cookie (T1539) | Credential Access |
| Регистрация backdoor-passkey | Browser Session Hijacking (T1185) | Collection |
| Расшифровка vault через SDS | Password Managers (T1555.005) | Credential Access |
| Извлечение паролей из Chrome DB | Credentials from Web Browsers (T1555.003) | Credential Access |
Место в kill chain: vaultjacking начинается на initial access (фишинговая ссылка) и за один engagement выводит атаку на credential access с масштабом, недоступным при классическом AiTM. Дальше всё зависит от содержимого vault: пароли от корпоративного SSO - lateral movement без единого хоста внутри периметра; VPN-credentials - прямой доступ во внутреннюю сеть; API-ключи от облачных провайдеров - cloud compromise.
С точки зрения OWASP, атака эксплуатирует паттерн A07:2021 - Identification and Authentication Failures: механизм восстановления доступа к security domain полагается на единственный 6-digit PIN без cross-device verification. Детекция затруднена (A09:2021 - Security Logging and Monitoring Failures): единственный сигнал - стандартный email о новом входе.
Предусловия и ограничения техники
Работает если:- Жертва использует Google Password Manager с настроенным PIN (шестизначный цифровой)
- В vault есть сохранённые пароли и/или synced passkeys
- Жертва вводит PIN в спуфнутую модалку (социальная инженерия успешна)
- AiTM-прокси корректно обрабатывает полный Google auth flow
- Жертва не настроила PIN для GPM - join к security domain невозможен без PIN, модалке нечего запрашивать
- Жертва сидит исключительно на hardware FIDO2-ключе (YubiKey) без синхронизации passkeys - SDS attack surface отсутствует
- Жертва распознаёт спуфнутую модалку и отказывается вводить PIN - техника полностью завязана на социальную инженерию
- Google поменяет архитектуру join и добавит push-подтверждение с существующих устройств (сейчас не реализовано)
- Жертва использует Google Advanced Protection Program (APP) - ограничивает аутентификацию только hardware-ключами
- Два последовательных действия жертвы (пароль + PIN), каждое из которых может сорваться. Конверсия ниже, чем у стандартного AiTM без PIN-модала.
- Если vault жертвы пуст - gain от техники нулевой. Бывает обидно.
- Server-side rate-limiting на PIN: при брутфорсе Google блокирует попытки. Но при AiTM правильный PIN вводится с первого раза самой жертвой - rate-limiting не при делах.
OPSEC атакующего: что видит жертва и SOC
Исходя из архитектуры GPM, vaultjacking предположительно оставляет минимальный след:
- Email-уведомление: одно письмо "New sign-in on Windows" на recovery-адрес. Идентично любому новому входу в Chrome. Если AiTM перехватил почтовый ящик в той же сессии - оператор подавляет письмо до прочтения.
- Push-уведомления: не отправляются. Chrome-инстансы на других устройствах молчат. Мобильные устройства не получают prompt. Тишина.
- Google Workspace Admin Console: для корпоративных аккаунтов event "new device joined security domain" может быть видим в логах. Но стандартные SIEM-правила для Google Workspace не включают корреляцию "AiTM-вход + новый passkey + security domain join в течение 10 минут" как IoC. Без кастомных правил детекции атака проходит незамеченной.
Vaultjacking vs Browser Syncjacking vs классический AiTM
| Критерий | Классический AiTM | Browser Syncjacking | Vaultjacking |
|---|---|---|---|
| Foothold на устройстве жертвы | Нет | Да (вредоносное расширение) | Нет |
| Масштаб доступа | 1 сессия, 1 аккаунт | Sync-данные (зависит от расширения) | Весь vault: пароли + passkeys |
| Persistence | Сессионные куки (истекают) | Расширение (до удаления) | Backdoor-passkey (переживает смену пароля) |
| Обходит DBSC | Да (inline-перехват; replay куки ограничен) | Зависит от реализации | Да (через backdoor-passkey, не через replay куки) |
| Требуемые действия жертвы | Пароль + MFA | Установка расширения | Пароль + MFA + PIN |
| Основной IoC | Email "new sign-in" | Расширение в Chrome policy | Email "new sign-in" |
| Фреймворки | Evilginx2, Modlishka и др. | Кастомный extension | Кастомный AiTM-прокси |
Browser Syncjacking бьёт в тот же sync-слой GPM, но через вредоносное расширение на устройстве жертвы. Vaultjacking принципиально отличается: никакого присутствия на устройстве, никакого расширения, никакого malware. Всё выполняется inline через стандартный AiTM-фишинг.
Выбор между техниками зависит от сценария: watering hole или supply chain - Syncjacking. Фишинговое письмо со ссылкой и никакого foothold - vaultjacking.
Что ломает цепочку: защитные меры глазами атакующего
Контрмеры с позиции того, что реально усложняет жизнь оператору:Hardware FIDO2-ключи без синхронизации. YubiKey или аналог, зарегистрированный как единственный аутентификатор. Passkey хранится на устройстве, не попадает в sync-слой GPM, attack surface в виде SDS отсутствует. Единственная мера, которая закрывает vaultjacking полностью. Ограничение: UX-боль при потере ключа, оправдано для DevOps-команд и привилегированных аккаунтов.
Мониторинг security domain join events. В Google Workspace Admin Console и через Reports API доступны события добавления устройств к security domain. Корреляция "вход с нового IP + регистрация passkey + security domain join в окне 10 минут" - сильный IoC. На практике такие правила настраивают единицы организаций.
Разделение рабочих и личных учётных данных. Корпоративные пароли в enterprise password manager (1Password Business, Bitwarden Enterprise) вместо личного GPM. Blast radius vaultjacking ограничен личными аккаунтами сотрудника - корпоративная инфраструктура не затронута.
Обучение: когда PIN-промпт аномален. Штатный PIN-промпт Google появляется при настройке нового устройства или в
chrome://settings/passwords. В середине login flow на внешнем сервисе PIN не запрашивается. Если внешняя форма просит PIN от GPM - это красный флаг.Vaultjacking заставляет пересмотреть модель угроз для атак на хранилища паролей. Классический credential phishing работает по формуле "один сайт - один пароль". Здесь формула другая: "один PIN - весь vault". Разница не количественная, а качественная - атакующий получает полный credential dump, сопоставимый по масштабу с компрометацией доменного контроллера, но через фишинговое письмо, а не через внутреннюю сеть.
Индустрия несколько лет продвигала passkeys как phishing-resistant решение. На уровне per-site аутентификации они действительно устойчивы - WebAuthn-хэндшейк привязывает credential к origin, relay невозможен. Но vaultjacking бьёт не в per-site слой, а в sync-слой ниже. Passkey защищает вход на конкретный сервис, но не защищает хранилище, в котором он лежит. Это разные уровни модели угроз, и Google сделал осознанный выбор в пользу удобства на уровне хранилища, оставив шестизначный PIN как единственный gate. Интересно, сколько пройдёт времени до того, как Google добавит cross-device approval при join - по аналогии с Apple iCloud Keychain. Пока этого не произошло, единственная надёжная контрмера для привилегированных аккаунтов - hardware FIDO2 без синхронизации. Мониторинг ловит атаку пост-фактум, обучение снижает вероятность, но не закрывает вектор. Если в вашем скоупе есть организации с GPM как единственным хранилищем рабочих паролей - vaultjacking стоит добавить в playbook. Если интересно разобрать AiTM-цепочку от перехвата до credential dump на практике - web-задачи на HackerLab.pro (https://hackerlab.pro) дают именно эту механику.
Последнее редактирование модератором: