一种劫持COM服务器并绕过微软反恶意软件扫描接口(AMSI)的方法 - 嘶吼 RoarTalk – 网络安全行业综合服务平台,4hou.com

一种劫持COM服务器并绕过微软反恶意软件扫描接口(AMSI)的方法

丝绸之路 系统安全 2017-08-08 11:35:42
202658
收藏

导语:Microsoft的反恶意软件扫描接口(AMSI)在Windows 10中被引入,作为标准接口,它可以让AV引擎将签名应用于内存和磁盘上的缓冲区。

Microsoft的反恶意软件扫描接口(AMSI)在Windows 10中被引入,作为标准接口,它可以让AV引擎将签名应用于内存和磁盘上的缓冲区。这使得AV产品能够在脚本解释之前“hook”,这意味着任何经过混淆或加密的PS程序都经过了解密程序的解密。你可以在这里这里阅读有关AMSI的更多信息。这篇文章将介绍一种通过劫持COM服务器来绕过AMSI的方式,并分析Microsoft是如何在build#16232 中修复它的,然后我又是如何绕过该修复的。

这个问题在5月3日提交给了微软,并且已经得到修复,并发布了Build#16232中的“深度防御”补丁。

下面是一个通过PowerShell进行的AMSI测试示例,当AMSI接受暴露的脚本块并将其传递给Defender进行分析时,内容如下:

amsi_trigger.png

正如你所看到的,AMSI接受了代码并将其传递给被调用的Invoke-Expression。由于该代码被认为是恶意的,因此被阻止执行。

那么问题来了:这个过程是如何工作的? 查看amsi.dll的导出,可以看到AMSI导出的各种函数调用:

amsi_exports.png

amsi!DllGetClassObjectamsi!DllRegisterServer很快引发我的思考,因为这些都是COM的入口点,用于方便的实例化一个COM对象。幸运的是,COM服务器很容易劫持,因为中等完整性流程默认在查找HKCR / HKLM之前搜索当前用户注册表配置单元(HKCU)以用于COM服务器。

查看IDA,我们可以看到COM接口ID(IID)和ClassID(CLSID)传递给CoCreateInstance():

co_createinstance.png

我们可以通过查看ProcMon的结果来验证这一点:

amsi_procmon.png

最终发生的事情是,AMSI的扫描功能似乎是通过自己的COM服务器来实现的,当COM服务器被实例化时会被暴露出来。当AMSI加载时,它实例化其自有的COM组件,并暴露了诸如amsi!AmsiOpenSession,amsi!AmsiScanBuffer,amsi!AmsiScanString和amsi!AmsiCloseSession之类的方法。如果我们强制COM实例化失败,AMSI将无法访问扫描恶意内容所需的方法。

由于COM服务器首先通过HKCU配置单元进行解析,因此普通用户可以劫持InProcServer32密钥并注册不存在的DLL(或者如果你也可以执行恶意的代码)。为了做到这一点,有两个注册表项需要处理:

hijack_regentry.png

当AMSI尝试实例化其COM组件时,它将查询其注册的CLSID并返回不存在的COM服务器。这导致加载失败,并阻止任何扫描方法被访问,最终使AMSI不可用。

你可以看到,导入上述注册表更改将导致“C: IDontExist”作为COM服务器返回:

hijack_execution.png

现在,当我们尝试运行我们的“恶意”AMSI测试样本时,你将注意到它被允许执行,因为AMSI无法通过其COM接口访问任何扫描方法:

amsi_bypass_execution.png

你可以在这里找到注册表更改:

https://gist.github.com/enigma0x3/00990303951942775ebb834d5502f1a6

现在我们可以理解这个bug了,那么我们来看看微软是如何在build#16232中修复它的。由于amsi.dll也是AMSI的COM服务器,因此将这两个DLL分开似乎是一个很好的办法。看到diff,AmsiInitialize函数突出显示,因为它可能包含了实际实例化AMSI的逻辑。

amsi_diff.png

在左侧,是原来的AMSI DLL,在右边的是新更新的AMSI DLL。如你所见,Microsoft似乎删除了对CoCreateInstance()的调用,并将其替换为直接调用DllGetClassObject()。CoCreateInstance()可以定义为用于实例化使用CoGetClassObject()实现的COM对象的高级函数。在分辨完成(部分通过注册表CLSID查找)和定位COM服务器之后,服务器的导出函数“DllGetClassObject()”将被调用。通过直接调用amsi.dll的DllGetClassObject()函数替换CoCreateInstance,避免了注册表解析。由于AMSI不再在COM服务器的注册表中查询CLSID,因此我们无法再劫持它。

现在我们知道了修复过程,那么我们该如何去绕过它呢?在进行绕过之前,重要的是我们要明白,自2006年以来,这个特定的bug已被公布和讨论。基本上,脚本解释器(如PowerShell)从工作目录加载amsi.dll,而不是从安全路径(如System32)加载它。由于这个原因,我们可以将PowerShell.exe复制到我们可以写入的目录,并加载易受攻击的amsi.dll版本。基于这一点,我们可以利用bat劫持DLL,或者我们可以创建相同的注册表项来劫持AMSI的COM组件。由于这个易受攻击的AMSI版本仍然会调用CoCreateInstance(),我们可以再次劫持注册表搜索顺序。

首先,我们可以通过为powershell.exe和AMSI的CLSID创建一个ProcMon过滤器来验证修补后的amsi.dll版本不通过注册表查询COM服务器。当PowerShell启动时,你将注意到没有任何结果出现:

procmon_filter.png

接下来,我们删除易受攻击的AMSI DLL并将PowerShell移动到同一目录。如你所见,现在正在查询注册表来定位AMSI的COM服务器:

amsi_dll_hijack.png

使用易受攻击的AMSI DLL,我们现在可以执行COM服务器劫持:

fix_bypass_execution.png

检测方案:尽管在构建#16232补丁中进行了修复,但仍然可以通过使用旧的,易受攻击的AMSI DLL执行DLL劫持来执行此操作。为了检测这种攻击手法,监视对于在其正常目录之外执行的任何二进制文件(wscript,cscript,PowerShell)(通过命令行日志记录等)是比较理想的方法。由于绕过修复程序需要将二进制文件移动到用户可写位置,所以在非标准位置执行这些命令就可以抓住这一攻击行为。

  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论

 
本站4hou.com,所使用的字体和图片文字等素材部分来源于原作者或互联网共享平台。如使用任何字体和图片文字有侵犯其版权所有方的,嘶吼将配合联系原作者核实,并做出删除处理。
©2024 北京嘶吼文化传媒有限公司 京ICP备16063439号-1 本站由 提供云计算服务