欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

无招胜有招: 看我如何通过劫持COM服务器绕过AMSI

来源:本站整理 作者:佚名 时间:2017-08-22 TAG: 我要投稿


在Windows 10中,Microsoft的反恶意软件扫描接口(AMSI)被作为新功能被引入,作为标准接口,该功能可以让反病毒引擎将特征规则应用于机器的内存和磁盘上的缓冲区中去。这使的反病毒产品能够在恶意程序的脚本被解释执行之前执行劫持操作,这在一定程度上意味着任何的代码混淆或加密都有相对应的例程去还原和解密程序。如果需要更多详细的有关AMSI的信息,您可以在这里阅读有关AMSI的更多信息。
在这篇文章中,我们将阐述一种通过劫持COM服务器来绕过AMSI的方法, 并分析Microsoft如何在build#16232中修复该绕过,然后再讨论如何再次绕过微软对该漏洞的修复。
通过劫持COM服务器来绕过AMSI的这个问题在5月3日我们向微软递交了报告,并且微软官方已经修复了该漏洞,具体修复信息可见Build#16232中的“深度防御”补丁。
在本文中,我们的实验是一个通过PowerShell进行的AMSI测试示例,测试过程是当AMSI模块接受外部传进来的脚本块并将其传递给Defender进行分析的时候进行劫持操作,具体可见下图所示:

正如你所看到的,AMSI接受了我们构造的恶意代码并将该代码块传递给被调用的Invoke-Expression。由于该代码被认为是恶意的,因此 该代码块被阻止执行。这里需要我们去研究的是:这种阻止恶意代码执行操作是如何工作的呢 ?之后我们通过查看amsi.dll的导出,可以看到AMSI导出的各种函数调用:

通过查看AMSI导出的函数,我们可以发现一些很重要的函数信息,那就是amsi!DllGetClassObject和amsi!DllRegisterServer这两个函数 ,因为这些都是COM入口点,这些函数都是用于方便实例化一个COM对象的。幸运的是,COM服务器易于劫持,因为COM服务在处理 流程上默认在查找HKCR/HKLM之前会去先搜索当前用户的注册表配置单元(HKCU) ,以用于COM服务器来正常处理。这个过程我们在IDA中可以看出,从图中 我们可以看到COM服务接口ID(IID)和ClassID(CLSID)传递给CoCreateInstance():

甚至,我们可以通过查看ProcMon来验证这一点:

通过以上的分析最终我们可以发现,AMSI扫描恶意程序的功能似乎是通过自己的COM服务器来实现的,该功能在COM服务器被实例化时被导出。当AMSI加载时,它首先实例化其COM组件,它导出了诸如amsi!AmsiOpenSession,amsi!AmsiScanBuffer,amsi!AmsiScanString和amsi!AmsiCloseSession之类的函数。在这个过程中如果我们强制COM实例化失败,那么AMSI将无法调用用来扫描恶意程序内容所需的函数方法。由于COM服务器首先通过HKCU配置单元进行解析,因此普通用户可以劫持InProcServer32键值并注册不存在的DLL(或者是一段恶意执行的代码)。为了做到这一点,有两个注册表项需要修改:

劫持COM服务的整个过程是:当AMSI尝试实例化其COM组件时,它将查询其在注册表中注册的CLSID并返回 一个不存在的数值。这将导致其加载失败,并阻止任何扫描恶意软件的方法被访问,最终使得AMSI不可使用。您可以看到,导入上述更改的注册表将导致COM服务器返回”C:\IDontExist”:

现在,当我们尝试运行我们的“恶意”的AMSI测试样本时,我们可以发现我们的恶意代码段被允许执行,因为AMSI无法通过其COM接口访问任何扫描恶意程序的方法 ,结果如下图所示:

您可以在这里找到更改注册表的方法:
https://gist.github.com/enigma0x3/00990303951942775ebb834d5502f1a6
现在我们可以看看微软如何在build#16232中修复该漏洞。由于amsi.dll也是AMSI的COM服务器,因此将这两个DLL分开似乎是一个很好的修复方法。我们来看一下漏洞被修复前后的不同,从图中可以看到AmsiInitialize函数,它可能包含了实际实例化AMSI的逻辑代码。

在左侧,我们有旧的AMSI DLL,在右边,我们有新更新的AMSI DLL。如您所见,Microsoft似乎删除了对CoCreateInstance()的调用,并将其替换为直接调用DllGetClassObject()。 CoCreateInstance()可以定义为高级函数,该函数用于实例化使用CoGetClassObject()生成的COM例程 。该函数解析完成后(部分通过注册表CLSID查找)以及定位到COM服务器后,服务器的导出函数“DllGetClassObject()”将被调用。通过直接调用amsi.dll的DllGetClassObject()函数替换CoCreateInstance,这一修复方法避免了注册表解析操作,由于AMSI不再在COM服务器的注册表中查询CLSID,因此我们无法再劫持它。

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载