曾有一段时间,管理员权限是 Windows 上攻击者的「终点」。以管理员身份加载内核驱动程序,转储 LSASS 进程的内存,就能拿到密码哈希和 Kerberos 票据。从那里起,不过是带着偷来的哈希走到另一台机器。
在 Credential Guard 正在运行的现行 Windows 11 上——从 22H2 起,在满足 Enterprise、Education 等许可证要求以及硬件要求的设备上,这是默认状态——那一套打法行不通。已经完全拿下内核的攻击者怎么搜内存,受保护域凭据的实际哈希也不会在「那个操作系统里面」被找到。若它没有在运行,旧的危险仍在,所以请连同后文的确认方法一起读。
那么它们在哪里?答案是「同一台 PC 里创建的另一个世界」。正如第1回所见,主机 Windows 运行在虚拟机监控程序之上的根分区里(「你的 Windows 实际在哪里运行?」)。本文从那里继续,追虚拟机监控程序在同一分区内部再画的一条边界。
第2回要回答的问题只有一个。
Windows 把管理员和内核都读不到的秘密放在哪里?
目标读者是在设置画面或故障排查案例中见过核心隔离、内存完整性、Credential Guard 等词、希望从机制上理解实体的开发者和运维人员。前提环境是 x64 Windows 10/11 或现行 Windows Server(与第1回一样,关于环和 SLAT 的讨论以 x64 为前提;Arm64 使用异常级别等不同机制)。所需背景是第1回讲过的分区和 SLAT 概念。难度为中级。目的是结构讲解,不是配置安全功能的操作手册。
1. 先说结论
Windows 增加了称为 VTL(Virtual Trust Level)的特权轴,并把秘密放在 VTL1。VTL1 的内存无法从运行在 VTL0 的普通内核读取。守住边界的不是内核自身,而是握着 SLAT 转换表的虚拟机监控程序。
这就是基于虚拟化的安全性(VBS)的骨架。VBS 用虚拟机监控程序创建隔离环境,并把安全功能安置在那里。它按「即便内核被攻破,隔离环境仍受保护」来设计。1
flowchart TB
accTitle: VBS 创建的两个世界
accDescr: VTL0 与 VTL1 坐在同一分区内;VTL0 持有普通内核和应用,VTL1 持有安全内核和隔离的安全功能,虚拟机监控程序守住边界
subgraph vtl0 ["VTL0(普通世界)"]
apps["应用(环 3)"]
ntk["NT 内核与驱动程序(环 0)"]
end
subgraph vtl1 ["VTL1(隔离世界)"]
ium["隔离的安全功能"]
sk["安全内核"]
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回出现。虚拟机监控程序以高于内核的特权运行,并很早就独占 CPU 内存访问权限(SLAT)的控制。虚拟机监控程序守卫的隔离区域,即使面对来自环 0(监督者模式)操作系统软件的访问也受保护。2
3. VSM 与 VTL ── 再加一条特权轴
3.1. 虚拟信任级别(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: 不仅内存,连 CPU 状态和中断也做成另一个世界,这是不留窥视孔的三件套。
若环(0 和 3)是分开「操作系统与应用」的轴,VTL 就是分开「普通世界与隔离世界」的第二轴。两轴正交,VTL1 内部也有内核模式和用户模式。
flowchart TB
accTitle: 环与 VTL 两轴造出的四个区域
accDescr: 环轴分开内核模式与用户模式,VTL 轴分开普通世界与隔离世界,组合产生四个区域:普通应用、NT 内核、IUM trustlet 和安全内核
subgraph ax0 ["VTL0(普通世界)"]
a0["环 3:普通应用"]
k0["环 0:NT 内核与驱动程序"]
end
subgraph ax1 ["VTL1(隔离世界)"]
a1["环 3:IUM(trustlet)"]
k1["环 0:安全内核"]
end
a0 --- k0
a1 --- k1
k0 ~~~ a1
图 4: 现在有两条特权轴,「是不是内核」和「是不是隔离世界」变成了分开的问题。
3.2. 边界的实体是 SLAT
第1回说过,把客户机物理地址(GPA)映射到实际 RAM(SPA)的第二级转换表——SLAT——由虚拟机监控程序持有。VSM 正是利用这一性质。VTL 隔离用 Hyper-V 虚拟机监控程序和 SLAT 创建。3
当 VTL1 声明「这块内存不要给 VTL0 看」时,虚拟机监控程序从 VTL0 的转换表里拿掉对该页的访问权限。此后,即便 VTL0 内核试图碰那个地址,也会在CPU 的地址转换阶段被拒绝。内核怎么改写自己的页表都没用。页表(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. 安全内核与 IUM
在 VTL1 里运行的不是普通 NT 内核,而是称为安全内核的小型内核。VTL1 的用户模式称为 IUM(Isolated User Mode),在那里运行的程序称为 trustlet(受信进程)。3
trustlet 不能像普通进程那样什么都做。大多数系统调用被编组到 VTL0 一侧的 NT 内核,工作在那里被请求。3 VTL1 不是「什么都能做的上层世界」;它被有意做小,作为存放秘密的保险库。能带进保险库的代码越少,攻击面越小。
flowchart TB
accTitle: trustlet 系统调用的流程
accDescr: VTL1 中的 trustlet 大多不自己处理系统调用;它把它们编组到 VTL0 的 NT 内核,只收回结果,从而让 VTL1 保持小
tl["Trustlet(VTL1 的 IUM)"] --> sc{"需要系统调用"}
sc -->|大多数情况| mar["请求被编组到 VTL0 的 NT 内核"]
mar --> res["只收回结果"]
res -.-> small["VTL1 保持小,缩小攻击面"]
图 6: 保险库没有自己的设施;它把杂务外包出去,只继续守卫秘密。
4. HVCI ── 在保险库里验证内核代码完整性
4.1. 在验证什么
坐在 VBS 上的第一个代表功能是内存完整性——HVCI(由虚拟机监控程序保护的代码完整性)。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{"隔离环境中的代码完整性验证"}
verify -->|通过| exec["允许为可执行页(禁止写入)"]
verify -->|失败| block["加载被阻止"]
block --> log["记录在 CodeIntegrity 运行日志(事件 ID 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 中确认(事件 ID 3087 是代表)。5
「启用内存完整性之后,某个外设不工作了」——很多情况下,那就是故障的真实身份。正确应对是更新到兼容 HVCI 的驱动程序;关闭内存完整性应被看成放弃整套保护的最后手段。若你从驱动程序开发的立场参与这次验证,也请看过滤器驱动程序文章(「Windows 迷你过滤器驱动程序」)。
flowchart TB
accTitle: 隔离内存完整性下外设停止工作的情况
accDescr: 在 CodeIntegrity 运行日志中识别被阻止的驱动程序;正确应对是更新到兼容 HVCI 的版本,没有则询问供应商,并把关闭当作不永久化的最后手段
sym["启用内存完整性后设备停止工作"] --> log2["在 CodeIntegrity 日志中识别被阻止的驱动程序"]
log2 --> upd{"有兼容 HVCI 的驱动程序吗?"}
upd -->|有| fix2["更新并在保持 HVCI 开启的情况下解决"]
upd -->|没有| ask2["向供应商要兼容版本"]
ask2 -.-> temp["关闭是最后手段,不是永久设置"]
图 10: 首先该看的不是设置画面而是日志,事件 ID 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 Ticket)——移到 LSAIso.exe,一个运行在 VTL1 的 IUM 中的 trustlet。6
- lsass.exe(VTL0)继续像以前一样作为身份验证处理的前台运行。
- 实际秘密由 LSAIso.exe(VTL1)持有,无法从 VTL0 访问。
- 两者经 RPC(Remote Procedure Call)通信。
- LSAIso 完全不承载设备驱动程序,只安置最少的已签名二进制。签名用 VBS 信任的证书验证。6
flowchart TB
accTitle: 启用 Credential Guard 时凭据坐在哪里
accDescr: VTL0 的 lsass 作为身份验证前台经 RPC 与 VTL1 的 LSAIso 通信;受保护域凭据的实际哈希和 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: 登录后实际秘密存放在 VTL1 的 LSAIso;每次需要身份验证时,VTL0 的 lsass 经 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 Ticket),以及作为域凭据保存的内容。以下不在范围内。8
- Kerberos 服务票据(TGT 受保护)
- 本地账户和 Microsoft 账户的凭据
- 键盘记录器对输入的窃取,以及物理攻击
- 使用 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 或 Win32_DeviceGuard 的 SecurityServicesRunning 判断。5
任务管理器「详细信息」选项卡上也有痕迹。VBS 正在运行的机器上会看到名为「Secure System」的进程。LsaIso.exe 是 Isolated LSA 服务寄宿在 VTL1 时出现的进程,在只启用 HVCI 的配置中通常不出现。不过进程的有无只是痕迹,因此是否运行 Credential Guard,仍按上面从 SecurityServicesRunning(是否包含 1)判断。两者都是从 VTL0 看见的、对应 VTL1 一侧世界的窗口。
flowchart TB
accTitle: 如何检查 VBS 相关功能在运行
accDescr: 通过查询 Win32_DeviceGuard 确认 VBS 在运行,从 SecurityServicesRunning 的值判断 Credential Guard 和 HVCI,驱动程序问题看 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 是假定已被攻破的纵深防御的一层,而且在客户端 PC 上才有效。在满足要求的 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(安全内核与 IUM)。2
- 边界的实体是 SLAT 内存访问保护,分区内的软件——包括内核——无法更改。2
- HVCI 在隔离环境中运行代码完整性验证,并强制「验证通过前不可执行」和「可执行页不可写」。4 代价是必须管理驱动程序兼容性。5
- Credential Guard 把域凭据的 NTLM 哈希和 TGT 隔离到 VTL1 的 LSAIso。从 Windows 11 22H2 起,在满足许可证要求(Enterprise、Education)和硬件要求的设备上默认启用(请连同运行状态检查一起使用)。67
- 可以从
Win32_DeviceGuard的 SecurityServicesRunning 确认运行状态(1 = Credential Guard,2 = HVCI)。9
续篇见第3回「数秒启动的虚拟机 ── WSL2、Windows Sandbox 与容器」。
至此我们从「隔离的强度」一侧看了虚拟化。最终回从相反的「轻」一侧看,追丢掉完整虚拟机重量的轻量虚拟机在哪里省。
相关文章
- Windows 虚拟化的深层(第1回) ── 你的 Windows 实际在哪里运行:虚拟机监控程序与分区
- Windows 内存的深层(第1回) ── 虚拟地址变成物理 RAM 的瞬间:页错误的全过程
- Windows I/O 的深层(第6回·最终回) ── 过滤器驱动程序与迷你过滤器:Procmon 与病毒扫描为何能够介入 I/O
- 解读 Windows 错误码 ── Win32 错误、HRESULT 与 NTSTATUS 的三层结构
相关咨询领域
小村软件有限公司承接 Windows 应用与安全功能的兼容性调查、驱动程序导致的故障分析,以及内部 PC 环境的技术验证。
参考链接
-
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 使用 Hyper-V 虚拟机监控程序和 SLAT 创建 VTL;安全内核和 IUM 在 VTL1 运行;trustlet 把系统调用编组到 VTL0 内核;以及 LSAIso 在 VTL1 运行并经 RPC 与 lsass 通信。 ↩ ↩2 ↩3
-
Microsoft Learn, Memory integrity and virtualization-based security. 关于内存完整性(HVCI)在隔离环境中运行代码完整性验证,以及内核内存页只有通过验证后才变为可执行、可执行页不变成可写。 ↩ ↩2 ↩3
-
Microsoft Learn, Memory integrity and VBS enablement. 关于在兼容硬件上全新安装 Windows 11 时内存完整性默认启用;在 msinfo32 和 Windows 安全应用中确认状态;以及经 CodeIntegrity 运行日志中的事件 ID 3087 确认被阻止的驱动程序。 ↩ ↩2 ↩3
-
Microsoft Learn, How Credential Guard works. 关于启用 Credential Guard 时 LSA 与 Isolated LSA 进程(LSAIso.exe)通信以存放秘密;存放的数据受 VBS 保护,操作系统其余部分无法访问;以及 Isolated LSA 进程完全不承载设备驱动程序,只安置最少的已验证签名的二进制。 ↩ ↩2 ↩3
-
Microsoft Learn, Credential Guard overview. 关于从 Windows 11 版本 22H2 起,在满足许可证、硬件和软件要求且未被显式禁用的设备上 Credential Guard 默认启用;符合资格的版本/许可证是 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. 关于如何经 Win32_DeviceGuard 类确认 VBS 和内存完整性的状态,以及 SecurityServicesRunning 值的含义(1 是 Credential Guard,2 是内存完整性)。 ↩ ↩2
相关文章
共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。
Windows 虚拟化的深层(第3回) ── 数秒启动的虚拟机:WSL2、Windows Sandbox 与容器为何这么轻
WSL2 和 Windows Sandbox 为何数秒启动、用起来这么轻?本文从动态基础映像、直接映射、动态内存分配讲到 Hyper-V 隔离容器,讲解其机制。
Windows 虚拟化的深层(第1回) ── 你的 Windows 实际在哪里运行:虚拟机监控程序与分区
启用 Hyper-V 后,主机 Windows 自身作为根分区运行在虚拟机监控程序之上。本文通过 VT-x、SLAT 与 VMBus 的角色讲解虚拟化的基础。
命名管道实务 ── 从设计到安全的 Windows 标准 IPC
以实务视角讲解 Windows 标准进程间通信——命名管道。根据一手资料整理字节模式与消息模式的选择、同时处理多客户端的服务器设计、ACL 与模拟的安全性,以及 .NET 的命名管道流。
Win32 线程池 API ── 用 CreateThreadpoolWork 实现不自建线程的并发
原生代码里是否到处调用 CreateThread?本文根据一手资料讲解 Vista 重新设计的 Win32 线程池 API——work、timer、wait、io 四种对象、清理组,以及回调中禁止做的事。
Windows的「内存使用量」究竟表示什么 ── 正确解读 Working Set・Private Bytes・Commit・页面文件
任务管理器中的内存、Working Set、Private Bytes、Commit并不是同一个值。本文讲解Windows虚拟内存与物理内存的关系、页面文件的作用,以及在排查内存不足或泄漏时应该关注的指标。
相关主题
与本文相近的主题页面。以本文为起点,可以进一步了解相关服务和其他文章。
Windows 技术主题
汇整 KomuraSoft LLC 关于 Windows 开发、故障调查与既有资产活用文章的主题中心。
常见问题
汇总了咨询这一主题时常见的问题。
- VBS(基于虚拟化的安全性)和核心隔离是同一回事吗?
- 严格说来不同。VBS 是用虚拟机监控程序创建隔离环境的基础技术,Windows 安全应用里的「核心隔离」是把建立在 VBS 之上的多项保护归在一起的画面名称。其中的代表是「内存完整性」,指的是 HVCI(由虚拟机监控程序保护的代码完整性)。各服务的运行状态应通过查询 Win32_DeviceGuard 确认,而不是看画面显示。
- 即便有管理员权限或从内核驱动程序,VTL1 内存真的读不到吗?
- 读不到。按 VTL 的内存访问保护由虚拟机监控程序针对分区的物理地址空间管理,分区内运行的软件无法更改它们。即便是在内核(环 0)运行的代码,也不允许从 VTL0 访问 VTL1 内存。
- 为什么启用内存完整性(HVCI)会让驱动程序停止工作?
- 在 HVCI 环境中,内核页只有通过完整性验证后才变为可执行,并且不允许写入可执行页。未签名的驱动程序,或改写可执行内存的旧设计驱动程序,无法满足这一约束,加载会被阻止。可以在 CodeIntegrity 运行日志(事件 ID 3087 等)中确认阻止。
- Credential Guard 保护什么,不保护什么?
- 它在隔离环境中保护域凭据的 NTLM 密码哈希、Kerberos TGT,以及应用作为域凭据保存的内容。Kerberos 服务票据、本地账户和 Microsoft 账户的凭据、键盘记录器对输入的窃取,以及物理攻击都不在范围内。
- 在哪里可以检查 VBS 是否在运行?
- 看 msinfo32 的「基于虚拟化的安全性」栏,或从 PowerShell 查询 root/Microsoft/Windows/DeviceGuard 命名空间中的 Win32_DeviceGuard 类。若 SecurityServicesRunning 包含 1,Credential Guard 在运行;若包含 2,内存完整性(HVCI)在运行。