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

在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,因此我们无法再劫持它。

现在我们知道修复,那么我们如何去绕过它呢?在进行研究之前,我们需要明白的是:基本上,脚本解释器(如PowerShell)从工作目录加载amsi.dll,而不是从安全路径(如System32)加载它。由于这个原因,我们可以将PowerShell.exe复制到我们可以写入的目录,并 将易受攻击的amsi.dll版本放到这个目录中。通过这些操作后,我们获许就可以劫持DLL,或者我们可以创建相同的注册表项来劫持AMSI的COM组件。由于这个易受攻击的AMSI版本仍然调用CoCreateInstance()函数,因此我们仍然可以通过劫持注册表的搜索顺序来劫持AMSI,整个操作方法如下:

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

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

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

总结:

尽管微软在补丁#16232中对该漏洞进行了修复,但仍然可以通过使用旧的,易受攻击的AMSI DLL执行DLL劫持来执行劫持操作。 关于防御方法,我们觉得对那些在正常目录之外执行任何的二进制文件(wscript,cscript,PowerShell)操作进行监视操作将是一个好的想法。 由于绕过修复补丁需要将二进制文件移动到用户可写位置,所以在非标准位置执行这些命令可以被当成一种异常的操作行为。

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2017-08-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏LanceToBigData

linux(二)之linux常用命令一

linux的命令非常之多,命令多就算了关键每个命令还有很多的参数。不过其实并不要去害怕它。 你只要常去用,并且的话,大部分你只要记住命令,参数不记得我们可以去查...

25280
来自专栏企鹅号快讯

PHP代码审计

代码审计顾名思义就是检查源代码中的缺点和错误信息,分析并找到这些问题引发的安全漏洞,并提供代码修订措施和建议。PHP代码审计审计套路通读全文法 ...

559100
来自专栏邹立巍的专栏

Linux 的进程间通信:消息队列

Linux 环境提供了 XSI 和 POSIX 两套消息队列,本文将帮助您掌握以下内容:如何使用 XSI 消息队列,如何使用 POSIX 消息队列,它们的底层实...

83700
来自专栏IT技术精选文摘

JVM致命错误日志(hs_err_pid.log)分析

当jvm出现致命错误时,会生成一个错误文件 hs_err_pid<pid>.log,其中包括了导致jvm crash的重要信息,可以通过分析该文件定位到导致cr...

68050
来自专栏Ken的杂谈

基于GitLab的Code Review教程

也就是说,使用GitLab进行Code Review就是在分支合并环节发起Merge Request,然后Code Review完成后将代码合并到目标分支。

1.7K30
来自专栏IMWeb前端团队

浏览器中的ECMAScript模块(译)

本文作者:IMWeb zzbozheng 原文出处:IMWeb社区 未经同意,禁止转载 原文:https://jakearchibald.com/20...

21480
来自专栏追不上乌龟的兔子

用.NET Core构建安全的容器化的微服务

微服务热潮正在如火如荼地进行,也有着充分的理由。它不是每个问题的银弹,但它无疑成为企业软件系统中可扩展性和弹性的实用解决方案。

42340
来自专栏C/C++基础

shell脚本实例

检查脚本书写完成后,需要crontab来定期执行该脚本,意在每隔多长时间去检测一次。crontab命令选项如下:

13120
来自专栏Web项目聚集地

三周学会小程序第五讲:登录的原理和实现

前面我们耗费在环境搭建上面已经很多时间,这一讲开始真正的和小程序功能对接。 登录便是小程序的开始,小程序可以方便的使用微信登录,获取用户的个人信息,这样我们就能...

13820
来自专栏匠心独运的博客

消息中间件—RabbitMQ(集群监控篇1)

摘要:任何没有监控的系统上线,一旦在生产环境发生故障,那么排查和修复问题的及时性将无法得到保证

30530

扫码关注云+社区

领取腾讯云代金券