一、前言
上周我在BsidesCharm 2019上做了一次演讲,简单讨论了COM方面内容,重点介绍了绕过Windows应用控制解决方案的一些技术。其中有个技术用到了Catalog文件中存在的一个问题,具体而言,老版本代码在更新版Windows依然处于已签名状态。
在本文中,我们将与大家讨论如何滥用Catalog文件签名机制绕过应用程序白名单(AWL),也会给出相应的缓解建议。
二、Catalog文件签名机制
代码签名是广泛使用的一种技术,可以用于验证文件完整性以及认证身份。Windows系统采用Authenticode作为代码签名技术,用来“帮助用户确认当前正在运行代码的创建者……也可以用来验证代码在发布后是否被更改或者篡改过”(Digicert)。微软使用两种方式来实现Authenticode:
- 内嵌方式:将Authenticode签名数据存放在文件中;
- Catalog文件:包含文件指纹(thumbprint)列表的一个文件,该文件经过Authenticode签名(Microsoft Docs)。
在Windows中,许多“经过签名”的文件实际上是采用catalog签名方式。这些“已签名”文件实际上并没有包含Authenticode签名数据块。相反,这些文件实际上采用“代理签名”方式,将文件指纹(哈希)存放到catalog文件中。为了判断文件是否经过签名、采用何种方式签名,我们可以使用PowerShell的Get-AuthenticodeSignature
cmdlet:
有趣的是,最近我发现微软在操作系统版本更新后,“管控的”catalog文件并没有相应得到一致性维护。这意味着早期版本操作系统(如Windows 10 Version 1803 Build 17134.1)中签名的代码(如二进制文件、脚本等)在系统更新后(比如更新至Windows 10 Version 1803 Build 17134.472)可能处于有效状态。简而言之,我们可以利用这一点来滥用老版的、存在漏洞代码。这里我们来讨论一种滥用场景:绕过AWL。
三、绕过应用程序白名单
在一月份时我发表过关于CVE-2018-8492的一篇文章,这个漏洞可以绕过Windows Defender Application Control(Device Guard),使用XML样式表转换来执行未签名scriptlet代码。在Windows Lockdown Policy(WLDP)下,我们可以初始化Microsoft.XMLDOM.1.0
(Microsoft.XMLDOM)COM对象,在“存在漏洞的”transformNode
方法被patch之前,访问和调用该方法:
2018年11月,微软patch(替换)了Microsoft.XML
、MSXML3.DLL
对应的服务端程序,之后transformNode
方法再也无法调用scriptlet代码:
在搭建新的WDAC虚拟机时,我想到了一个问题:我是否可以重新引入老版本代码来“重放攻击”,绕过这种安全控制呢?
在复制一些二进制文件后(在我的测试环境中,我复制了MSXML3.dll
及其依赖项),我发现只要处于相同版本序列中,老版本的文件实际上还处于catalog签名状态,因此自然也会被操作系统所信任:
注意:在某些情况下,WinSxS目录中可能还有存在漏洞的程序文件。
在之前的文章中,我提到了COM劫持技术,这种技术似乎适用于这种catalog文件签名场景。大家都知道,大多数COM类(元)数据存放在HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES\CLSID
注册表键值中,这些元数据实际上会合并到HKEY_CLASSES_ROOT\CLSID
中。有趣的是,攻击者可以在HKEY_CURRENT_USER\SOFTWARE\CLASSES\CLSID
中重新创建类似的结构来覆盖这些值。当合并到HKCR
中时,这些值优先级较高,会覆盖HKLM
中的值。在我们的测试案例中,我们可以利用这种方式,导出HKLM
中Microsoft.XMLDOM.1.0
COM类的Class ID(CLSID
)子健,修改必要的值以便导入HKCU
中,将服务器(InProcServer32
)对应的键值指向我们“之前版本的”MXSML3.dll
库。
将这些值导入注册表后,被修改后的值将成功合并到HKCR
中:
一切准备就绪后,我们可以简单重新执行之前的攻击过程,观察攻击结果:
大功告成。结果表明我们可以利用Catalog文件签名问题,使用老版本、经过签名的代码发起攻击,绕过WDAC。
四、缓解建议
微软并没有通过补丁方式解决核心问题,而是选择在WDAC推荐阻止规则策略中,为某些DLL添加新规则来缓解该问题。尽管这种方式可以阻止已知的几种规避技术,但Catalog文件签名机制仍然存在被滥用的风险,比如WDAC绕过技术等。无论如何,如果大家安装了AWL解决方案,最好还是将这些阻止规则添加到WDAC策略中。
想要检测COM劫持是比较困难的一个任务,这跟当前环境的透明程度以及所部署的EDR解决方案的跟踪配置/功能有关。监控更改的注册表键值(特别是COM类对象以及InprocServer32
/LocalServer32
键值)可能是不错的选择(如果发现替换的程序文件不在System32
/SysWow64
目录中就更加可疑)。此外,我们也可疑重点关注一些有趣的二进制文件,包括scrobj.dll
、msxml3.dll
、msxml6.dll
、mshtml.dll
、wscript.exe
以及cscript.exe
。
这篇文章中提到的一些建议同样可以用来解决WDAC问题。比如可以增加透明度,便于发现Active Scripting、PowerShell以及COM对象实例化滥用操作。
五、参考资料
关于COM、相关WDAC绕过技术以及Windows信任机制方面的内容,我建议大家可以参考其他研究人员提供的如下资料/白皮书:
- COM In 60 Seconds by James Forshaw(@tiraniddo)
- Sneaking Past Device Guard by Philip Tsukerman(@PhilipTsukerman)
- Subverting Trust in Windows by Matt Graeber(@mattifestation)
六、时间线
- 2018年12月:向MSRC反馈该问题,MSRC分配了报告案例
- 2019年3月:MSRC表示将推出补丁,分配CVE编号
- 2019年4月:MSRC决定不推出补丁,而是在WDAC推荐阻止规则策略中添加待阻止的DLL列表