攻防实战:如何检测或优化内存中的.NET Tradecraft

概述

对于红队的攻击操作来说,使用内存中的Tradecraft所起到的效果变得越来越大,这主要是由于EDR不断进行功能改进,已经使越来越多的蓝队获得了监测运行中内存的能力。

此前,我们曾经讨论过将混淆处理集成到管道中的方法,也讨论过如何绕过Windows事件跟踪的方式,这两种方法都可以有助于减少蓝队用于检测内存中Tradecraft的有效指标。

Pentest Laboratories近期发表了一篇题为《AppDomainManager注入和检测》的文章,其中概述了如何使用AppDomainManager对象实现和检测内存中的.NET执行。在这篇文章的基础上,我们开始思考如何将这些概念应用于其他.NET执行技术,例如Cobalt Strike的execute-assembly,由此我们开展了一系列的研究。对于红队成员来说,了解我们所使用的工具以及工具的劣势,是至关重要的一个方面。

在本文中,我们将说明检测内存中程序集执行的另一种方式,并重点说明能进一步优化Tradecraft的可行策略。

回顾:ETW修补

在讨论本文的主要话题之前,我们首先回顾一下从上一篇文章中学到的内容,在上篇文章中,我们详细介绍了红队是如何修补Windows事件跟踪的函数,以限制正在运行的进程CLR中可见的程序集。在该过程中,涉及到修补ntdll.dll!EtwEventWrite函数,以防止该事件被报告。

我们可以使用.NET程序集选项卡,检查通过ETW在ProcessHacker中报告的程序集,奇热如下所示:

攻防实战:如何检测或优化内存中的.NET Tradecraft_第1张图片

但同时,我们也可以修补EtwEventWrite,使其实现以下的代码返回:

internal static void PatchEtwEventWrite()
{
       bool result;
       var hook = new byte[] { 0xc2, 0x14, 0x00, 0x00 };
       var address = GetProcAddress(LoadLibrary("ntdll.dll"), "EtwEventWrite");
        result = VirtualProtect(address, (UIntPtr)hook.Length, (uint)MemoryProtectionConsts.EXECUTE_READWRITE, out uint oldProtect);
       Marshal.Copy(hook, 0, address, hook.Length);
       result = VirtualProtect(address, (UIntPtr)hook.Length, oldProtect, out uint blackhole);
}

在应用补丁后,将会显示出如下的结果,可以证明成功限制了ETW的有效性:

攻防实战:如何检测或优化内存中的.NET Tradecraft

在这个阶段,我们还希望了解.NET exe在内存中运行时的隐蔽性,并希望能分析Cobalt Strike的beacon execute-assembly功能是如何工作的。

深入分析Cobalt Strike的execute-assembly

Cobalt Strike的execute-assembly提供了漏洞利用后的功能,可以根据malleable配置稳健的spawnto配置,将CLR注入到远程进程中。

在这里,我们不会详细介绍CLR的注入方式,因为在以前的文章中已经做过说明。但是,值得注意的是,在利用CLR时,会将CLR DLL clr.ddl、clrjit.dll和其他相关文件加载到任何正在运行的进程中,并且Cobalt Strikes的execute-assembly也不例外:

攻防实战:如何检测或优化内存中的.NET Tradecraft

当然,这就为蓝队如何寻找内存中的.NET执行提供了一个起点,可以缩小可能承载.NET exe进程的范围。毫无疑问,这可以作为一个基线,以识别不应加载的CLR进程异常。TheWover还提供了一个出色的工具用来监视模块加载,可以作为检测CLR加载过程的一种方法。

我们可以使用process-inject块中的选项,在某种程度上控制远程进程注入的配置,并且还可以使用startrwx和userwx设置来调整初始和最终页面的权限。首先,要允许使用READWRITE权限分配内存,然后将VirtualProtected分配给EXECUTE_READ,以防范蓝队通常情况下搜索EXECUTE_READWRITE设置。

让我们来执行一个长期运行的进程,以便可以正确分析注入过程中发生的事情:

public static void Main(string[] args)
{
       while (true)
       {
              Console.WriteLine("Sleeping");
              Thread.Sleep(60000);
       

你可能感兴趣的:(攻防实战:如何检测或优化内存中的.NET Tradecraft)