在本文中,我将演示如何使用自主开发的Memory-Dump-UEFI工具从内存中提取完整卷加密密钥(FVEK)来绕过Windows 11的BitLocker加密。
https://github.com/NoInitRD/Memory-Dump-UEFI
背景介绍
当攻击者能够物理接触设备时,可以通过突然重启电脑并转储最近运行的Windows实例的RAM内容来获取访问权限。通过分析捕获的内存数据,可以定位FVEK密钥等敏感信息。不过这种技术并非万无一失,因为断电后RAM中的内容会迅速消失。
有几种方法可以减缓内存数据的消失,包括物理降低RAM温度或使用外部电源维持供电。在本演示中,我通过短接主板上的复位引脚来实现系统突然重启而不断电。
另一个潜在问题是安全启动,这是一项限制设备启动时允许运行程序的安全标准。这种保护也有其局限性,可以通过使用shim程序或其他方法绕过,这些方法不在本演示范围内。
第一步:制作可启动U盘
首先需要准备一个容量大于目标系统RAM大小的U盘。我提供了一个名为flashimage.sh
的脚本来简化这个步骤。
点击此处查看制作和使用可启动程序的详细步骤。
第二步:突然重启目标系统
实现方式有很多种,但关键是要把电脑完全断电的时间降到最低。根据经验,如果是为了寻找FVEK密钥,在Windows加载过程中但登录界面出现之前重启系统效果最好。
第三步:从U盘启动
立即从U盘启动Memory-Dump-UEFI。进入UEFI shell后,找到并执行app.efi
。具体操作方法可以参考该程序说明文档。所需时间取决于要转储的RAM容量和U盘速度。建议在此步骤中拔掉其他USB存储设备,避免程序误写入错误的驱动器。
上图展示了成功进入shell后的界面。程序会不断生成转储文件,直到内存用尽。完成后可以正常关机。
第四步:分析转储文件
准备工作
由于FAT32文件系统对单个文件大小有4GB的限制,程序可能会生成多个转储文件。为了符合UEFI规范,必须使用FAT32文件系统。为了方便使用,我在tools目录下提供了一个名为concatDumps.py
的脚本,可以按时间顺序将多个转储文件合并。转储文件包含当时内存中的原始数据,建议使用xxd
工具查看。为了便于搜索,我提供了一个名为searchMem.py
的脚本,可以在转储文件中搜索十六进制模式。找到模式的偏移量后,可以使用xxd -s <偏移量> <转储文件>
跳转到对应位置。
内存池标识
内存池标识是由4个字符组成的标识符,用于标记Windows内核内存池。这些池由Windows内核分配,是寻找敏感信息的重要位置。内存池标识有很多种,我提供了一个名为pooltag.txt
的文件,其中包含了这些标识及其用途说明。
在继续之前,我要为微软在内存中清晰标记加密密钥的位置鼓个掌。在Windows 7上,只需定位对应fvevol.sys
的加密分配的FVEc
池标识就能恢复密钥。在Windows 8.1和10上,密钥位于对应ksecdd.sys
模块的Cngb
标记的内存池中。在研究Windows 11内存转储时,我没有在这两个位置找到密钥,但在另外两个地方发现了它。
FVEK密钥恢复
第一个发现FVEK密钥的位置是dFVE
池标识下,这个标识对应BitLocker驱动器加密的完整卷加密崩溃转储过滤器dumpfve.sys
的内存分配。池标识用蓝色下划线标出,FVEK密钥用红色高亮显示。这是我发现密钥最容易且最稳定的位置,而且前面有0x0480
标记表示使用的加密类型,在我的例子中是XTS-AES-128。
第二个位置在None
标识下,这与ExAllocatePool
例程的调用有关。这次可以看到密钥的前半部分出现了两次,后半部分出现了一次。
后续步骤
需要注意的是,获取的密钥前面要加上所使用的算法标识。也就是说,如果你的密钥是:
b2cbc06071931b7cc50b59f8789571f4dd815c2008e93c02d5c6cd98c83ef54b
你需要在密钥开头以小端格式添加0x8004
(或其他使用的算法标识),如下所示:
0480b2cbc06071931b7cc50b59f8789571f4dd815c2008e93c02d5c6cd98c83ef54b
接下来,需要将这串十六进制数据写入文件,可以使用以下命令:
echo "0480b2cbc06071931b7cc50b59f8789571f4dd815c2008e93c02d5c6cd98c83ef54b" | xxd -r -p > output.fvek
强烈建议使用dislocker
工具集来确定需要使用的算法/值,并最终解锁驱动器。如果所有步骤都正确,就可以使用output.fvek
解锁受BitLocker保护的分区,访问卷上的所有数据。
最后说明
理解微软如何实现BitLocker的最佳方式是使用windbg
进行内核级调试。使用虚拟机或交叉的USB 3.0 A/A线缆就能轻松实现。我之所以能找到密钥,是因为通过逐步调试Windows启动过程,观察BitLocker的运行。虽然微软试图使用SymCryptSessionDestroy
等函数销毁密钥,但并未能销毁所有密钥,这从堆中仍能找到密钥可以证明。
参考资料
https://tribalchicken.net/recovering-bitlocker-keys-on-windows-8-1-and-10/
https://github.com/libyal/libbde/blob/main/documentation/BitLocker%20Drive%20Encryption%20(BDE)%20format.asciidoc
https://github.com/Aorimn/dislocker
https://github.com/microsoft/SymCrypt
https://github.com/libyal/libbde
https://github.com/zodiacon/PoolMonX/blob/master/res/pooltag.txt
https://techcommunity.microsoft.com/blog/askperf/an-introduction-to-pool-tags/372983
原文始发于微信公众号(独眼情报):Windows 11 (24H2版本) BitLocker加密绕过方案
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论