静默漏洞缓解机制:为1%用户设计
随着Windows 10加速发布计划,新功能定期推出已成为常态。特别是那些用于缓解设计不良API或易被滥用行为的特性。这些缓解措施的问题在于它们通常缺乏文档记录,或者至少没有通过常见的Win32 API公开。这意味着虽然微软可以高枕无忧并防止自身代码受到攻击,但却让第三方开发者陷入困境。
这些静默缓解措施的一个例子是额外的OBJECT_ATTRIBUTE标志OBJ_IGNORE_IMPERSONATED_DEVICEMAP和OBJ_DONT_REPARSE,这些标志最终得到了文档化——部分原因是因为我表示这样做会很好。当然,从它们被引入以修复我报告的漏洞到被文档化,只用了5年时间。我想在微软的世界里这已经算很快了。而且,只有当您使用系统调用API时,这些标志才会对您有所帮助——别忘了,这些API只有部分被文档化。
在深入研究Windows 10 2004时(唉…真的让人困惑),可能是在某个时候被Alex Ionescu提醒,我注意到微软引入了另一个缓解措施,该措施只能通过未文档化的系统调用使用,而不能通过任何公开的Win32 API使用。所以我想,我应该将其文档化。
更新(2020-04-23):根据@FireF0X的说法,这已被反向移植到所有受支持的操作系统。因此,这是一个重要到足以进行反向移植的安全修复,但却没有告诉任何人。太棒了。
相关的系统调用是NtLoadKey3。根据j00ru的系统调用表,这是在Windows 10 2004中引入的,但至少也存在于Windows 10 1909中。顾名思义(至少对我来说),这将注册表键Hive加载到附加点。这一功能随着时间的推移而扩展,最初只有NtLoadKey,然后我相信在XP中引入了NtLoadKey2以添加一些标志。接着引入了NtLoadKeyEx,以添加诸如显式受信任Hive支持等功能,以缓解跨Hive符号链接攻击(这全是j00ru和Gynvael的错)。现在终于有了NtLoadKey3。我不知道为什么它先变成2,然后变成Ex,然后又回到3,也许这是微软的新计数系统。NtLoadKeyEx通过Win32 API RegLoadKey和RegLoadAppKey API部分公开,尽管它们只公开了系统调用功能的一个子集。
那么,NtLoadKey3试图缓解哪类漏洞?加载完整注册表Hive(而不是每用户应用程序Hive)的一个问题行为是,您需要在调用者的有效令牌上拥有SeRestorePrivilege*。SeRestorePrivilege仅授予管理员,因此为了成功调用API,您不能模拟低权限用户。然而,API在加载Hive文件时也可以创建文件。这包括Hive文件本身以及恢复日志文件。
*不要关注RegLoadKey的文档,该文档声称您还需要SeBackupPrivilege。也许在某个时候需要,但现在不再需要。
当加载系统Hive(如HKLM\SOFTWARE)时,这不是问题,因为这些Hive存储在仅管理员可访问的位置(如果您好奇的话,是c:\windows\system32\config),但有时Hive是从用户可访问的位置加载的,例如从用户配置文件或为了Desktop Bridge支持。在用户可访问的位置,您可以使用符号链接技巧强制将日志文件写入任意位置,更糟糕的是,主Hive文件的安全描述符被复制到日志文件,因此之后可以访问它。正是这个漏洞的一个例子,在这种情况下是在Desktop Bridge中,是问题1492(以及1554,因为他们没有正确修复它(╯°□°)╯︵ ┻━┻)。
NtLoadKey3通过引入一个额外参数来指定一个访问令牌,该令牌在创建任何文件时将被模拟,从而修复了这个问题。这样,对SeRestorePrivilege的检查可以使用调用者的访问令牌,但任何“危险”操作将使用用户的令牌。当然,他们可能可以通过添加一个新标志来实现这一点,该标志将检查调用者的主令牌以获取特权,就像他们对SeImpersonatePrivilege和SeAssignPrimaryTokenPrivilege所做的那样,但我知道什么呢…
如果使用得当,这应该完全缓解系统调用的不良设计。例如,用户配置文件服务在从用户配置文件加载Hive时现在使用NtLoadKey3。您自己如何调用它?我显然找不到任何文档,即使在通常的位置(如OLE32的私有符号中)似乎也没有任何结构数据,因此我做出了以下最佳猜测:
|
|
请注意,来自NtLoadKeyEx的TrustKey和Event句柄也被折叠成一个句柄值列表。也许有人不确定他们是否曾经需要扩展系统调用,是选择NtLoadKey4还是NtLoadKeyExEx,因此他们通过使系统调用更灵活来避免做出决定。此外,最后一个参数(也存在于NtLoadKeyEx中)似乎未使用,或者我只是无法追踪它何时被引用。Process Hacker的头文件声称它用于IO_STATUS_BLOCK指针,但我没有看到任何证据表明情况如此。
在这个新的、共享和关怀的微软中,如果他们能更频繁地共享和关怀,尤其是对于保护第三方应用程序安全的重要功能,那将是非常棒的。老实说,我认为他们更专注于将Wayland引入WSL2或将新的API集强加给开发者,而不是文档化这样的事情。