На одном IR-кейсе в финтех-компании мы снимали дамп RAM через WinPmem - RAT на рабочей станции разработчика обнаружили в четверг утром, полный образ памяти начали через четыре часа после старта реагирования. Bitwarden на машине был заблокирован: пользователь залочил хранилище за два часа до нашего приезда. Мастер-пароль из 24 символов лежал в heap-сегменте процесса Bitwarden.exe в открытом виде. Два часа после блокировки, никакого взаимодействия с приложением - а парольная фраза читается через
strings без единого преобразования. CVE-2023-38840. Тот кейс определил, как мы теперь строим мониторинг менеджеров паролей на эндпоинтах.Место в kill chain: зачем атакующему дамп памяти менеджера паролей
Менеджер паролей - золотая цель пост-эксплуатации. Дамп LSASS (T1003.001, Credential Access) даёт хеши доменных учёток текущей машины. Извлечение паролей из памяти менеджера (T1555.005, Credential Access) открывает доступ ко всему, что пользователь хранит в хранилище: корпоративные SaaS, VPN-конфигурации, API-ключи, SSH-сертификаты, учётки облачных консолей. Разница - как между одним ключом от квартиры и связкой от всего здания.Цепочка атаки:
- Initial Access - spearphishing, drive-by, компрометация supply chain
- Persistence - RAT закрепляется на хосте
- Discovery (T1057) - перечисление процессов, поиск Bitwarden.exe, KeePass.exe, 1Password.exe
- Credential Access (T1555.005) - чтение памяти целевого процесса или снятие minidump
- Collection (T1005) - параллельный сбор файлов хранилища (.kdbx, data.json)
- Exfiltration - вывод мастер-пароля и файлов хранилища на C2
procdump, Task Manager «Create Dump File» и др.). Для SOC это означает: мониторить нужно не только внешние угрозы, но и нетипичное использование легитимных утилит на внутренних хостах.Финансовая логика для Blue Team прозрачна: одна скомпрометированная учётка менеджера - не одна учётка, а десятки-сотни сервисов. Типичный сценарий из расследований: атакующий извлекает мастер-пароль Bitwarden из дампа, расшифровывает vault из
%AppData%\Bitwarden\data.json, логинится в облачную консоль через IAM-учётку из хранилища и создаёт backdoor-пользователя. От дампа до закрепления в облаке - менее часа. Для компаний под регуляторными требованиями это прямой путь к оборотным штрафам за утечку данных.Memory forensics менеджеров паролей: что остаётся в RAM
Ключевой вопрос для DFIR-аналитика при анализе памяти процессов менеджера паролей: что именно остаётся в RAM после ввода мастер-пароля, и что из этого переживает блокировку хранилища?
Bitwarden: мастер-пароль из памяти и CVE-2023-38840
Bitwarden Desktop построен на Electron - под капотом Chromium с движком V8. Каждая функциональная часть работает в отдельном дочернем процессе. При анализе дампа ищите процесс Bitwarden.exe с аргументом--no-zygote в командной строке - именно этот рендер-процесс кеширует чувствительные данные. Для веб-расширения в Chrome/Edge - процесс с --extension-process, но там уязвимость закрыли раньше, чем в десктоп-клиенте.Корень проблемы - архитектура V8. JavaScript-строки иммутабельны: перезаписать содержимое строки нулями нельзя, можно только обнулить ссылку на неё. При блокировке хранилища Bitwarden обнулял переменную с паролем, но сама строка оставалась в heap V8. Сборщик мусора V8 при освобождении памяти не зануляет содержимое - байты пароля лежат по тому же адресу, пока аллокатор не переиспользует область под другой объект. По сути, "заблокировать" - это выбросить ключ от сейфа, но оставить сейф открытым.
CVE-2023-38840 - CVSS 5.5 (MEDIUM). Вектор: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N. Ключевые компоненты: локальный доступ (AV:L), низкая сложность (AC:L), минимальные привилегии (PR:L), действие пользователя не требуется (UI:N), конфиденциальность - полная компрометация (C:H). Уязвимы Bitwarden Desktop версии 2023.7.0 и ниже включительно.
По данным исследования Hexiosec, мастер-пароль в памяти рендер-процесса предварялся стабильным hex-префиксом. Точный формат зависит от внутреннего представления строк V8 (SeqOneByteString vs SeqTwoByteString):
04 00 00 00 [длина] 00 00 00 01 [3 байта] [байты пароля] - приблизительная схема, где пятый байт кодирует длину строки (например, 0x14 для 20 ASCII-символов в SeqOneByteString). Первые четыре байта и байты 7–9 оставались стабильными даже после перезагрузки. Hexiosec создали PoC-инструмент BW-dump (тестировался на Bitwarden Desktop 2023.2.0) для автоматизированного извлечения мастер-пароля на Windows через Windows API для чтения памяти целевого процесса.Патч закрыл уязвимость в версиях выше 2023.7.0 (сама 2023.7.0 остаётся уязвимой). Но вот что важно: при разблокированном хранилище все записи vault находятся в памяти в расшифрованном виде. Это подтверждено в обсуждении на Bitwarden Community: "When the vault is unlocked, all of the vault contents exist in a decrypted state in the process memory""Когда сейф разблокирован, весь контект сейфа существует в памяти процесса в незафифрованном виде". Архитектурная неизбежность - приложение не может показать пароль, не расшифровав его.
KeePass: мастер-пароль из памяти через .NET heap
KeePass написан на .NET и используетSecureString, содержимое которого шифруется в памяти процесса (на Windows - через DPAPI/ProtectedMemory). На бумаге - надёжно. На практике - с оговорками, которые для memory forensics меняют всё.CVE-2023-32784 (CVSS 7.5, HIGH): в KeePass 2.x до версии 2.54 мастер-пароль (кроме первого символа) восстанавливается из дампа памяти, даже если хранилище заблокировано или процесс завершён. Root cause - уязвимость в SecureTextBoxEx: при посимвольном вводе пароля в маскированное поле каждый набранный символ порождал managed-строку остатков (
•a, ••ab, ••ab), которые оставались в managed heap .NET и позволяли восстановить пароль со второго символа. Это не связано с SecureString -> System.String конверсией для KDF - тот механизм представляет отдельный архитектурный риск.Помимо CVE-2023-32784, есть общая архитектурная проблема: при вводе мастер-пароля KeePass расшифровывает
SecureString в обычный System.String для криптографических операций - деривации ключа, проверки целостности базы. В этот момент дамп памяти мастер-пароль покажет в managed heap .NET. Компактирующий GC .NET перемещает объекты: копирует строку на новый адрес для дефрагментации, а старую область не обнуляет. Результат - несколько копий мастер-пароля в heap, ни одна не очищена. Если при анализе дампа пароль не находится по ожидаемому смещению - ищите в "мёртвых" областях кучи, куда GC переместил оригинал. GC в роли невольного архиватора паролей - ирония, которую разработчики .NET явно не закладывали.Каждая запись, к которой пользователь обращался за сессию, остаётся в памяти процесса в расшифрованном виде. По данным отчёта ISE 2019 года, на который ссылаются участники Bitwarden Community, это подтверждено для KeePass, 1Password и Dashlane.
Инструмент Password Manager Forensics (PMF), разработанный Sascha Hähni (репозиторий shaehni/password-manager-forensics на GitHub), автоматизирует извлечение артефактов из Bitwarden и KeePass на Windows. PMF реализует четырёхэтапный процесс: идентификация файлов менеджера, извлечение мастер-пароля из дампа памяти, парсинг конфигурации, расшифровка хранилища паролей forensics-совместимым способом с валидацией. Если мастер-пароль не удаётся вытащить из дампа - PMF переходит к брутфорсу PIN-кода или короткого пароля.
Сравнение подходов к защите памяти
| Аспект | Bitwarden Desktop (до 2023.7.0) | KeePass 2.x | 1Password |
|---|---|---|---|
| Архитектура | Electron / V8 | .NET Framework | Native (Rust/Go) |
| Мастер-пароль после блокировки | Остаётся в heap | SecureString, но копии в managed heap (CVE-2023-32784 до 2.54) | Нет публичных данных для актуальных версий |
| Vault в RAM при разблокировке | Полностью расшифрован | Расшифрованы просмотренные записи | Полностью расшифрован (ISE 2019) |
| Зануление при блокировке | Не выполнялось | Частичное (DPAPI + SecureString) | Заявлено через memory locking |
Данные по 1Password основаны на отчёте ISE 2019 - актуальные версии с Rust-компонентами могли серьёзно улучшить работу с памятью. Для текущего состояния нужна независимая верификация.
Извлечение хранилища паролей из RAM: практика
Требования к окружению:
- Целевая машина: Windows 10/11 или Windows Server 2016+
- Машина аналитика: Windows или GNU/Linux, Python 3.8+
- RAM аналитика: минимум 8 ГБ; для обработки дампов объёмом более 4 ГБ - 16 ГБ
- Инструменты: WinPmem (снятие полного дампа RAM), procdump (Sysinternals, дамп конкретного процесса), Volatility 3 (анализ образа), YARA 4.x (паттерн-матчинг)
- Диск: объём RAM целевой машины + 20% запас
Снятие дампа и анализ памяти процессов менеджера паролей
Тайминг критичен: чем дольше машина работает после инцидента, тем выше вероятность перезаписи области памяти с паролем - GC V8 или .NET переместит объект, а новая аллокация затрёт старые байты. Снимайте дамп при первой возможности. Каждая минута работает против вас.Два подхода в зависимости от задачи. Полный образ RAM через
winpmem_mini_x64.exe output.raw - даёт возможность проанализировать все процессы и реконструировать картину. Целевой дамп через procdump -ma <PID> bw_dump.dmp - быстрее и компактнее, но теряете контекст остальных процессов. PID нужного дочернего процесса (с --no-zygote) определяется через wmic process where "name='Bitwarden.exe'" get ProcessId,CommandLine.Первичный триаж -
strings -el (Unicode Little Endian) с поиском маркеров: email пользователя (логин Bitwarden), имя файла .kdbx (KeePass), фрагменты URL хранилища. Наличие маркеров подтверждает артефакты менеджера паролей в дампе и сужает область поиска.В Volatility 3 начните с
vol -f memdump.raw windows.pslist - найдите PID процесса менеджера и его дочерних процессов. Для Bitwarden Desktop ищите дочерний с --no-zygote в командной строке - именно он содержит чувствительные данные.YARA-паттерны для автоматизации поиска
Для автоматизации поиска мастер-пароля Bitwarden в дампе памяти - YARA-правило на основе hex-префикса из исследования Hexiosec:
Код:
rule bitwarden_master_pwd_heap {
meta:
description = "Bitwarden Desktop master pwd prefix"
cve = "CVE-2023-38840"
strings:
$prefix = { 04 00 00 00 ?? 00 00 00 01 ?? ?? ?? }
condition:
$prefix
}
$prefix должны содержать печатные символы длиной, равной значению пятого байта.Ограничение: паттерн подтверждён для Bitwarden Desktop до 2023.7.0. В пропатченных версиях мастер-пароль очищается при блокировке - этот метод неприменим.
Для KeePass стабильного hex-префикса нет. Эффективнее работает
strings -el с фильтрацией по окрестности маркеров KeePass - строки "KeePass", ".kdbx", "ProtectedBin".Detection: мониторинг credential extraction из RAM
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Чеклист hardening
- Обновить Bitwarden Desktop выше 2023.7.0 (версия 2023.7.0 уязвима) - закрывает CVE-2023-38840
- Настроить автоблокировку хранилища: таймаут 1–2 минуты неактивности
- Включить Sysmon EID 10 для Bitwarden.exe, KeePass.exe, 1Password.exe в конфигурации
- В EDR создать правило детекции ReadProcessMemory к процессам менеджеров паролей
- Заблокировать procdump.exe (LOLBAS: T1202), WinPmem, DumpIt на Windows-станциях через AppLocker/WDAC (исключение - IR-команда); в контексте дампа памяти менеджеров паролей релевантна T1555.005
- Для KeePass: минимизировать время жизни записей в буфере обмена (параметр ClipboardClearAfterSeconds)
- На Linux-хостах: установить
[URL='https://www.kernel.org/doc/html/latest/admin-guide/LSM/Yama.html']kernel.yama.ptrace_scope[/URL]=1- разрешает ptrace только к прямым потомкам процесса (parent->child), блокирует чтение памяти других процессов того же пользователя без CAP_SYS_PTRACE - Мониторить создание файлов .dmp/.raw/.mem в пользовательских каталогах
Даже после патча CVE-2023-38840 разблокированное хранилище держит все записи в открытом виде в памяти. Это не баг - это архитектурное ограничение. На Bitwarden Community точно сформулировали: если процесс скомпрометирован, ни один менеджер паролей не защитит секреты - кейлоггер, API-запросы через токен, ReadProcessMemory. Единственный реальный контроль - сократить окно: агрессивный таймаут блокировки, детекция чтения памяти, мониторинг инструментов дампинга.
В ряде инфраструктур, с которыми я работал, версию Bitwarden на станциях разработчиков вообще не контролировали - ставили что хотели, обновляли когда хотели (то есть никогда). Менеджеры паролей остаются слепым пятном корпоративной защиты, и пока SOC не начнёт мониторить эти процессы с тем же вниманием, что и LSASS, атакующие будут использовать этот разрыв. Проверьте свои правила корреляции прямо сейчас - есть ли там хоть одно упоминание Bitwarden.exe или KeePass.exe? Если ваш SOC строит детекцию credential access на стеке, отличном от Sysmon + ELK, - на codeby.net коллеги обсуждают адаптацию Sigma-правил под конкретные SIEM-платформы с примерами для разных стеков.
Последнее редактирование модератором: