微软近日发布了针对使用基于虚拟化的安全(VBS)安全区的开发者的全面指导,强调了加强不同虚拟信任级别之间信任边界的关键安全措施。
VBS 安全区的安全挑战
微软安全团队的这份指导文件,主要探讨了在实现 VBS 安全区时所面临的基本安全挑战。VBS 安全区利用管理程序的虚拟信任级别,在用户模式进程内隔离内存和代码执行区域。
VBS 安全区提供了强大的可信执行环境(TEE),可以保护敏感数据(如加密密钥)免受恶意管理员的访问。然而,这些保护措施在 VTL1 安全区和 VTL0 主机进程之间引入了一个独特的信任边界。
与传统的信任边界不同,安全区存在于其主机进程内部,这就要求开发者采取全新的安全视角。文件中强调的主要安全原则是:安全区绝不能信任 VTL0。尽管主机进程无法读取或写入安全区的内存区域,但安全区可以访问其主机的内存,如果管理不当,就会产生安全漏洞。
指针验证的重要性
微软研究人员指出,一个关键建议是验证从主机进程传递的指针是否在 VTL1 安全区的地址范围之外。微软通过代码示例展示了这一漏洞,恶意主机可能通过操纵指针值来攻击安全区。例如:
`LPVOID GetState (LPVOID lpParam) { State* state = (State*) lpParam; if (state == nullptr) { return (LPVOID)E_INVALIDARG; } *state = g_State; return (LPVOID)S_OK; }`
如果没有适当的验证,该函数可能会无意中允许主机覆盖敏感的安全区内存。
检查前在 VTL1 中捕获 VTL0 结构(来源:微软)
安全实现模式
开发者被建议在初始化时使用EnclaveGetEnclaveInformation
API 来确定安全区的边界,并验证所有主机提供的指针是否落在这些边界之外。
CRITICAL_SECTION 锁(来源:微软)
此外,为了防止“检查时间-使用时间”(TOCTOU)攻击,应在验证之前将 VTL0 的结构复制到 VTL1 的内存中。指导文件还强调,机密信息应始终在安全区内生成,并且不应通过非安全通道暴露。
微软警告开发者不要重新发明安全原语,建议使用 Windows 实现库和 RAII 包装器。有趣的是,微软甚至在文件中提到探索 Rust 进行安全区开发的可能性,并提到在最近的 MORSE 黑客马拉松中开发的一个概念验证,该验证利用了 Rust 的内存安全特性。
参考来源: