如何利用COMPlus_ETWEnabled隐藏.NET行为

阅读量284352

|

发布时间 : 2020-06-08 10:30:05

x
译文声明

本文是翻译文章,文章原作者 xpnsec,文章来源:blog.xpnsec.com

原文地址:https://blog.xpnsec.com/hiding-your-dotnet-complus-etwenabled/

译文仅供参考,具体内容表达以及含义原文为准。

 

0x00 前言

之前一段时间,我想澄清防御方如何检测内存中加载的Assembly(程序集),并在3月份发表了一篇文章译文),介绍了禁用ETW的一些思路。随后有多个研究人员(包括CneelizBatSec以及modexp)也提供了一些巧妙的、改进版的方法,可以绕过这类检测机制。这些方法都需要篡改ETW子系统,比如拦截并控制对某些函数的调用行为(如用户模式下的EtwEventWrite函数或者NtTraceEvent内核函数),或者解析并控制ETW注册表来避免代码patch行为。

然而其实我们还有一种办法能够禁用针对.NET的ETW:在环境变量中设置COMPlus_ETWEnabled=0

公布这种方法后,有许多人向我咨询,主要想了解我如何发现这个选项、以及该选项的工作原理。因此在本文中,我想与大家分享关于这方面的一些细节。

在深入分析之前,我们需要澄清一点:ETW本不应该被当成一种安全控制解决方案。达成这个共识后,我们更容易理解本文阐述的一些信息。ETW的主要功能是作为一款调试工具,但随着攻击者不断改进payload执行技术,有些防御方开始利用ETW的功能来获取关于某些事件的信息(如.NET Assembly的加载行为)。在ETW的原始设计场景中,我们发现的COMPlus_ETWEnabled有点类似一个安全审核开关,而实际上这只是关闭某些调试功能的一种简单方法。

 

0x01 前缀为COMPlus_的选项

COMPlus_前缀的选项为开发者提供了许多可配置项,开发者可以在运行时进行配置,对CLR造成不同程度的影响,包括:加载替代性JIT、调整性能、转储某个方法的IL等。这些选项可以通过环境变量或者注册表键值来设置,并且其中很多选项没有公开文档。如果想了解每个选项的具体功能,我们可以参考CoreCLR源中的lrconfigvalues.h文件。

如果大家快速分析该文件,会发现其中并不存在COMPlus_ETWEnabled,事实上早在2019年5月31日的某次commit中,CoreCLR就已经删除了该选项。

与许多未公开的功能一样,这些选项可以为攻击者提供比较有趣的一些功能。需要注意的是,这些选项名不一定以COMPlus_作为前缀,比如2007年公开的一篇文章中就使用了名为COR_PROFILER的一个选项,通过MMC.exe实现UAC绕过。

现在我们已经基本了解了这些选项的存在意义以及具体列表,下面继续分析COMPlus_ETWEnabled的发现过程。

 

0x02 寻找COMPlus_ETWEnabled

尽管CoreCLR源中包含大量设置,但许多设置并不适用于我们较为熟悉的标准.NET Framework。

为了检测哪些COMPlus_适用于.NET Framework,我们可以简化思路,在clr.dll中寻找这些前缀的蛛丝马迹,比如clrconfigvalues.h中列出的COMPlus_AltJit选项。

我们可以删除前缀,在IDA中简单搜索字符串,可以发现clr.dll中可能引用到了AltJit,如下图所示:

跟踪引用位置,我们可以找到一个方法CLRConfig::GetConfigValue,该方法以选项名为参数,获取具体值:

以这个信息为索引,搜索重载方法,我们可以找到其他一些方法,这些方法也可以在运行时访问类似的配置选项:

由于微软为CLR贴心提供了匹配的PDB文件,我们可以逐一分析这些方法,查看Xref,寻找哪些引用是潜在的目标,比如:

最后我们可以跟踪该引用,查看传递给CLRConfig::GetConfigValue的参数,从而发现最终使用的选项:

 

0x03 COMPlus_ETWEnabled的作用

发现.NET Framework中存在该选项后,我们还需澄清为什么该选项能够禁用事件跟踪。我们可以在IDA中观察CFG,很快就能知道禁用ETW的原理:

从上图我们可以找到2个代码路径,具体执行的路径取决于CLRConfig::GetConfigValue所返回的COMPlus_ETWEnabled值。如果该选项存在并且返回0值,那么CLR就会跳过上图中蓝色的ETW注册代码块(_McGenEventRegisterEventRegister API的简单封装函数)。

通过这些provider的GUID进一步分析,我们可以看到较为熟悉的代码:

我们在前一篇文章中unhook ETW时也用到了这个GUID({e13c0d23-ccbc-4e12-931b-d9cc2eee27e4}),在微软官方文档中,这个GUID对应的是CLR ETW provider:

 

0x04 总结

希望这篇文章能给大家提供关于该选项的一些启发,从本质上来讲,我们可以通过该选项让CLR跳过.NET ETW provider的注册过程,从而隐蔽相关事件。

为了防御这种攻击,大家可以参考Roberto Rodriguez提供的一些思路,其中详细介绍了许多可用的检测及缓解措施。

本文翻译自blog.xpnsec.com 原文链接。如若转载请注明出处。
分享到:微信
+10赞
收藏
興趣使然的小胃
分享到:微信

发表评论

内容需知
合作单位
  • 安全客
  • 安全客
Copyright © 北京奇虎科技有限公司 三六零数字安全科技集团有限公司 安全客 All Rights Reserved 京ICP备08010314号-66