GreatXML 深度剖析:当 Windows 恢复环境成为加密的「阿喀琉斯之踵」——从 Defender 离线扫描到 BitLocker 绕过的攻击链完全拆解(2026)
一、背景:一场针对微软防线体系的「连环爆破」
2026年6月10日,就在微软6月补丁日(Patch Tuesday)关闭窗口后数小时,化名 Nightmare Eclipse(又名 Chaotic Eclipse / MSNightmare)的安全研究员在 GitHub 上公开了名为 GreatXML 的概念验证代码(PoC),声称可以通过一条精心构造的攻击链绕过 Windows BitLocker 全盘加密。
这已经是该研究员自2026年4月以来公开的第八个零日漏洞。同一天,他还发布了另一个名为 RoguePlanet 的 Defender 权限提升漏洞。两个漏洞联合出击——一个拿到 SYSTEM 最高权限,一个绕过磁盘加密——构成了对 Windows 端点安全的完整威胁。
GreatXML 的核心发现令人不安:BitLocker 的加密边界并非我们想象的那样坚固。当 Windows 恢复环境(WinRE)与 Defender 离线扫描的特殊状态相遇时,一个合法的部署机制(unattend.xml)竟然能成为打开加密保险箱的钥匙。
本文将从攻击原理、技术原语、代码实战、检测防御四个维度,完整拆解 GreatXML 的攻防逻辑。
二、攻击面全景:WinRE、Defender 离线扫描与 BitLocker 的「三角关系」
2.1 BitLocker 的安全承诺
BitLocker 是微软提供的全卷加密(FVE)解决方案,其核心安全模型建立在一个关键假设之上:只有在可信的启动路径中,才会释放加密密钥。
在 TPM-Only 配置下,这个「可信启动路径」由 TPM 芯片保证——如果启动链未被篡改,TPM 自动释放密钥,用户无感登录即可访问数据。这是最便捷的配置,也是企业环境中最常见的部署方式。
微软的官方文档明确承诺:
"在恢复环境中,除非用户提供密钥,否则加密文件不应可访问。"
GreatXML 正是在挑战这个承诺。
2.2 WinRE:运行在加密边界之外的「瑞士军刀」
Windows 恢复环境(Windows Recovery Environment,WinRE)是微软为系统修复设计的预启动环境,基于 Windows PE 构建。它默认存在于 Windows 10、Windows 11 和 Windows Server 2016 及更高版本中。
WinRE 的启动方式包括:
- Shift + Restart(从登录界面)
- 高级启动选项(从 Windows 设置)
- 恢复介质(USB/DVD)
- 自动启动(系统启动失败时)
关键在于:WinRE 运行在正常的用户会话之外。此时端点安全控制、企业遥测、审计日志等机制可能尚未完全激活。但 WinRE 又需要足够的权限来修复系统——包括访问加密卷。
这就是矛盾的根源:一个拥有加密卷访问权限的环境,运行在安全控制的盲区。
2.3 Defender 离线扫描:一个「状态残留」的安全隐患
Windows Defender 的离线扫描功能(Start-MpWDOScan)会将机器引导到一个特殊的 WinRE 模式来执行恶意软件扫描。扫描完成后,系统会恢复正常的启动流程。
但关键问题在于:离线扫描会在恢复分区留下特定的配置状态。即使扫描已经完成,这些状态的残留可能被后续的启动流程所利用。
正常 Windows → 启动离线扫描 → 重启进入 WinRE 离线扫描模式 → 扫描完成 →
重启回 Windows → 但恢复分区的状态已被修改
这个「状态残留」正是 GreatXML 攻击链的入口。
2.4 unattend.xml:一个被「错放」的合法工具
unattend.xml(无人值守应答文件)是微软提供的 Windows 部署自动化机制。它原本是为 OEM 工厂流水线设计的,允许自动完成 Windows 安装和配置。
unattend.xml 的合法功能包括:
- 自动创建用户账户
- 安装设备驱动
- 执行命令行脚本
- 配置网络设置
- 应用安全策略
问题不在于 unattend.xml 本身——它是微软官方支持的标准机制。问题在于它在错误的时间、错误的地点、被错误的人利用。
当这个部署机制在 WinRE 的恢复路径中被执行时,它携带的命令执行能力就直接转化为对加密卷的访问权限。
三、攻击链深度拆解
3.1 前置条件
根据 PoC 的 README 描述,触发攻击需要以下前置条件:
Defender 离线扫描已被触发过至少一次。这是核心前置条件——离线扫描在恢复分区留下的特殊状态是攻击链的关键环节。
物理访问权限。攻击者需要能够物理接触目标机器,写入恢复分区。
TPM-Only 配置。目标机器使用纯 TPM 模式的 BitLocker,没有额外的 PIN 或 USB 密钥。
值得注意的是,如果 Defender 离线扫描从未被触发过,攻击者需要:
- 以某种方式登录系统并触发离线扫描,或者
- 找到其他方法将 WinRE 引导到离线扫描状态
PoC 作者明确表示这第二种路径是「推测性的」,并非已验证的步骤。
3.2 完整攻击流程
步骤 1: 物理写入
┌─────────────────────────────────────────────────┐
│ 攻击者将以下文件写入恢复分区根目录: │
│ ├── unattend.xml(包含命令执行逻辑的应答文件) │
│ └── Recovery/WindowsRE/(恢复环境配置目录) │
└─────────────────────────────────────────────────┘
│
▼
步骤 2: 重启进入 WinRE
┌─────────────────────────────────────────────────┐
│ 通过 Shift+Restart、高级启动选项或恢复介质 │
│ 将机器引导至 WinRE │
│ (由于离线扫描状态残留,恢复环境处于特殊状态) │
└─────────────────────────────────────────────────┘
│
▼
步骤 3: unattend.xml 被处理
┌─────────────────────────────────────────────────┐
│ WinRE 中的 Windows 安装/恢复逻辑 │
│ 发现并处理攻击者放置的 unattend.xml │
│ 执行其中嵌入的命令(写入脚本 → 启动 conhost.exe)│
└─────────────────────────────────────────────────┘
│
▼
步骤 4: 获得加密卷访问
┌─────────────────────────────────────────────────┐
│ 攻击者获得一个命令行 Shell │
│ 此 Shell 具有对 BitLocker 加密卷的 │
│ 无限制访问权限 │
│ BitLocker 仍然报告卷处于保护状态 │
└─────────────────────────────────────────────────┘
3.3 unattend.xml 的技术分析
根据安全研究员的防御性分析,PoC 中包含的 unattend.xml 不是一个正常的加固配置文件,而是包含以下行为:
- 写入并启动 PE 命令脚本
- 启动 conhost.exe(命令行宿主进程)
- 使用 PowerShell 安装脚本逻辑
以下是 unattend.xml 的典型结构(简化示意,不含任何实际利用代码):
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend"
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
<settings pass="specialize">
<component name="Microsoft-Windows-Shell-Setup"
processorArchitecture="amd64"
language="neutral"
publicKeyToken="31bf3856ad364e35"
versionScope="nonSxS">
<!-- 正常的无人值守配置:计算机名、用户等 -->
<ComputerName>RECOVERY-PC</ComputerName>
<!-- 关键部分:RunSynchronous 命令执行 -->
<RunSynchronous>
<RunSynchronousCommand wcm:action="add">
<Order>1</Order>
<Path>cmd.exe /c write_payload.bat</Path>
<Description>Setup Script Execution</Description>
<WillReboot>false</WillReboot>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>2</Order>
<!-- 启动命令行宿主 -->
<Path>conhost.exe</Path>
<Description>Console Host Launch</Description>
</RunSynchronousCommand>
</RunSynchronous>
</component>
</settings>
<settings pass="oobeSystem">
<component name="Microsoft-Windows-International-Core">
<UILanguage>en-US</UILanguage>
<SystemLocale>en-US</SystemLocale>
</component>
</settings>
</unattend>
关键观察:这些 XML 元素本身都是微软文档中定义的合法配置项。攻击者的巧妙之处在于将它们组合成一个在 WinRE 恢复路径中可被自动处理的执行链。
3.4 Defender 离线扫描的状态机制
理解为什么「离线扫描曾经运行过」是关键前置条件,需要深入理解 Start-MpWDOScan 的行为:
# 触发 Defender 离线扫描
Start-MpWDOScan
# 该命令的行为:
# 1. 修改启动配置数据(BCD),添加离线扫描入口
# 2. 在恢复分区中配置扫描环境
# 3. 设置下次启动为 WinRE 离线扫描模式
# 4. 重启计算机进入扫描
# 5. 扫描完成后恢复正常启动配置
扫描完成后,虽然启动配置恢复到正常状态,但恢复分区中的某些文件和状态可能被永久性修改。这些修改包括:
- WinRE 镜像的加载路径配置
ReAgent.xml的内容变更- 扫描过程中创建的临时目录和文件
GreatXML 的作者推测,正是这些残留的状态变更,使得后续重启进入 WinRE 时,恢复环境会以不同的行为模式处理 unattend.xml。
3.5 攻击链的争议:可靠性存疑
独立安全研究员 Will Dormann(前 CERT/CC 分析师)的实测结果表明,实际触发条件比 PoC 描述的更为苛刻:
- Shell 的出现时机可能不在普通 WinRE 启动时,而是在下一次离线扫描启动期间
- 这意味着攻击链的触发实际上绑定在离线扫描的启动路径上,而非简单的 WinRE 启动
- 可能在特定硬件和 Windows 版本上表现不一致
状态总结:
| 项目 | 状态 |
|---|---|
| GitHub 仓库公开存在 | ✅ 已确认 |
| WinRE 为默认 PE 恢复环境 | ✅ 微软文档确认 |
| unattend.xml 为合法部署机制 | ✅ 微软文档确认 |
| Defender 离线扫描改变启动路径 | ✅ 微软文档确认 |
| 获得加密卷 Shell | ⚠️ 作者声称,部分独立验证 |
| 无需登录即可触发 | ❌ 未验证 |
| 跨硬件可复现 | ❌ 未验证 |
| 微软确认为漏洞 | ❌ 未确认,无 CVE 分配 |
四、Nigthmare Eclipse 的「零日风暴」:一个更大的攻击模式
GreatXML 并非孤立事件。它是同一个研究员发起的一系列针对 Windows 维护层攻击中的最新一环。
4.1 时间线梳理
2026年4月 ─── YellowKey (CVE-2026-45585)
WinRE + BitLocker 绕过
微软发布缓解措施 → 6月补丁日修复
│
2026年5月 ─── BlueHammer (CVE-2026-33825)
│
├── RedSun (CVE-2026-41091)
│
├── UnDefend (CVE-2026-45498)
│
├── GreenPlasma
│
2026年6月10日── RoguePlanet
Defender 竞态条件 → SYSTEM 权限提升
│
└── GreatXML
Defender 离线扫描 + WinRE + unattend.xml
→ BitLocker 绕过
4.2 攻击模式的共性
这些漏洞的共同主题非常清晰:
信任边界在维护层被突破。Windows 的维护组件(Defender、WinRE、部署工具)被设计为「可信任的」,但正是这种信任成为了攻击面。
预操作系统环境的安全盲区。在 Windows 正常启动之前,端点安全控制可能处于未激活或不完整状态。
合法机制的被武器化。unattend.xml、Defender 离线扫描、系统恢复流程——这些都是微软设计和维护的合法功能。
4.3 RoguePlanet:GreatXML 的「搭档」
与 GreatXML 同一天发布的 RoguePlanet 利用 Defender 实时扫描引擎中的竞态条件:
低权限用户 → 创建恶意符号链接 → 干扰 Defender 扫描流程 →
诱导 Defender 覆盖自身文件 → 以 SYSTEM 权限执行任意代码
已有多名安全研究员在安装了2026年6月补丁的 Windows 10/11 系统上成功复现此攻击。这意味着 6月补丁日未能修复此漏洞。
两个漏洞的组合使用场景:
- RoguePlanet → 拿到 SYSTEM 权限
- GreatXML → 绕过 BitLocker 加密
- 组合效果 → 完整的端点沦陷,包括获取加密数据
五、检测与狩猎:实战指南
5.1 恢复分区完整性监控
最直接的检测方法是监控恢复分区的异常写入:
# 检查 WinRE 状态
reagentc /info
# 示例输出:
# Windows Recovery Environment (Windows RE) 和启动配置数据(BCD)信息
# 已启用 Windows RE
# RE 位置: \\?\GLOBALROOT\device\harddisk0\partition1\Recovery\WindowsRE
# 启动配置:
# 标识符: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
# 位置: \\?\GLOBALROOT\device\harddisk0\partition1\Recovery\WindowsRE\winre.wim
# 检查 BitLocker 保护器类型
manage-bde -protectors -get C:
# 示例输出(TPM-Only - 高风险):
# 数值密码标识符: (无)
# TPM: 已启用
# 示例输出(TPM+PIN - 低风险):
# TPM And PIN: 已启用
# PIN: ****
5.2 检测规则:KQL / SIEM 查询
以下是基于 Windows 事件日志的检测逻辑:
// 规则 1:恢复分区异常写入
DeviceFileEvents
| where TargetFilename has @"\\Recovery\\WindowsRE"
| where TargetFilename endswith "unattend.xml"
or TargetFilename endswith "ReAgent.xml"
| where InitiatingProcess !has "Microsoft"
and InitiatingProcess !has "reagentc"
and InitiatingProcess !has "dism"
| project Timestamp, DeviceName, TargetFilename, InitiatingProcess, InitiatingProcessCommandLine
// 规则 2:非预期的 Defender 离线扫描
DeviceProcessEvents
| where ProcessCommandLine has "Start-MpWDOScan"
or FileName == "MpCmdRun.exe" and ProcessCommandLine has "-Scan"
| project Timestamp, DeviceName, FileName, ProcessCommandLine, InitiatingProcess
// 规则 3:异常的 WinRE 启动
DeviceBootEvents
| where BootType == "WinRE"
| join kind=inner (
DeviceFileEvents
| where TargetFilename has "unattend.xml" and TimeGenerated between (ago(1h)..ago(0s))
) on DeviceId
| project Timestamp, DeviceName, BootType
5.3 文件系统指标监控
在端点上监控以下文件和路径的异常变更:
监控目标列表:
├── 恢复分区根目录/unattend.xml ← 关键指标
├── 恢复分区根目录/Recovery/
│ └── WindowsRE/
│ └── ReAgent.xml ← 配置变更
├── WinRE 镜像文件 (winre.wim) ← 完整性变更
└── BCD 启动配置 ← 启动路径变更
使用 PowerShell 定期审计脚本:
# 恢复分区审计脚本 - 建议加入定期任务
function Audit-RecoveryPartition {
param(
[string]$RecoveryDrive = "X:",
[string]$LogPath = "C:\Logs\RecoveryAudit.log"
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$results = @()
# 检查 unattend.xml 是否存在
$unattendPath = Join-Path $RecoveryDrive "unattend.xml"
if (Test-Path $unattendPath) {
$fileInfo = Get-Item $unattendPath
$results += "[$timestamp] ALERT: unattend.xml found - LastModified: $($fileInfo.LastWriteTime), Size: $($fileInfo.Length)"
}
# 检查 Recovery 目录
$recoveryDir = Join-Path $RecoveryDrive "Recovery\WindowsRE"
if (Test-Path $recoveryDir) {
$recoveryFiles = Get-ChildItem -Path $recoveryDir -Recurse -Force
$results += "[$timestamp] Recovery directory contains $($recoveryFiles.Count) files"
# 检查 ReAgent.xml
$reAgentPath = Join-Path $recoveryDir "ReAgent.xml"
if (Test-Path $reAgentPath) {
$reAgent = Get-Item $reAgentPath
$results += "[$timestamp] ReAgent.xml - LastModified: $($reAgent.LastWriteTime)"
}
}
# 检查 WinRE 启用状态
$reagentInfo = reagentc /info 2>&1
$results += "[$timestamp] WinRE Status:`n$reagentInfo"
# 输出日志
$results | ForEach-Object {
Write-Warning $_
$_ | Out-File -Append -FilePath $LogPath
}
}
# 执行审计
Audit-RecoveryPartition
5.4 BitLocker 保护器扫描
企业环境中批量检查 BitLocker 配置:
# 批量检查 TPM-Only 配置的设备(高风险)
$computers = Get-ADComputer -Filter {Enabled -eq $true} -Properties Name
$highRiskDevices = foreach ($computer in $computers) {
try {
$protectors = manage-bde -protectors -get C: -cn $computer.Name 2>&1
if ($protectors -match "TPM" -and $protectors -notmatch "PIN" -and $protectors -notmatch "USB") {
[PSCustomObject]@{
ComputerName = $computer.Name
Config = "TPM-Only (HIGH RISK)"
Protectors = ($protectors | Out-String)
}
}
} catch {
# 远程查询失败,记录
}
}
# 导出高风险设备列表
$highRiskDevices | Export-Csv -Path "C:\Reports\BitLockerHighRiskDevices.csv" -NoTypeInformation
Write-Output "发现 $($highRiskDevices.Count) 台 TPM-Only 高风险设备"
六、防御加固:从紧急缓解到长期策略
6.1 紧急缓解措施
优先级最高:添加预启动认证(TPM+PIN)
# 单机添加 PIN 保护器
manage-bde -protectors -add C: -TPMAndPIN
# 验证
manage-bde -protectors -get C:
# 输出应包含:
# TPM And PIN: 已启用
为什么这是最有效的防御?
TPM+PIN 配置下,加密密钥的释放需要两个因素:
- TPM 芯片验证启动链完整性
- 用户输入 PIN 码
即使攻击者成功进入 WinRE 并获得 Shell,加密卷仍然是锁定的——因为 PIN 没有被输入,TPM 不会释放密钥。攻击者看到的只是一堆加密数据。
企业级批量部署(GPO/Intune):
<!-- GPO 配置:要求启动时额外认证 -->
<!-- 路径:计算机配置 → 管理模板 → Windows 组件 → BitLocker 驱动器加密 -->
<!-- 操作系统驱动器 → 在启动时要求附加身份验证 -->
<Policy>
<Name>RequireAdditionalAuthenticationOnStartup</Name>
<State>Enabled</State>
<Configuration>
<AllowTPM>True</AllowTPM>
<AllowTPM+PIN>True</AllowTPM+PIN>
<AllowTPM+StartupKey>True</AllowTPM+StartupKey>
<AllowTPM+PIN+StartupKey>True</AllowTPM+PIN+StartupKey>
<AllowPIN>False</AllowPIN>
<AllowStartupKey>True</AllowStartupKey>
<AllowTPM+PIN+USB>True</AllowTPM+PIN+USB>
<!-- 强制要求 PIN -->
<RequirePIN>True</RequirePIN>
</Configuration>
</Policy>
6.2 WinRE 加固
# 1. 检查 WinRE 镜像是否为最新版本
# WinRE 更新通常包含在累积更新中
# 确保 KB5025885 或更高版本的安全更新已安装
# 2. 禁用 WinRE(高风险环境,权衡恢复能力)
# ⚠️ 这将使系统无法使用高级启动选项
reagentc /disable
# 3. 重新部署 WinRE 镜像(确保使用最新版本)
dism /image:C: /cleanup-image /startcomponentcleanup
reagentc /rearm
6.3 物理安全控制
物理安全清单:
├── UEFI/BIOS 密码设置 ← 阻止未经授权的固件访问
├── Secure Boot 保持启用 ← 确保启动链完整性
├── 禁用外部设备启动 ← 阻止 USB/CD 恢复介质启动
├── 防篡改封条和机箱锁 ← 检测物理接触
├── BIOS 中的 VT-x/AMD-V 控制 ← 防止 DMA 攻击向量
└── 端口物理封堵(USB、Thunderbolt 等) ← 消除物理接入点
6.4 Defender 离线扫描控制
# 检查离线扫描是否可用
$defenderStatus = Get-MpComputerStatus
Write-Output "AntiSpywareEnabled: $($defenderStatus.AntiSpywareEnabled)"
Write-Output "AntivirusEnabled: $($defenderStatus.AntivirusEnabled)"
# 通过 GPO 限制离线扫描的触发权限
# 路径:计算机配置 → 管理模板 → Windows 组件 → Windows Defender 防病毒
# → 允许用户启用 Microsoft Defender 防病毒网络实时检查
# → 配置为"已禁用"(限制普通用户触发)
6.5 安全启动流程加固
# 验证 Secure Boot 状态
Confirm-SecureBootUEFI
# 检查启动配置完整性
bcdedit /enum all
# 关注以下设置:
# - 安全启动是否启用
# - 是否存在非预期的启动入口
# - WinRE 启动路径是否正常
七、威胁建模:GreatXML 对不同场景的影响
7.1 企业环境
风险等级:🔴 高
攻击场景:设备丢失/被盗
影响范围:TPM-Only 配置的所有 Windows 设备
缓解难度:中等(企业 GPO 可批量部署 TPM+PIN)
攻击路径:
1. 笔记本电脑被盗(物流/差旅场景)
2. 攻击者使用 USB 启动盘进入 WinRE
3. 写入恶意 unattend.xml 到恢复分区
4. 重启 → 获得加密卷 Shell
5. 提取敏感数据
7.2 高价值目标
风险等级:🔴🔴 极高
攻击场景:针对性物理入侵
影响范围:执行人员、高管、开发人员(拥有生产凭证)
特殊风险:
- 开发人员笔记本通常包含生产环境凭证、API 密钥
- 高管设备包含商业机密、战略文档
- 记者和活动人士设备可能包含敏感来源信息
7.3 个人用户
风险等级:🟡 中
攻击场景:设备丢失/二手设备数据恢复
影响范围:所有 TPM-Only BitLocker 用户
缓解建议:
1. 添加 PIN 或密码保护
2. 启用 OneDrive 设备加密备份
3. 设置设备定位和远程擦除
八、从 GreatXML 看 Windows 安全架构的深层问题
8.1 「信任链」的隐含假设
BitLocker 的安全模型假设了一个连续的信任链:
UEFI 固件 → Secure Boot → Windows Boot Manager → Windows 内核 →
BitLocker 服务 → 密钥释放 → 加密卷访问
但 WinRE 的存在引入了一个绕过点:
UEFI 固件 → WinRE 启动 → [此处信任链被重新定义] →
恢复工具对加密卷的访问
WinRE 需要访问加密卷才能执行修复操作(如回滚到还原点、修复启动配置)。这个「需要」就是信任链中最薄弱的环节。
8.2 维护层作为攻击面的趋势
GreatXML、YellowKey、RoguePlanet 三个漏洞连续打击的是同一个攻击面:Windows 的维护基础设施。
这些基础设施的设计初衷是保障系统可用性:
- WinRE → 系统恢复
- Defender 离线扫描 → 恶意软件清除
- unattend.xml → 自动化部署
但「保障可用性」和「保障安全性」之间存在根本矛盾:
- 维护操作需要高权限
- 维护操作在预操作系统环境中运行
- 维护操作需要绕过某些安全控制才能生效
8.3 「微软组件 = 安全」的信任陷阱
许多安全检测系统基于「微软签名的进程是可信的」这一假设。但 GreatXML 证明:
微软签名的 WinRE → 处理微软支持的 unattend.xml → 执行攻击者提供的命令
在这个过程中,每一个环节都是合法的微软组件,但最终结果是恶意行为。这对基于信誉的检测模型构成了根本性挑战。
8.4 开源披露 vs 负责任的漏洞报告
Nightmare Eclipse 选择公开披露的方式也值得关注。据其自称是前微软员工,因漏洞赏金纠纷被微软封禁了 GitHub 和 MSRC(微软安全响应中心)账户,因此自4月起通过个人博客和 GitHub 持续发布武器化漏洞。
这种「报复性披露」(Retaliatory Disclosure)带来了复杂的伦理问题:
- 公开披露迫使微软修复,但也为攻击者提供了可直接使用的武器
- 系列性披露使得防御方难以应对——修复一个漏洞的同时新漏洞又出现
- 无 CVE 分配意味着企业难以追踪和优先级排序
九、实战代码:自动化安全基线检查工具
以下是一个完整的 PowerShell 安全基线检查工具,用于检测企业环境中的 GreatXML 攻击面:
<#
.SYNOPSIS
GreatXML 攻击面安全基线检查工具
.DESCRIPTION
检测当前系统对 GreatXML 类 BitLocker 绕过攻击的脆弱性,
包括 BitLocker 配置、WinRE 状态、恢复分区完整性。
.NOTES
File Name: GreatXML-Baseline-Audit.ps1
Author: Security Audit Script
Version: 1.0
Date: 2026-06-14
#>
[CmdletBinding()]
param(
[switch]$ExportReport,
[string]$ReportPath = "C:\Reports\GreatXML-Audit-$(Get-Date -Format 'yyyyMMdd').csv"
)
$ErrorActionPreference = 'Stop'
$results = [System.Collections.Generic.List[PSCustomObject]]::new()
function Test-AdminPrivilege {
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = [Security.Principal.WindowsPrincipal]($identity)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
# 1. 检查 BitLocker 保护器配置
function Audit-BitLockerConfig {
try {
$volumes = Get-BitLockerVolume | Where-Object { $_.ProtectionStatus -ne 'Unknown' }
foreach ($vol in $volumes) {
$mountPoint = $vol.MountPoint
$protectors = $vol.KeyProtector
$hasTPM = $protectors | Where-Object { $_.KeyProtectorType -eq 'Tpm' }
$hasPIN = $protectors | Where-Object { $_.KeyProtectorType -eq 'TpmPin' }
$hasPassword = $protectors | Where-Object { $_.KeyProtectorType -eq 'Password' }
$hasRecovery = $protectors | Where-Object { $_.KeyProtectorType -eq 'RecoveryPassword' }
$hasUSB = $protectors | Where-Object { $_.KeyProtectorType -eq 'ExternalKey' }
# 风险评估
$risk = "LOW"
$riskReason = ""
if ($hasTPM -and -not $hasPIN -and -not $hasPassword -and -not $hasUSB) {
$risk = "CRITICAL"
$riskReason = "TPM-Only: Vulnerable to physical BitLocker bypass (GreatXML)"
} elseif ($hasTPM -and $hasPIN) {
$risk = "LOW"
$riskReason = "TPM+PIN: Resistant to physical bypass"
} elseif ($hasTPM -and $hasPassword) {
$risk = "LOW"
$riskReason = "TPM+Password: Resistant to physical bypass"
} elseif (-not $hasTPM) {
$risk = "INFO"
$riskReason = "No TPM protector: BitLocker not using hardware-based protection"
}
$results.Add([PSCustomObject]@{
Category = "BitLocker"
Item = "Volume: $mountPoint"
Status = $risk
Detail = $riskReason
ProtectorTypes = ($protectors.KeyProtectorType -join ', ')
})
}
} catch {
$results.Add([PSCustomObject]@{
Category = "BitLocker"
Item = "Volume Check"
Status = "ERROR"
Detail = $_.Exception.Message
ProtectorTypes = "N/A"
})
}
}
# 2. 检查 WinRE 状态
function Audit-WinRE {
try {
$reagentOutput = reagentc /info 2>&1 | Out-String
$winreEnabled = $reagentOutput -match "Windows RE.*已启用" -or
$reagentOutput -match "Windows RE.*enabled"
$results.Add([PSCustomObject]@{
Category = "WinRE"
Item = "Status"
Status = if ($winreEnabled) { "ENABLED" } else { "DISABLED" }
Detail = if ($winreEnabled) {
"WinRE is enabled - recovery partition is accessible"
} else {
"WinRE is disabled - recovery functionality unavailable"
}
ProtectorTypes = "N/A"
})
# 提取 WinRE 路径
if ($reagentOutput -match "位置[:\s]+(.+)") {
$winrePath = $Matches[1].Trim()
$results.Add([PSCustomObject]@{
Category = "WinRE"
Item = "Image Location"
Status = "INFO"
Detail = "WinRE image path: $winrePath"
ProtectorTypes = "N/A"
})
}
} catch {
$results.Add([PSCustomObject]@{
Category = "WinRE"
Item = "Status Check"
Status = "ERROR"
Detail = $_.Exception.Message
ProtectorTypes = "N/A"
})
}
}
# 3. 检查 Secure Boot
function Audit-SecureBoot {
try {
$secureBoot = Confirm-SecureBootUEFI 2>&1
$results.Add([PSCustomObject]@{
Category = "SecureBoot"
Item = "UEFI Secure Boot"
Status = if ($secureBoot) { "ENABLED" } else { "DISABLED" }
Detail = if ($secureBoot) {
"Secure Boot is enabled - boot chain integrity verified"
} else {
"Secure Boot is DISABLED - WARNING: boot chain not verified"
}
ProtectorTypes = "N/A"
})
} catch {
$results.Add([PSCustomObject]@{
Category = "SecureBoot"
Item = "UEFI Secure Boot"
Status = "UNKNOWN"
Detail = "Cannot determine Secure Boot status: $($_.Exception.Message)"
ProtectorTypes = "N/A"
})
}
}
# 4. 检查 Defender 离线扫描历史
function Audit-DefenderOfflineScan {
try {
$mpStatus = Get-MpComputerStatus
$results.Add([PSCustomObject]@{
Category = "Defender"
Item = "Offline Scan Availability"
Status = if ($mpStatus.AntivirusEnabled) { "AVAILABLE" } else { "UNAVAILABLE" }
Detail = "Defender is $($mpStatus.AntivirusEnabled ? 'enabled' : 'disabled')"
ProtectorTypes = "N/A"
})
# 检查事件日志中的离线扫描记录
$offlineScanEvents = Get-WinEvent -FilterHashtable @{
LogName = 'Microsoft-Windows-Windows Defender/Operational'
Id = 5001, 5007
} -MaxEvents 10 -ErrorAction SilentlyContinue
if ($offlineScanEvents) {
foreach ($event in $offlineScanEvents) {
$results.Add([PSCustomObject]@{
Category = "Defender"
Item = "Offline Scan Event"
Status = "INFO"
Detail = "Event ID $($event.Id) at $($event.TimeCreated): $($event.Message.Substring(0, [Math]::Min(200, $event.Message.Length)))"
ProtectorTypes = "N/A"
})
}
} else {
$results.Add([PSCustomObject]@{
Category = "Defender"
Item = "Offline Scan History"
Status = "INFO"
Detail = "No recent offline scan events found"
ProtectorTypes = "N/A"
})
}
} catch {
$results.Add([PSCustomObject]@{
Category = "Defender"
Item = "Status Check"
Status = "ERROR"
Detail = $_.Exception.Message
ProtectorTypes = "N/A"
})
}
}
# 5. 检查 BCD 启动配置
function Audit-BootConfig {
try {
$bcdOutput = bcdedit /enum all 2>&1 | Out-String
# 检查是否有非预期的启动入口
$bcdEntries = $bcdOutput -split "----" | Where-Object { $_.trim() -ne "" }
$customEntries = $bcdEntries | Where-Object {
$_ -match "recovery" -and ($_ -match "custom" -or $_ -match "unattend")
}
if ($customEntries) {
$results.Add([PSCustomObject]@{
Category = "BCD"
Item = "Custom Recovery Entry"
Status = "WARNING"
Detail = "Custom recovery boot entry detected - requires investigation"
ProtectorTypes = "N/A"
})
} else {
$results.Add([PSCustomObject]@{
Category = "BCD"
Item = "Boot Configuration"
Status = "OK"
Detail = "No suspicious custom recovery entries detected"
ProtectorTypes = "N/A"
})
}
} catch {
$results.Add([PSCustomObject]@{
Category = "BCD"
Item = "Boot Config Check"
Status = "ERROR"
Detail = $_.Exception.Message
ProtectorTypes = "N/A"
})
}
}
# 执行所有审计
if (-not (Test-AdminPrivilege)) {
Write-Warning "此脚本需要管理员权限运行。部分检查可能失败。"
}
Write-Output "=========================================="
Write-Output "GreatXML 攻击面安全基线检查"
Write-Output "时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
Write-Output "=========================================="
Write-Output ""
Audit-BitLockerConfig
Audit-WinRE
Audit-SecureBoot
Audit-DefenderOfflineScan
Audit-BootConfig
# 输出结果
$results | Format-Table Category, Item, Status, Detail -AutoSize
# 统计
$critical = ($results | Where-Object { $_.Status -eq 'CRITICAL' }).Count
$warnings = ($results | Where-Object { $_.Status -match 'WARNING|HIGH' }).Count
Write-Output ""
Write-Output "=========================================="
Write-Output "检查结果摘要"
Write-Output " 关键风险: $critical"
Write-Output " 警告项: $warnings"
Write-Output "=========================================="
if ($ExportReport) {
$results | Export-Csv -Path $ReportPath -NoTypeInformation -Encoding UTF8
Write-Output "报告已导出至: $ReportPath"
}
十、总结与展望
10.1 关键结论
GreatXML 揭示了 Windows 安全架构的一个根本性弱点:维护基础设施(WinRE、Defender、部署工具)的设计目标与安全目标之间的矛盾。这些组件需要高权限和预操作系统访问能力,而正是这些特性使它们成为攻击面。
BitLocker TPM-Only 配置在面对物理攻击时已不足够。这一直是安全社区的共识,但 GreatXML 提供了一个具体的攻击路径来证明这一点。所有高风险设备都应配置 TPM+PIN 或更强的预启动认证。
检测模型需要从「基于信誉」转向「基于行为」。当攻击利用合法的微软组件时,仅凭进程签名和信誉无法识别恶意行为。需要关注的是上下文——微软组件在异常环境中的异常行为。
Nigthmare Eclipse 的系列披露暗示 WinRE 是一个系统性问题。三个连续的漏洞(YellowKey、RoguePlanet、GreatXML)都针对同一攻击面,这不是巧合——微软的恢复环境设计需要根本性的安全改进。
10.2 行动建议优先级
| 优先级 | 行动 | 实施难度 | 防护效果 |
|---|---|---|---|
| P0 立即 | 高风险设备添加 TPM+PIN | 低 | 消除物理绕过风险 |
| P1 本周 | 监控恢复分区异常写入 | 中 | 及时发现攻击活动 |
| P1 本周 | 部署安全基线检查脚本 | 低 | 掌握全网脆弱性 |
| P2 本月 | 限制 Defender 离线扫描触发权限 | 中 | 减少攻击面 |
| P2 本月 | 审计 WinRE 启用状态 | 低 | 收缩攻击面 |
| P3 季度 | 评估高安全设备是否需要禁用 WinRE | 高 | 消除恢复环境风险 |
| P3 季度 | 更新物理安全策略 | 中 | 阻止物理接触 |
10.3 行业展望
GreatXML 事件预示了几个趋势:
维护层将成为 2026 年的主要攻击面。随着微软修补了传统的内核漏洞和应用层漏洞,攻击者转向了更难加固的维护基础设施。
物理攻击的「数字化」。传统意义上的物理安全(锁门、加密)正在与数字攻击面深度融合。安全团队需要将物理安全和信息安全统一考虑。
AI 辅助的漏洞挖掘将加速此类发现。随着 AI 编程工具的普及,安全研究员(和攻击者)将能够更快地发现和利用复杂的跨组件漏洞链。
最核心的教训是:安全不是一条链,而是一个网络。任何节点的信任都不应被隐式假设,即使这个节点叫做「Windows Defender」或「Windows Recovery」。
参考资料
- Hive Security - GreatXML: When a Setup File Unlocks BitLocker
- Marc Frederic Gomez - GreatXML Technical Analysis
- The Register - Nightmare Eclipse drops claimed BitLocker bypass
- SecurityWeek - GreatXML Zero-Day Exploit Bypasses BitLocker
- NVD - CVE-2026-45585 (YellowKey)
- Microsoft Learn - Windows Recovery Environment
- Microsoft Learn - BitLocker Countermeasures
- Microsoft Learn - Start-MpWDOScan