0x00 概述
近年来,Cobalt Strike框架受到了红队成员和威胁参与者的广泛欢迎。由于具有较强的功能性、灵活性和稳定性,它也顺理成章成为了商业化命令与控制框架的领导者。
与此同时,防御人员为了构建Cobalt Strike及其植入物Beacon的可靠签名,已经进行了大量的研究和努力。这篇文章主要研究一些此前未知的威胁指标(IoC)。由于此前已经有大量的研究人员对Cobalt Strike默认配置的签名进行过研究,因此我们在这里就不再重复这方面,而是重点关注一些Cobalt Strike的后漏洞利用功能的内置模块,例如键盘记录器、Mimikatz和屏幕截图模块。
需要说明的是,这里涉及到的威胁指标和行为特征都是根据Cobalt Strike作者提供的信息,在4.2版本的Malleable配置文件中作为可以自定义的选项供攻击者自行设置。
希望这篇文章可以有助于蓝队成员增强其检测能力,同时能够促进红队成员使用更加复杂和定制化的技术。
0x01 分析
我们知道,Cobalt Strike在执行某些命令时会使用一种特定的模式,被称为“Fork-n-Run”。Fork-n-Run模式会产生一个新的进程(也被称为Sacrificial Process),并将功能注入到其中。这种模式有很多好处,其中之一就是可以执行需要长时间运行的任务,不会阻塞Beacon主线程,键盘记录器Keylogger就是一个很好的例子。通常情况下,这些功能需要以反射式DLL的方式来实现。
该框架的最新版本为攻击者提供了很大的灵活性,使其可以自定义注入进程的功能。但除此之外的其他地方并没有太大的变动,而这些地方就是我们需要重点关注的位置。
更具体地来说,没有变动的地方,就是检索注入模块的输出的能力。例如,键盘记录器(Keylogger)模块可以将按键发送回主Beacon进程。但是,键盘记录器模块是无文件形式的,那么与主Beacon进程的通信如何发生?
答案是——通过管道。
管道是用于进程之间相互通信的共享内存,具体可以分为两种类型——命名管道和未命名管道。
顾名思义,命名管道带有名称,可以通过引用该名称的方式进行访问。
未命名管道需要将其句柄传递给其他通信进程,从而交换数据。这个过程可以通过多种方式来完成。
Cobalt Strike同时使用了命名管道和未命名管道在Beacon和Sacrificial Process之间交换数据。
0x02 命名管道
我们发现,当使用一些Cobalt Strike的模块,将反射式DLL注入Sacrificial Process时,会创建具有可预测的规律的命名管道。
请注意,这些命名管道不是用于横向移动的SMB命名管道,可以通过Malleable配置文件对其进行自定义。在4.2版本之前,这个命名管道的名称不能由攻击者修改。
具体而言,一旦启动了作业(Job),Beacon就会创建一个命名管道。管道的名称仅包含十六进制字符,且长度等于模块名称的长度(例如:屏幕截图模块screenshot,长度为10个字符)。我们发现如下模块符合上述特征:
1、键盘记录器 Keylogger
2、屏幕截图工具 Screenshot
3、Mimikatz (dcsync、dpapi、logonpasswords)
4、Powerpick
5、Net (netview)
下面的截图中分别展示了执行“keylogger”命令后,Sysmon事件ID 17和18(分别是管道创建和管道访问)的示例:
我们进行了一些实验,没有发现其他的合法应用程序会创建具有相同命名特征的命名管道。我们随后打算使用这个特征来创建Splunk搜索,搜索过程中使用Sysmon和Yara规则来扫描进程内存。
0x03 匿名管道
并非每个Cobalt Strike命令都会创建一个命名管道,其中一些也会使用匿名(未命名)管道来实现相同的目标。下图展示了发出“execute-assembly”命令后创建的管道:
我们可以对启动长时间运行的程序集所产生的Sacrificial Process进行调试,以确认这一点:
我们在“ntdll!NtWriteFile”函数上设置了一个断点,可以看到,Sacrificial Process在试图写入的句柄与属于管道文件系统(NPFS)的未命名文件相关联:
我们发现,例如“execute-assembly”这类的命令并不像上述示例那样琐碎。那么,我们使用管道可以做些什么呢?
从理论上说,我们可以针对使用匿名管道的进程建立基线。值得关注的是,本地Windows进程通常不会使用匿名管道。因此,我们就可以寻找连接到匿名管道的Windows进程,并从那里开始调查。
之所以在这里要着重提到Windows进程,是因为攻击者经常会将本地Windows二进制文件作为Malleable配置文件中的Sacrificial Process。我们可以从C2Concealer存储库中找到一些已经列出的二进制文件,C2Concealer存储库是一个用于创建随机Malleable配置文件的项目。从下述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,如下所示:
执行此模块后,我们可以识别出以前看到的相同的匿名管道行为:
0x04 检测规则
可以通过多种方法来检测异常命名管道。作为概念验证,我们开发了可以用于扫描进程内存和查找活动实例的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) }
针对Sacrificial Process执行的示例:
.\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!="" | regex PipeName="^\\\\[a-f0-9]{7,10}$"
在对命名管道进行自动化检测的过程中,这种方法可能更容易出现误报。但是,它可以与其他威胁指标结合使用,以获得更准确的结果。
Splunk搜索的示例可以用于获取创建匿名管道的进程,会按照频率由低到高排序:
index="YOUR_INDEX" source="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=17 PipeName=""| rare limit=20 Image
0x05 逃避检测的注意事项
站在红队的视角来看,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”参数中,可以选择合法使用匿名管道的二进制文件,从而减少被检测到的概率。
可以参考官方的Malleable命令说明,以及ThreatExpress的jQuery示例配置文件,从而更加深入地了解Cobalt Strike的Malleable配置文件选项。
0x06 总结
这篇文章展示了两种不同的策略,用于识别终端上使用Cobalt Strike的情况。首先,我们分析与默认模块相关的异常命名管道,然后再将重点转移到统计学的方法上,以识别更为复杂的攻击。
对于红队队员来说,不要使用默认设置和默认模块则变得更为关键。对于蓝队防御者来说,我们希望能够提供一些如何发现该工具的实用建议,让大家可以更加广泛地使用Sysmon等工具对管道异常进行监控。
本文翻译自:https://labs.f-secure.com/blog/detecting-cobalt-strike-default-modules-via-named-pipe-analysis/如若转载,请注明原文地址: