介绍
继上一篇文章"Bitlocker密钥提取之深入分析TPM释放密钥VMK过程" 之后,为了证实,当PCR11寄存器的值为0时,可以通过TPM命令,模拟真实过程,从TPM芯片中解封(Unseal)并释放出VMK密钥,从而离线解锁Bitlocker TPM加密的磁盘。
本次试验环境依然采用前一个文章中的调试环境,即IDA+GDB+VMware虚拟机的方式,通过在系统启动过程中,动态修改系统启动流程和内存数据,绕过bootmgfw.efi和winload.edi对PCR11的扩展,即保持PCR11寄存器的值始终是它的初始值0。
绕过流程
首先定位EFI固件中函数EfiTreeSubmitCommand的地址,得到该函数在内存中的偏移地址,具体的分析方法,参见前文,这里不再赘述。
接着便是对该函数EfiTreeSubmitCommand的地址下断点,然后启动虚拟机系统。
假设我们没有系统的登录密码等口令,无法解锁登录目标系统,虚拟磁盘和内存文件都是加密的,无法绕过,无法获取有用数据。因此备选方案是启动到目标系统的恢复模式下。通过强关2次系统,再次启动时就自动进入Windows恢复模式。
经过观察分析,前三次的断点中断,是对固件、证书、bootmgfw.efi文件的完整性检验,并扩展到对应的PCR寄存器中,不会扩展改变PCR11寄存器的初始值,这些并不影响接下来的实验,所以可以忽略前三次的断点中断,即按F9继续系统的启动。
接下来会有2次的断点命中。
第一次是bootmgfw.efi对PCR11的扩展修改。该模块计算10 00 00 00这4个字节的SHA256哈希值,扩展到PCR11上。
第二次是winload.efi对PCR11的扩展修改,该模块计算FF FF 00 00这4个字节的SHA256哈希值,扩展到PCR11上。
通常每个TPM Bitlocker加密的Windows系统,PCR11扩展后最终的SHA256的值都是相同的,如下值(可以通过系统自带的TpmTool命令查看该值):
接下来查看2次中第1次的命中,如下图所示
此时,查看R8寄存器指向的内存地址中的值正是10 00 00 00,R9寄存器存储字节长度,即4字节。修改此时的CPU寄存器值,即修改RIP, RSP, RAX,从而实现跳过函数EfiTreeSubmitCommand的执行,绕过bootmgfw.efi对PCR11的扩展修改,寄存器修改如下:
RIP = [RSP] ; 直接执行下一条指令
RSP = RSP + 0x08 ; 栈中弹出一个值,保持堆栈平衡
RAX = 0x00 ; 设置函数返回结果,0代表成功
修改后截图如下:
接下按F9继续执行,直到第2次命中断点,如下图所示:
此时,R8寄存器指向的内存地址处的值为FF FF 00 00,正如上文所说,winload.efi中计算这4个字节的SHA256,扩招到PCR11上。
用同样的方式修改CPU寄存器的值,绕过函数EfiTreeSubmitCommand的执行,修改后同样的按F9继续执行,系统将启动到Windows的恢复模式。
选择“疑难解答” -> “高级选项” -> “命令行提示符”进入命令行操作窗口(中间跳过恢复密钥输入窗口)。通过工具可以打印此时的PCR值,如下图示:
查看PCR11 SHA256哈希值为0(红框所指),说明对PCR11扩展修改绕过成功。并且磁盘仍然处于锁定状态,无法访问系统盘数据。
系统盘Bitlocker加密状态如下图所示,显示加密磁盘尚未解锁
编码实现TPM解封工具
接下来就是编写模拟解封TPM密钥的工具了。本次使用微软开源库框架TSS.MSR,支持多种语言,对TPM交互指令进行了很好的封装,方便开发使用。
将写好的工具放在目标系统下(恢复模式)执行,如下图:
最终得到熟悉的VMK密钥字符串如下:
b468267d6801e284b473f9f2886a5e6ca48c9baa708e5f941b769f6f671eecfd
解封用到的相关数据都是可以在解密磁盘的-FVE-FS-元数据中找到,分解如下:
如果PCR11的值不是0(被扩招修改),则再次解封密钥将无法成功,因为PolicyPCR校验无法通过,如下:
复制Raw Response内容到tpmstream,查看具体错误描述信息:
首发地址:https://mp.weixin.qq.com/s/_4VFVI210Wz8thOp4-pIuA