Глубины виртуализации Windows (часть 2) — память, которую не видит даже ядро: как работают VBS, HVCI и Credential Guard
· Го Комура · Windows, Виртуализация, Безопасность, VBS, HVCI, Credential Guard
Было время, когда права администратора были «целью» для злоумышленника в Windows. Загрузить драйвер ядра как администратор, снять дамп памяти процесса LSASS — и у вас хеши паролей и билеты Kerberos. Дальше остаётся только пройти на другую машину украденными хешами.
На актуальном Windows 11 с работающим Credential Guard — состояние по умолчанию начиная с 22H2 на устройствах, которые удовлетворяют лицензионным требованиям вроде Enterprise и Education плюс аппаратным требованиям, — этот сценарий не работает. Злоумышленник, который полностью взял ядро, может сколько угодно искать в памяти, и фактические хеши защищённых учётных данных домена «внутри этой ОС» не находятся. Если не работает, старая опасность остаётся, поэтому читайте вместе со способами подтверждения дальше в статье.
Так где же они? Ответ — «другой мир, созданный внутри того же ПК». Как мы видели в части 1, хостовый Windows работает в корневом разделе поверх гипервизора («Где на самом деле работает ваш Windows?»). Эта статья продолжает оттуда и прослеживает ещё одну линию границы, которую гипервизор проводит внутри того же раздела.
Вопрос, на который отвечает часть 2, ровно один.
Куда Windows кладёт секреты, которые не может прочитать ни администратор, ни ядро?
Целевые читатели — разработчики и эксплуатационщики, которые видели слова вроде «изоляция ядра», «целостность памяти» и Credential Guard на экране настроек или в случае устранения неполадок и хотят понять суть с механизма. Предпосылки — x64 Windows 10/11 или актуальный Windows Server (как в части 1, разбор колец и SLAT предполагает x64; у Arm64 другой механизм, например уровни исключений). Нужный фон — понятия разделов и SLAT из части 1. Сложность — средняя. Цель — объяснение структуры, а не инструкция по настройке функций безопасности.
1. Сначала вывод
Windows добавила ось привилегий под названием VTL (Virtual Trust Level) и положила секреты в VTL1. Память в VTL1 нельзя прочитать из обычного ядра, которое работает в VTL0. Границу стережёт не само ядро, а гипервизор, который держит таблицы перевода SLAT.
Это скелет безопасности на основе виртуализации (VBS). VBS использует гипервизор, чтобы создать изолированную среду, и размещает там функции безопасности. Она спроектирована из допущения, что изолированная среда остаётся защищённой, даже если ядро скомпрометировано.1
flowchart TB
accTitle: Два мира, которые создаёт VBS
accDescr: VTL0 и VTL1 сидят внутри одного раздела; VTL0 держит обычное ядро и приложения, VTL1 держит Secure Kernel и изолированные функции безопасности, а гипервизор стережёт границу
subgraph vtl0 ["VTL0 (обычный мир)"]
apps["Приложения (кольцо 3)"]
ntk["Ядро NT и драйверы (кольцо 0)"]
end
subgraph vtl1 ["VTL1 (изолированный мир)"]
ium["Изолированные функции безопасности"]
sk["Secure Kernel"]
end
hv["Гипервизор (держит границу через SLAT)"] --- vtl0
hv --- vtl1
ntk -.->|Нельзя прочитать| ium
Рис. 1: Внутри одного Windows два мира, и ядро VTL0 не может обратиться к памяти VTL1.
Важно то, что это не «поднять ещё одну ВМ». VTL0 и VTL1 — внутри одного раздела, внутри одного Windows. Посмотрим по очереди, как это разделение реализовано.
2. Пределы модели колец — страж и охраняемое сидят на одной высоте
Традиционная безопасность Windows строилась на лестнице колец (уровней привилегий). Пользовательский режим (кольцо 3) стережёт режим ядра (кольцо 0). Так кто стережёт кольцо 0 — никто. Кольцо 0 — высшая привилегия.
У этой структуры две структурные слабости.
- Ядро не монолит. В кольце 0 работают не только сам Windows, но и большое число сторонних драйверов. Если у любого из них есть уязвимость, злоумышленник получает выполнение кода в кольце 0.
- Из кольца 0 видно всё. Как бы ни защищался процесс пользовательского режима вроде LSASS, его память свободна для чтения злоумышленнику, который взял ядро. И атрибуты защиты, и таблицы страниц управляются самим ядром.
flowchart TB
accTitle: Путь кражи учётных данных в традиционной модели колец
accDescr: Злоумышленник, который берёт кольцо 0 через уязвимый драйвер, может прочитать память процесса LSASS с полной властью ядра и получить хеши паролей
mal["Код злоумышленника"] -->|Эксплуатирует уязвимый драйвер| r0["Берёт управление кольцом 0"]
r0 --> readall["Может читать всю физическую память"]
readall --> lsass["Получает хеши из памяти LSASS"]
lsass --> lateral["Используется для бокового движения на другие машины"]
Рис. 2: Поскольку страж (ядро) и охраняемое (секреты) сидят на одной высоте, фундаментальная слабость в том, что если падает кольцо 0, падает всё.
Что нужно тогда — «место выше кольца 0». Это место уже появилось в части 1. Гипервизор работает на привилегии выше ядра и рано монополизирует управление разрешениями доступа к памяти ЦП (SLAT). Изолированная область, которую стережёт гипервизор, защищена даже от доступа со стороны ПО ОС в кольце 0 (режим супервизора).2
3. VSM и VTL — ещё одна ось привилегий
3.1. Virtual Trust Levels (VTL)
Семейство возможностей гипервизора, которые дают эту изоляцию, называется VSM (Virtual Secure Mode). VSM — основание для Device Guard, Credential Guard, виртуального TPM и подобного.2
Центральное понятие VSM — VTL (Virtual Trust Level). Ключевые пункты таковы.2
- VTL иерархичны, и чем выше номер, тем выше привилегия. VTL0 — самый низкий; VTL1 привилегированнее VTL0.
- Архитектурно определено до 16 уровней, но что сейчас реализовано — два: VTL0 и VTL1.
- У каждого VTL независимые защиты доступа к памяти. Этими защитами управляет гипервизор относительно физического адресного пространства раздела, поэтому системное ПО внутри раздела изменить их не может.
- У виртуального процессора отдельное состояние регистров и механизм прерываний на каждый VTL, и нижний VTL не может подсмотреть состояние верхнего VTL.
flowchart TB
accTitle: Три независимости, из которых складывается изоляция VTL
accDescr: Защиты доступа к памяти, состояние регистров виртуального процессора и механизм прерываний независимы на каждый VTL, и нижний VTL не может тронуть ни одно из них в верхнем VTL
vtl["Что независимо на каждый VTL"] --> m1["Защиты доступа к памяти"]
vtl --> m2["Состояние регистров вирт. процессора"]
vtl --> m3["Механизм прерываний"]
m1 -.-> rule["Нижний VTL не трогает верхний VTL"]
m2 -.-> rule
m3 -.-> rule
Рис. 3: Сделать отдельным миром не только память, но и состояние ЦП и прерывания — комплект из трёх частей, который не оставляет глазка.
Если кольца (0 и 3) — ось, которая разделяет «ОС и приложения», VTL — вторая ось, которая разделяет «обычный мир и изолированный мир». Две оси ортогональны, и внутри VTL1 тоже есть режим ядра и пользовательский режим.
flowchart TB
accTitle: Четыре области, которые создают две оси колец и VTL
accDescr: Ось колец разделяет режим ядра и пользовательский режим, ось VTL разделяет обычный мир и изолированный мир, и сочетание даёт четыре области: обычные приложения, ядро NT, трастлеты IUM и Secure Kernel
subgraph ax0 ["VTL0 (обычный мир)"]
a0["Кольцо 3: обычные приложения"]
k0["Кольцо 0: ядро NT и драйверы"]
end
subgraph ax1 ["VTL1 (изолированный мир)"]
a1["Кольцо 3: IUM (трастлеты)"]
k1["Кольцо 0: Secure Kernel"]
end
a0 --- k0
a1 --- k1
k0 ~~~ a1
Рис. 4: Осей привилегий теперь две, и «это ядро?» и «это изолированный мир?» стали отдельными вопросами.
3.2. Суть границы — SLAT
В части 1 мы говорили, что таблицы перевода второго уровня, которые отображают гостевой физический адрес (GPA) на фактическую ОЗУ (SPA), — SLAT — держит гипервизор. VSM использует ровно это свойство. Изоляция VTL создаётся с помощью гипервизора Hyper-V и SLAT.3
Когда VTL1 заявляет «эту память VTL0 показывать не надо», гипервизор снимает разрешение доступа к этой странице из таблиц перевода VTL0. С тех пор, даже если ядро VTL0 попытается тронуть этот адрес, ему отказывают на этапе перевода адреса ЦП. Бесполезно ядру как угодно переписывать свои таблицы страниц. Таблицы страниц (GVA→GPA) могут принадлежать ядру, но перевод дальше (GPA→SPA) и окончательное разрешение доступа принадлежат гипервизору.
flowchart TB
accTitle: Поток, которым доступ из VTL0 к памяти VTL1 отклоняется
accDescr: Когда ядро VTL0 пытается прочитать память VTL1, оно может пройти свою таблицу страниц, но защита доступа SLAT отказывает, и управление передаётся гипервизору
try["Ядро VTL0 пытается прочитать страницу VTL1"] --> pt["Проходит собственную таблицу страниц ядра"]
pt --> slat{"Защита доступа SLAT разрешает?"}
slat -->|Не разрешает| deny["Гипервизор вмешивается и отказывает"]
slat -->|Разрешает| ok["Обычный доступ к памяти"]
deny -.-> point["Защищено на слое, который ядро не может изменить"]
Рис. 5: Барьер сидит вне ядра, и защиты SLAT не может изменить ПО внутри раздела.
В части 1 серии про память мы писали, что «VAD, PTE и атрибуты защиты решают, разрешён ли доступ». В среде VBS это можно упорядочить так: после того как все они пройдены, всё ещё ждёт контрольная точка SLAT.
3.3. Secure Kernel и IUM
То, что работает внутри VTL1, — не обычное ядро NT, а маленькое ядро под названием Secure Kernel. Пользовательский режим в VTL1 называется IUM (Isolated User Mode), а программы, которые там работают, — трастлетами (доверенными процессами).3
Трастлет не может делать всё так, как обычный процесс. Большинство системных вызовов маршалируют ядру NT на стороне VTL0 и работу запрашивают там.3 VTL1 — не «верхний мир, который может всё»; он намеренно построен маленьким, как хранилище, которое держит секреты. Чем меньше кода можно внести в хранилище, тем меньше поверхность атаки.
flowchart TB
accTitle: Поток системных вызовов трастлета
accDescr: Трастлет в VTL1 большинство системных вызовов сам не обрабатывает; он маршалирует их ядру NT VTL0 и получает только результат, что держит VTL1 маленьким
tl["Трастлет (IUM в VTL1)"] --> sc{"Нужен системный вызов"}
sc -->|В большинстве случаев| mar["Запрос маршалируют ядру NT VTL0"]
mar --> res["Возвращается только результат"]
res -.-> small["VTL1 остаётся маленьким, сужая поверхность атаки"]
Рис. 6: У хранилища нет собственных удобств; оно отдаёт хозяйство на сторону и продолжает стеречь только секреты.
4. HVCI — проверка целостности кода ядра в хранилище
4.1. Что проверяют
Первая представительная функция, которая сидит на VBS, — целостность памяти, HVCI (hypervisor-protected code integrity). У Windows есть механизм целостности кода, который инспектирует драйверы и двоичные файлы режима ядра до старта и не загружает неподписанные или недоверенные. HVCI выполняет эту проверку внутри изолированной среды VBS.1
Причина перенести саму логику проверки в VTL1 — ровно слабость раздела 2. Если код проверки сидит внутри ядра VTL0, злоумышленник, который взял ядро, может подменить проверку. Если она в VTL1, подменяющая рука до неё не достаёт.
flowchart TB
accTitle: Разница от того, где живёт код проверки
accDescr: Если код проверки сидит внутри ядра VTL0, его можно отключить, взяв ядро, но если он в VTL1, даже злоумышленник, который взял ядро, не достаёт до него, и проверка защищена
atk["Злоумышленник, который взял ядро"] --> q{"Где живёт проверка целостности кода?"}
q -->|"Внутри ядра VTL0 (классика)"| bad["Логику проверки можно подменить"]
q -->|"Изолированная среда в VTL1 (HVCI)"| good["Подмена вне досягаемости"]
bad --> res1["Неподписанный код может работать в ядре"]
good --> res2["Проверка продолжает работать после компрометации ядра"]
Рис. 7: Не кладите контрольную точку внутрь стороны, которую могут пробить, — это перенесение логики проверки и есть суть HVCI.
4.2. Правила для исполняемых страниц
Эффект HVCI не ограничивается «инспекцией при старте». Он также ограничивает выделение памяти ядра.4
- Страница ядра становится исполняемой только после того, как прошла проверку целостности кода.
- Исполняемая страница не становится записываемой (так называемый W^X).
Когда эти два на месте, даже если уязвимость вроде переполнения буфера позволяет переписать память ядра, переписанное содержимое в выполнение не поставить. Исполняемую страницу нельзя переписать, а страницу, которую можно переписать, нельзя выполнить.4 Окончательная опора разрешения на выполнение — право выполнения на стороне SLAT, которым ядро VTL0 манипулировать не может.
flowchart TB
accTitle: Пока страница ядра не станет исполняемой в среде HVCI
accDescr: Запрос загрузки драйвера получает проверку целостности кода в изолированной среде VBS; если проходит, разрешается как исполняемая незаписываемая страница, а если нет — блокируется и записывается в журнал CodeIntegrity
load["Запрос выполнить код ядра"] --> verify{"Проверка целостности в VTL1?"}
verify -->|Проходит| exec["Исполняемая (без записи)"]
verify -->|Не проходит| block["Загрузка блокируется"]
block --> log["CodeIntegrity 3087"]
exec -.-> wx["Запись ≠ исполнение"]
Рис. 8: Проверка правила, которое не даёт сосуществовать выполнению и записи, делается на стороне VTL1, и ядро VTL0 не может его опрокинуть.
Проследить это с точки зрения злоумышленника делает ясным, как правило действует.
flowchart TB
accTitle: Поток, которым внедрение кода проваливается в среде HVCI
accDescr: Даже если уязвимость позволяет переписать память ядра, страница, в которую удалось записать, неисполняема, а исполняемую страницу переписать нельзя с самого начала, поэтому внедрённый код в выполнение не поставить
inj["Попытаться подменить память ядра через уязвимость"] --> which{"Какая страница цель?"}
which -->|Записываемая страница| wok["Запись удаётся"]
which -->|Исполняемая страница| xfail["Сама запись невозможна"]
wok --> nx["Но эта страница неисполняема"]
nx --> dead["Внедрённый код нельзя выполнить"]
xfail --> dead
Рис. 9: Смысл не скрещивать записываемые страницы с исполняемыми в том, что с какого входа ни зайди, упираешься в тупик.
4.3. Цена в совместимости драйверов
Это правило сталкивается с драйверами старой конструкции. Те, что переписывают свой код во время выполнения, не имеют подписи или требуют память, одновременно исполняемую и записываемую, — такие драйверы в среде HVCI загрузить нельзя. Факт блокировки можно подтвердить в средстве просмотра событий в Applications and Services Logs\Microsoft\Windows\CodeIntegrity\Operational (представительный идентификатор события — 3087).5
«После того как я включил целостность памяти, периферия перестала работать» — во многих случаях это и есть настоящая личность неприятности. Правильный ответ — обновить до драйвера, совместимого с HVCI; отключение целостности памяти стоит считать крайней мерой, которая сдаёт защиту целиком. Если вы участвуете в этой проверке со стороны разработки драйверов, см. также статью о драйверах-фильтрах («Минифильтры Windows»).
flowchart TB
accTitle: Изоляция случая, когда периферия перестаёт работать при целостности памяти
accDescr: Определите заблокированный драйвер в журнале CodeIntegrity Operational; правильный ответ — обновить до версии, совместимой с HVCI, спросить поставщика, если её нет, и считать отключение крайней мерой, которую не делают постоянной
sym["Устройство перестаёт работать после включения целостности памяти"] --> log2["Определить заблокированный драйвер в журнале CodeIntegrity"]
log2 --> upd{"Есть драйвер, совместимый с HVCI?"}
upd -->|Да| fix2["Обновить и решить, оставив HVCI включённым"]
upd -->|Нет| ask2["Попросить у поставщика совместимую версию"]
ask2 -.-> temp["Отключение — крайняя мера, не постоянная настройка"]
Рис. 10: Первое, на что смотреть, — не экран настроек, а журнал, и идентификатор события 3087 знает, кто заблокировал загрузку.
5. Credential Guard — хеши внутри LSAIso
5.1. LSASS и LSAIso
Вторая представительная функция, которая сидит на VBS, — ответ на загадку вступления: Credential Guard.
Традиционный Windows держал хеши NTLM и билеты Kerberos в памяти процесса LSA (lsass.exe). Когда Credential Guard включён, хранение защищённых секретов среди них — хешей NTLM учётных данных домена и Kerberos TGT (Ticket Granting Tickets) — переезжает в LSAIso.exe, трастлет, который работает в IUM в VTL1.6
- lsass.exe (VTL0) продолжает работать как приёмная обработки аутентификации, как прежде.
- Фактические секреты держит LSAIso.exe (VTL1), и из VTL0 к ним обратиться нельзя.
- Двое общаются через RPC (Remote Procedure Call).
- LSAIso не размещает драйверы устройств вовсе и держит только минимум подписанных двоичных файлов. Подписи проверяют сертификатом, которому доверяет VBS.6
flowchart TB
accTitle: Где лежат учётные данные, когда Credential Guard включён
accDescr: lsass в VTL0 общается с LSAIso в VTL1 через RPC как приёмная аутентификации; фактические хеши и TGT защищённых учётных данных домена держит LSAIso, поэтому злоумышленник, который получает права администратора в VTL0 и снимает дамп lsass, всё равно не получает защищённую суть
subgraph v0 ["VTL0"]
lsassP["lsass.exe (приёмная аутентификации)"]
att["Злоумышленник (права администратора)"]
end
subgraph v1 ["VTL1"]
iso["LSAIso.exe (хранилище секретов)"]
end
lsassP <-->|RPC| iso
att -->|Дамп памяти| lsassP
att -.->|Не достаёт| iso
Рис. 11: Поскольку приёмную и хранилище разделили, дамп lsass больше не даёт фактические хеши защищённых учётных данных домена.
Начиная с Windows 11 версии 22H2 на устройствах, которые удовлетворяют лицензионным требованиям (Enterprise E3/E5, Education A3/A5) и аппаратным требованиям, VBS и Credential Guard включены по умолчанию. В редакциях вроде Pro Credential Guard автоматически не включается (есть исключения, например когда машину, включённую по подходящей лицензии, позже понижают).7 «Сценарий больше не работает» во вступлении — не история об особом дополнительном продукте; это стандартное состояние актуального Windows на целевых редакциях.
flowchart TB
accTitle: Поток учётных данных от входа до аутентификации
accDescr: После входа фактические секреты хранятся в LSAIso в VTL1; каждый раз, когда нужна аутентификация, lsass в VTL0 запрашивает вычисление через RPC, и в VTL0 возвращается только результат обработки аутентификации, без самих защищённых долговременных секретов
signin["Пользователь входит"] --> front["lsass обрабатывает как приёмная"]
front --> store["Фактические секреты хранятся в LSAIso"]
auth["Последующие запросы аутентификации"] --> front
front -->|"Запросить вычисление через RPC"| store
store -->|"Возвращает результат (секрет не возвращает)"| front
Рис. 12: Сами защищённые долговременные секреты хранилище не покидают; в VTL0 возвращается результат обработки аутентификации, например билет.
5.2. Точно знать, что не защищено
Credential Guard — не щит на все случаи. Что защищено — хеши NTLM учётных данных домена, Kerberos TGT (Ticket Granting Tickets) и то, что сохранено как учётные данные домена. Следующее — вне области.8
- Служебные билеты Kerberos (TGT защищены)
- Учётные данные локальных учётных записей и учётных записей Майкрософт
- Кража ввода кейлоггером и физические атаки
- Учётные данные на путях, которые используют NTLMv1, MS-CHAPv2, Digest или CredSSP
- Внутренности стороннего ПО, которое само управляет учётными данными
Кроме того, когда Credential Guard включён, NTLMv1, неограниченное делегирование Kerberos и подобное становятся непригодны, поэтому бизнес-системам, которые зависят от устаревшей аутентификации, нужна проверка совместимости.8 Не «включили — и готово», а понять, что внутри и вне оборонительного диапазона, и остальное закрыть другими контролями — правильный способ использования на практике.
flowchart TB
accTitle: Оборонительный диапазон Credential Guard
accDescr: Хеши NTLM домена и TGT, а также сохранённые учётные данные домена защищены, тогда как служебные билеты, локальные учётные записи, кейлоггеры, физические атаки и учётные данные, которые приложение хранит само, — вне области
scope{"По какую сторону границы защиты этот секрет?"} --> inA["Хеши NTLM домена и TGT"]
scope --> outA["Служебные билеты и локальные учётные записи"]
inA --> prot["Защищено в LSAIso"]
outA --> unprot["Не защищено (нужны другие контроли)"]
unprot -.-> outB["Нажатия клавиш, физ. атаки и частные хранилища приложений тоже вне области"]
Рис. 13: Оборонительный диапазон проведён чёткой линией, а внешнюю сторону линии закрывают многофакторной аутентификацией и проектированием на стороне приложения.
6. Посмотрите сами
Состояние работы VBS и каждой функции можно подтвердить на своей машине.
Get-CimInstance -Namespace root/Microsoft/Windows/DeviceGuard `
-ClassName Win32_DeviceGuard |
Select-Object VirtualizationBasedSecurityStatus,
SecurityServicesConfigured,
SecurityServicesRunning
Как читать — так.9
- Если
VirtualizationBasedSecurityStatusравен 2, VBS включена и работает. - Если
SecurityServicesRunningсодержит 1, работает Credential Guard; если содержит 2, работает целостность памяти (HVCI).
Чтобы подтвердить состояние работы в графическом интерфейсе, смотрите поле «Безопасность на основе виртуализации» в msinfo32 (перечислены службы, которые работают, например «Hypervisor enforced Code Integrity»). Переключатель «Целостность памяти» в «Безопасность устройства > Изоляция ядра» в приложении «Безопасность Windows» — экран, который отражает настройки; он может выглядеть включённым, пока HVCI на самом деле не работает — ожидание перезагрузки сразу после включения или проблема совместимости при старте, — поэтому работает ли она, судите по msinfo32 или по SecurityServicesRunning у Win32_DeviceGuard.5
Есть и след на вкладке «Подробности» Диспетчера задач. На машине, где VBS работает, вы увидите процесс под названием «Secure System». LsaIso.exe — процесс, который появляется, когда служба Isolated LSA размещена в VTL1, и обычно не появляется в конфигурации, где включён только HVCI. Наличие или отсутствие процесса — лишь след, поэтому работает ли Credential Guard, судите по SecurityServicesRunning (содержит ли 1), как выше. Оба — окна, видимые из VTL0, которые соответствуют миру стороны VTL1.
flowchart TB
accTitle: Как проверить, что функции, связанные с VBS, работают
accDescr: Подтвердите, что VBS работает, запросом Win32_DeviceGuard, судите Credential Guard и HVCI по значениям SecurityServicesRunning и смотрите журнал CodeIntegrity при проблемах с драйверами
q0["Win32_DeviceGuard"] --> q1{"Состояние VBS 2?"}
q1 -->|Нет| off["VBS не работает"]
q1 -->|Да| q2{"Содержит 1 или 2?"}
q2 -->|1| cg["Credential Guard вкл."]
q2 -->|2| hvciR["HVCI вкл."]
hvciR -.-> ev["CodeIntegrity 3087"]
Рис. 14: Подтверждение состояния идёт в три этапа: сама VBS, каждая служба поверх неё и журнал, когда возникает проблема.
7. Три прочтения, которых стоит избегать на практике
7.1. «Защитить права администратора достаточно. VBS — история серверной стороны»
То, чему Credential Guard мешает, — распространение ущерба после того, как права администратора уже взяты (извлечение хешей и боковое движение). Иными словами, VBS — один слой глубокой обороны, который исходит из компрометации, и эффективен он именно на клиентских ПК. На Windows 11, который удовлетворяет требованиям, включение по умолчанию — стандарт, поэтому правильная поза — не «это к нам не относится», а «управляйте совместимостью из допущения, что уже работает».
flowchart TB
accTitle: Этапы компрометации и где действует VBS
accDescr: Начальный доступ закрывают другие контроли вроде многофакторной аутентификации и обучения; HVCI блокирует внедрение кода в ядро после повышения прав; Credential Guard блокирует кражу защищённых секретов домена и боковое движение, но не достаёт до секретов вне своей области
s1["Начальный доступ (фишинг и подобное)"] --> s2["Повышение прав"]
s2 --> s3["Внедрение кода в ядро"]
s3 --> s4["Кража защищённых секретов домена и боковое движение"]
s1 -.-> d1["Это закрывают MFA, обучение и EDR"]
s3 -.-> d2["HVCI блокирует этот шаг"]
s4 -.-> d3["Credential Guard блокирует это (только защищённые секреты)"]
Рис. 15: VBS — не технология «не пускайте их»; это технология «не дайте им победить, когда они уже внутри», и этап, который она стережёт, другой.
7.2. «Если целостность памяти вызывает проблему, просто выключите»
Выключение на время заставит вещи работать, но снимает барьер против внедрения кода в ядро целиком. Правильный ответ — сначала определить заблокированный драйвер в журнале CodeIntegrity и применить обновлённую версию поставщика. Даже если временно отключаете для проверки, рекомендуем эксплуатацию, которая не делает это постоянной настройкой.
7.3. «С Credential Guard пароли украсть нельзя»
Это самоуверенность от смешения оборонительного диапазона. Служебные билеты, локальные учётные записи, сами нажатия клавиш и учётные данные, которые приложение хранит само, — вне области.8 Фишинг и кейлоггеры нуждаются в других контролях (многофакторная аутентификация, Windows Hello и ревью управления учётными данными на стороне приложения).
8. Итоги
- VBS использует гипервизор, чтобы создать изолированную среду, и защищает функции безопасности из допущения, что ядро может быть скомпрометировано.1
- Единица изоляции — VTL; сейчас реализованы два уровня: VTL0 (обычный мир) и VTL1 (Secure Kernel и IUM).2
- Суть границы — защита доступа к памяти SLAT, которую ПО внутри раздела — включая ядро — изменить не может.2
- HVCI выполняет проверку целостности кода в изолированной среде и принуждает «не исполняемо, пока проверка не прошла» и «исполняемая страница не записываема».4 Цена — нужно управлять совместимостью драйверов.5
- Credential Guard изолирует хеши NTLM учётных данных домена и TGT в LSAIso в VTL1. Начиная с Windows 11 22H2 включён по умолчанию на устройствах, которые удовлетворяют лицензионным требованиям (Enterprise, Education) и аппаратным требованиям (используйте вместе с проверкой состояния работы).67
- Состояние работы можно подтвердить по SecurityServicesRunning у
Win32_DeviceGuard(1 = Credential Guard, 2 = HVCI).9
Продолжение в части 3, «Виртуальные машины, которые загружаются за секунды — WSL2, Windows Sandbox и контейнеры».
До сих пор мы смотрели на виртуализацию со стороны «силы изоляции». Последняя часть смотрит с противоположной стороны «лёгкости» и прослеживает, где лёгкие ВМ, которые сбросили вес полной ВМ, срезают углы.
Похожие статьи
- Глубины виртуализации Windows (часть 1) — где на самом деле работает ваш Windows? Гипервизор и разделы
- Глубины памяти Windows (часть 1) — момент, когда виртуальный адрес становится физической ОЗУ: ошибка страницы от начала до конца
- Глубины I/O в Windows (часть 6, финал) — драйверы-фильтры и минифильтры: почему Procmon и антивирусные сканеры могут перехватывать ввод-вывод
- Расшифровка кодов ошибок Windows — трёхслойная структура ошибок Win32, HRESULT и NTSTATUS
Смежные области консультирования
KomuraSoft LLC занимается расследованиями совместимости Windows-приложений и функций безопасности, анализом отказов, вызванных драйверами, и технической проверкой внутренних сред ПК.
- Разработка Windows-приложений
- Исследование дефектов и анализ первопричин
- Поддержка использования существующих активов и миграции
- Связаться с нами
Справочные ссылки
-
Microsoft Learn, Virtualization-based Security (VBS). О том, что VBS использует аппаратную виртуализацию и гипервизор Windows, чтобы создать изолированную среду, и относится к ней как к корню доверия ОС из допущения, что ядро может быть скомпрометировано; целостность памяти выполняет проверку целостности кода режима ядра внутри этой изолированной среды; и SLAT — жёсткое требование для VBS. ↩ ↩2 ↩3
-
Microsoft Learn, Virtual Secure Mode. О том, что VSM — основание для Device Guard, Credential Guard, виртуального TPM и подобного; доступ к изолированным областям контролируется только через гипервизор и защищён даже от ПО ОС в кольце 0; VTL иерархичны, из максимума 16 уровней реализованы 2; и защиты доступа к памяти по VTL системное ПО внутри раздела изменить не может. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Isolated User Mode (IUM) Processes. О том, что VSM создаёт VTL с помощью гипервизора Hyper-V и SLAT; Secure Kernel и IUM работают в VTL1; трастлеты маршалируют системные вызовы ядру VTL0; и LSAIso работает в VTL1 и общается с lsass через RPC. ↩ ↩2 ↩3
-
Microsoft Learn, Memory integrity and virtualization-based security. О том, что целостность памяти (HVCI) выполняет проверку целостности кода в изолированной среде, и о том, что страницы памяти ядра становятся исполняемыми только после прохождения проверки, а исполняемые страницы не становятся записываемыми. ↩ ↩2 ↩3
-
Microsoft Learn, Memory integrity and VBS enablement. О том, что целостность памяти включена по умолчанию на чистой установке Windows 11, если оборудование совместимо; о подтверждении состояния в msinfo32 и приложении «Безопасность Windows»; и о подтверждении заблокированного драйвера через идентификатор события 3087 в журнале CodeIntegrity Operational. ↩ ↩2 ↩3
-
Microsoft Learn, How Credential Guard works. О том, что LSA общается с процессом Isolated LSA (LSAIso.exe), чтобы хранить секреты, когда Credential Guard включён; хранимые данные защищены VBS и недоступны из остальной ОС; и процесс Isolated LSA не размещает драйверы устройств и держит только минимум двоичных файлов с проверенной подписью. ↩ ↩2 ↩3
-
Microsoft Learn, Credential Guard overview. О том, что Credential Guard включён по умолчанию начиная с Windows 11 версии 22H2 на устройствах, которые удовлетворяют лицензионным, аппаратным и программным требованиям и не были явно отключены; подходящие редакции/лицензии — Enterprise (E3/E5) и Education (A3/A5), Pro вне области; и машина Pro, которая ранее была включена по подходящей лицензии, остаётся целью включения по умолчанию после понижения. ↩ ↩2
-
Microsoft Learn, Credential Guard protection limits. О том, что служебные билеты, локальные учётные записи, кейлоггеры, физические атаки и подобное вне области защиты Credential Guard; TGT защищены, а служебные билеты — нет; и NTLMv1 и неограниченное делегирование становятся непригодны, когда он включён. ↩ ↩2 ↩3
-
Microsoft Learn, Enable virtualization-based protection of code integrity. О том, как подтвердить состояние VBS и целостности памяти через класс Win32_DeviceGuard, и о значении значений SecurityServicesRunning (1 — Credential Guard, 2 — целостность памяти). ↩ ↩2
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
Глубины виртуализации Windows (часть 3) — виртуальные машины, которые загружаются за секунды: почему WSL2, Windows Sandbox и контейнеры такие лёгкие
Почему WSL2 и Windows Sandbox стартуют за секунды и ощущаются такими лёгкими? Статья разбирает механизмы — от динамического базового обра...
Глубины виртуализации Windows (часть 1) — где на самом деле работает ваш Windows? Гипервизор и разделы
Когда включают Hyper-V, сам хостовый Windows работает поверх гипервизора как корневой раздел. Статья разбирает основы виртуализации через...
Именованные каналы на практике — стандартный IPC Windows: от проектирования до безопасности
Практическое руководство по именованным каналам — стандартному межпроцессному взаимодействию Windows. Статья по первичным источникам разб...
Политика выполнения PowerShell и подпись скриптов — практическое руководство, как перестать «затыкать дыры» параметром Bypass
Политика выполнения PowerShell — это «не граница безопасности, а защитный механизм». Разбираем различия между RemoteSigned и другими поли...
Встраиваем аутентификацию Entra ID в приложения WinForms/WPF — практическая архитектура на MSAL.NET и брокере WAM
Разбираем порядок встраивания аутентификации Entra ID в десктопные приложения WinForms/WPF: концепцию публичного клиента, регистрацию при...
Связанные темы
Эти страницы показывают тему статьи в более широком контексте услуг и решений.
Технические темы Windows
Раздел о разработке Windows, расследовании сбоев и использовании существующих активов.
Услуги по этой теме
Статья напрямую связана со следующими услугами.
Разработка приложений для Windows
Бизнес-приложения, интеграция оборудования и средства связи — от требований до разработки.
Частые вопросы
Вопросы, которые часто возникают при консультациях по теме статьи.
- Одно и то же ли VBS (безопасность на основе виртуализации) и изоляция ядра?
- Строго говоря, нет. VBS — базовая технология, которая создаёт изолированную среду гипервизором, а «Изоляция ядра» в приложении «Безопасность Windows» — название экрана, который группирует несколько защит, построенных на VBS. Представительная из них — «Целостность памяти», которая относится к HVCI (целостность кода, защищённая гипервизором). Состояние работы каждой службы подтверждайте запросом Win32_DeviceGuard, а не по отображению экрана.
- Неужели память VTL1 действительно нельзя прочитать даже с правами администратора или из драйвера ядра?
- Нельзя. Защиты доступа к памяти по VTL управляет гипервизор относительно физического адресного пространства раздела, и программное обеспечение, которое работает внутри раздела, изменить их не может. Даже коду, который выполняется в ядре (кольцо 0), доступ к памяти VTL1 из VTL0 не разрешён.
- Почему включение целостности памяти (HVCI) может остановить работу драйвера?
- В среде HVCI страница ядра становится исполняемой только после того, как прошла проверку целостности, а запись в исполняемые страницы не разрешена. Неподписанный драйвер или драйвер старой конструкции, который переписывает исполняемую память, не может удовлетворить это ограничение, и его загрузка блокируется. Блокировку можно подтвердить в журнале CodeIntegrity Operational (идентификатор события 3087 и подобное).
- Что защищает Credential Guard и что не защищает?
- Он защищает хеши паролей NTLM учётных данных домена, Kerberos TGT и то, что приложение сохранило как учётные данные домена, в изолированной среде. Служебные билеты Kerberos, учётные данные локальных учётных записей и учётных записей Майкрософт, кража ввода кейлоггером и физические атаки — вне области.
- Где проверить, работает ли VBS?
- Смотрите поле «Безопасность на основе виртуализации» в msinfo32 или запросите класс Win32_DeviceGuard в пространстве имён root/Microsoft/Windows/DeviceGuard из PowerShell. Если SecurityServicesRunning содержит 1, работает Credential Guard; если содержит 2, работает целостность памяти (HVCI).
Об авторе
Страница с профилем автора статьи.
Го Комура
Представитель KomuraSoft LLC
Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.