如何利用COMPlus_ETWEnabled隐藏.NET行为

admin 2020年6月30日16:37:28评论514 views字数 2073阅读6分54秒阅读模式

如何利用COMPlus_ETWEnabled隐藏.NET行为

 

0x00 前言

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

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

如何利用COMPlus_ETWEnabled隐藏.NET行为

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

在深入分析之前,我们需要澄清一点: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,如下图所示:

如何利用COMPlus_ETWEnabled隐藏.NET行为

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

如何利用COMPlus_ETWEnabled隐藏.NET行为

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

如何利用COMPlus_ETWEnabled隐藏.NET行为

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

如何利用COMPlus_ETWEnabled隐藏.NET行为

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

如何利用COMPlus_ETWEnabled隐藏.NET行为

 

0x03 COMPlus_ETWEnabled的作用

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

如何利用COMPlus_ETWEnabled隐藏.NET行为

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

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

如何利用COMPlus_ETWEnabled隐藏.NET行为

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

如何利用COMPlus_ETWEnabled隐藏.NET行为

 

0x04 总结

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

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

本文来源于互联网:如何利用COMPlus_ETWEnabled隐藏.NET行为

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2020年6月30日16:37:28
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   如何利用COMPlus_ETWEnabled隐藏.NET行为http://cn-sec.com/archives/78213.html

发表评论

匿名网友 填写信息