当前位置:首页 > Safe 2017年08月06日
VirtualBox 5.1.22 - Windows进程DLL签名旁路特权升级攻击(国外)

VirtualBox:Windows进程DLL签名绕过EoP

平台:VirtualBox v5.1.22 r115126 x64(在Windows 10上测试)

类:特权提升

  

概要:

可以绕过VirtualBox驱动程序实现的进程加固,以在VirtualBox进程中加载任意代码,以访问VBoxDrv驱动程序,该驱动程序可以允许从普通用户路由到EoP。

  

描述:

   

注意:我不知道你是否认为这是一个问题,但是您修复了我发送的最后一个旁路,所以有可能你仍然认为它是一个安全边界。

   

VirtualBox中的Ring 3进程加固为模块加载添加了三个钩子,以尝试防止不受信任的代码加载到进程LdrLoadDll,NtCreateSection和LDR DLL通知中。每个都将尝试并验证一个DLL加载,并拒绝带有错误的加载,或者杀死该进程是不可能防止它发生的。看看钩子有几个问题,当组合在一起允许用户将任意DLL注入到受保护的进程中。

   

位置检查不是很严格。据我所知,任意文件需要由admin / trustedinstaller拥有,但如果文件位于system32 / WinSxS中,则可以放弃此检查。但是这并没有考虑到有一些目录可以写入system32,比如Tasks。

强制执行特定证书的代码似乎没有启用,所以至少与1结合使用,您可以加载任何有效的签名文件。

   

可能认为2不是问题,因为获取签名证书可能是“恶意”攻击者的足够负担,因此,值得考虑的是,弱路径检查允许您做什么。 DLL路径的处理有一些有趣的行为,最有趣的是,如果没有文件扩展名添加到路径,那么加载程序将自动将.DLL附加到它的行为。这实际上是在LdrLoadDll中实现的,这导致了我们的第三个问题:

   

3.如果传递给LdrLoadDll的路径没有扩展名,则保护代码将签名检查扩展名较少的文件,但加载程序将加载.DLL扩展名的文件。例如。如果尝试加载\ path \ abc,那么\ path \ abc是签名,但\ path \ abc.dll被加载。

   

当结合绕过所有者检查的能力时,我们可以在我们的不受信任的DLL旁边放置任意有效的签名文件,并利用此TOCTOU加载任意的未签名的DLL。当加载文件testdll时,VboxHardening.log将显示以下内容。

   

2064.492c:\ Device \ HarddiskVolume4 \ Windows \ System32 \ Tasks \ dummy \ testdll:所有者不受信任的安装程序

2064.492c:\ Device \ HarddiskVolume4 \ Windows \ System32 \ Tasks \ dummy \ testdll:放松这个DLL的TrustedInstaller要求(它在system32中)。

2064.492c:supHardenedWinVerifyImageByHandle: - > 0(\ Device \ HarddiskVolume4 \ Windows \ System32 \ Tasks \ dummy \ testdll)WinVerifyTrust

2064.492c:supR3HardenedWinVerifyCacheInsert:\ Device \ HarddiskVolume4 \ Windows \ System32 \ Tasks \ dummy \ testdll

2064.492c:supR3HardenedMonitor_LdrLoadDll:pName = c:\ windows \ system32 \ tasks \ dummy \ testdll(rcNtResolve = 0xc0150008)* pfFlags = 0x0 pwszSearchPath = 0000000000002009:<flags> [calling]

   

这表明它成功地通过LdrLoadDll钩子中的签名检查,但是其他钩子之一应该尝试重新检查真正的testdll.dll文件,而不是加载。由于此文件的名称与缓存的签名检查不匹配,所以仍然无法完成加载。这是第四个问题:

   

4.在禁用WinVerifyTrust的supHardenedWinVerifyImageByHandle中进行检查(即在DLL加载通知钩子中),并且目标文件没有签名信息时返回错误的错误代码,看起来像成功导致DLL被允许加载和执行。

   

特别是当supR3HardenedDllNotificationCallback被调用时,它会传递给supR3HardenedScreenImage的fAvoidWinVerifyTrust参数。这首先使用RT代码检查文件是否被签名,如果我们使用未签名的文件,那么这将返回错误VERR_LDRVI_NOT_SIGNED(-22900)。后来在supHardenedWinVerifyImageByLdrMod中,这个错误被检查,并且调用了函数supHardNtViCheckIfNotSignedOk。这似乎导致错误编码从错误更改为VINF_LDRVI_NOT_SIGNED(22900),这实际上是一个成功的代码。通常这将被调用WinVerifyTrust再次被覆盖,但由于禁用此过程的最终结果是DLL通知回调认为签名检查是成功的,即使不是。这导致DLL被允许完成加载。

   

例如,以下是旁路发生时的输出片断。

   

2064.492c:\ Device \ HarddiskVolume4 \ Windows \ System32 \ Tasks \ dummy \ TestDll.dll:所有者不是



发表评论: