通过命名管道分析检测Cobalt Strike默认模块

通过命名管道分析检测Cobalt Strike默认模块

介绍

近年来,Cobalt Strike框架在红队成员和威胁参与者之间获得了广泛的欢迎。它的功能性,灵活性和稳定性使其成为市售Command&Control框架的最新技术。

为建立Cobalt Strike及其植入物Beacon的可靠签名,已经做出了相当大的努力。这篇文章的目的是研究一些以前未知的妥协指标(IoC)。这篇文章不会涵盖默认Cobalt Strike配置的签名-其他论文对此进行了深入研究。取而代之的是,我们将注意力集中在一些提供Cobalt Strike的后期开发功能的内置模块上,例如键盘记录器,Mimikatz和屏幕截图模块。

必须指出的是,IoC /行为是由Cobalt Strike的作者提出的,并随后在4.2韧性配置文件中作为可自定义的设置向操作员公开。

希望此文将有助于双方防御者增强其检测能力,并迫使红队成员使用更复杂和定制的技术(雨苁–红队成员:我特码谢谢你)。

分析

众所周知,Cobalt Strike在执行某些命令时会使用一种特定的模式,称为“ Fork-n-Run” 。“ Fork-n-Run”模式包括产生新流程(也称为牺牲流程)并将功能注入其中。这种模式提供了许多好处,其中之一就是可以执行长时间运行的任务,而“ keylogger”就是一个很好的例子,而又不会阻塞Beacon主线程。通常,这些功能被实现为反射DLL。

该框架的最新版本为操作员提供了很大的灵活性 ,使其可以自定义功能注入过程。但是,某些一般方面并没有太大变化,这就是我们要重点关注的方面。

更具体地,保持不变的特征是检索注入模块的输出的能力。例如,“按键记录器”模块能够将按下的按键发送回主信标过程。但是,由于“ keylogger”模块完全没有文件,与主信标过程的通信如何发生?

答案:管道!(pipes)

管道是共享的内存,用于进程之间相互通信。从根本上讲,管道有两种类型:命名管道和未命名管道。

  • 顾名思义,命名管道具有名称,可以通过引用该名称进行访问。
  • 未命名的管道,需要将其句柄传递给其他通信进程以交换数据。这可以通过多种方式来完成。 

Cobalt Strike使用命名管道和未命名管道在信标及其牺牲过程之间交换数据。

命名管道

F-Secure观察到,当使用一些Cobalt Strike的模块将反射的DLL注入牺牲过程时,将创建具有可预测模式的命名管道。

请注意,这些命名管道不是用于横向移动的SMB命名管道,可以通过可延展的轮廓对其进行自定义。在4.2版之前,此命名管道的名称不能由操作员修改。

更具体地说,据观察,一旦启动了“作业”,信标就创建了一个命名管道。管道的名称仅包含十六进制字符,并且发现其长度等于模块名称的长度(例如,屏幕截图模块为10个字符)。一些具有此行为的模块:

  • 键盘记录器
  • 屏幕截图
  • Mimikatz(dcsync,dpapi,登录密码)
  • Powerpick
  • Net (netview)

下面的屏幕快照显示了执行“ keylogger”命令后Sysmon事件ID 17和18(分别创建和访问管道)的示例:

进行了有限的实验,但是未找到其他合法应用程序来创建具有相同命名约定的命名管道。我们稍后将使用此信息来创建Splunk搜索,该搜索使用Sysmon和Yara规则来扫描进程内存。

匿名管道

并非每个Cobalt Strike命令都会创建一个命名管道,其中一些将使用匿名(未命名)管道来达到相同的结果。下图显示了发出“ execute-assembly”命令后创建的管道的实例:

我们可以通过调试启动长时间运行的程序集后产生的牺牲过程来确认:

检测Cobalt Strike

在“ ntdll!NtWriteFile”函数上设置了一个断点,并且可以看到,牺牲进程试图写入的句柄与属于管道文件系统(Npfs)的未命名文件相关联:

检测Cobalt Strike

如我们所见,发现诸如“ execute-assembly”之类的命令并不像上面的示例那样琐碎。使用管道可以做些什么吗?

从理论上讲,我们可以为使用匿名管道的流程建立基线。有趣的结果是,本机Windows进程通常不使用匿名管道。因此,我们可以寻找连接到匿名管道的Windows进程并从那里进行调查。

我们之所以提到“ Windows进程”,是因为攻击者经常将本机Windows二进制文件用作可延展配置文件中的牺牲进程。这样的例子是C2Concealer存储库中列出的二进制文件,C2Concealer存储库是一个用于创建随机延展性轮廓的项目。我们可以从下面的C2Concealer默认配置中看到可执行文件:

''
#################################################
Data set containing post_ex block data, including
spawn-to processes. 
#################################################
'''
#CUSTOMIZE THIS LIST#
spawn_processes = ['runonce.exe','svchost.exe','regsvr32.exe','WUAUCLT.exe']

可以看到,上述过程用于后期开发作业。它们通常都不使用匿名管道与不同的进程进行通信。因此,可以使用它执行搜索并最终创建检测规则。

在实验过程中,发现以下Windows二进制文件使用匿名管道进行进程间通信:

  • wsmprovhost.exe
  • ngen.exe
  • splunk.exe
  • splunkd.exe
  • firefox.exe

这同样适用于通过Cobalt Strike的dllspawn API执行的自定义反射DLL,因为基本的通信机制是相同的。这样的一个例子是Outflank的Ps-Tools存储库。Ps-Tools是与Cobalt Strike完全兼容的rDLL的集合,允许操作员监视过程活动。让我们执行“ psw”模块,该模块用于枚举活动的Windows,如下所示:

检测Cobalt Strike

执行此模块,我们可以识别出以前看到的相同匿名管道行为:

检测Cobalt Strike

检测规则

可以通过多种方式来检测异常的命名管道。作为概念验证,我们开发了可用于扫描进程内存和查找活动实例的Yara签名,以及可与Sysmon结合使用的Splunk搜索。

Yara规则如下所示:

rule cs_job_pipe
{
    meta:
        description = "Detects CobaltStrike Post Exploitation Named Pipes"
        author = "Riccardo Ancarani & Jon Cave"
        date = "2020-10-04"
    strings:
        $pipe = /\\\\\.\\pipe\\[0-9a-f]{7,10}/ ascii wide fullword
        $guidPipe = /\\\\\.\\pipe\\[0-9a-f]{8}\-/ ascii wide
    condition:
        $pipe and not ($guidPipe)
}

 针对牺牲过程执行的示例:

.\yara64.exe .\cs-job-pipe.yar -s 9908
cs_job_pipe 9908
0x13372b7b698:$pipe: \\.\pipe\928316d80
0x13372bf3940:$pipe: \\x00\\x00.\x00\\x00p\x00i\x00p\x00e\x00\\x009\x002\x008\x003\x001\x006\x00d\x008\x000\x00

下面的Splunk搜索可用于提醒创建与上述模式匹配的命名管道:

index="YOUR_INDEX" source="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=17 PipeName!="<Anonymous Pipe>"   | regex PipeName="^\\\\[a-f0-9]{7,10}$"

关于使用匿名管道进行自动检测,此方法可能更容易出现误报。但是,它可以与其他IOC结合使用以获得更好的结果。

Splunk搜索的示例,可用于获取创建匿名管道的进程,按最小频率排序:

index="YOUR_INDEX" source="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=17 PipeName="<Anonymous Pipe>"| rare limit=20 Image

Opsec注意事项

从红队的角度来看,Cobalt Strike 4.2版使操作员能够修改上述命名管道命名约定。实际上,可以在“ post-ex”块中配置“ pipename”参数,其名称最好与环境中使用的管道混合。

下面显示了一个“ post-ex”块的示例:

post-ex {
    
    set spawnto_x86 "%windir%\\syswow64\\dllhost.exe";
    set spawnto_x64 "%windir%\\sysnative\\dllhost.exe";

    set obfuscate "true";
    set smartinject "true";
    set amsi_disable "true";

    set pipename "pipe\\CtxSharefilepipe###,";
    
}

此外,在“ spawnto_x86”和“ spawnto_x64”参数中选择合法使用匿名管道的二进制文件将减少被检测到的机会。

官方延展性命令的参考ThreatExpress’ jQuery的示例性配置文件是学习更多有关Cobalt Strike的延展性配置文件选项巨大的资源。

总结思想

这篇文章展示了两种不同的策略来识别端点内的Cobalt Strike使用情况:我们首先分析与默认模块关联的异常命名管道,然后将重点转移到更加统计的方法上,以识别更复杂的攻击。

对于攻击者,我们加强了远离默认设置和模块的重要性。对于防御者,我们希望就如何发现此特定工具提供一些实用建议,并更广泛地使用Sysmon等工具监视管道异常。

from