关键词:信标、数据集、Cobalt Strike

本篇博客的作者团队RIFT在三年多前发布了关于识别Cobalt Strike团队服务器的信息,目前已经从超过24,000个活跃的团队服务器中收集了超过128,000个信标。现在作者将该信标数据集与用于研究和解析Cobalt Strike相关数据的Python库dissect.cobaltstrike的开源版本一起公开发布。发布的数据集包含从2018年到2022年的历史信标元数据。本篇博客将重点介绍其中一些发现,供读者参考。

Cobalt Strike信标数据集

数据集beacons.jsonl.gz是一个GZIP压缩文件,包含128,340行JSON格式的信标元数据作为。读者可以从以下存储库下载该数据集,并查看随附的Jupyter notebook:

  • https://github.com/fox-it/cobaltstrike-beacon-data

该数据集涵盖了从2018年7月到2022年2月近四年的历史Cobalt Strike信标元数据。然而由于存档问题,丢失了2019年内五个月的数据。此外,该数据集主要关注团队服务器中HTTP端口80、443和DNS上的x86信标,不包含来自其他来源的任何信标,例如 VirusTotal。

由于数据集大小限制,信标有效负载本身不在数据集中。相反,数据集中会存储不同的信标配置设置,包括其他元数据,例如:

  • 收集信标的日期以及来自哪个IP地址和端口

  • GeoIP + ASN元数据

  • DER格式的TLS证书

  • PE信息(时间戳、magic_mz、magic_pe、stage_prepend、stage_append)

  • 如果负载是XOR编码的,哪个XOR密钥用于模糊配置

  • 原始信标配置字节,方便手动解析信标配置。(例如使用dissect.cobaltstrike或其他选择的解析器)

虽然有一些简单的方法可以从信标有效负载中识别破解或盗版的Cobalt Strike Team服务器,但很难分辨出所使用的方法。因此,该数据集是未经过滤、完全公开的,并且包含收集的所有信标。

信标介绍以及如何获取

Cobalt Strike信标是通过首先识别Internet上的团队服务器,然后使用checksum8 HTTP请求下载信标来获取的。通过蜜罐,可以看出并非只有RIFT在挖掘信标。现在很多团队都在这样做。与Cobalt Strike检测相关的博客文章和示例脚本的增加,很大程度上都归因于此,当然, Cobalt Strike的日益普及也是一个因素。

Cobalt Strike扫描探测的发展十分引人注目,先后出现了用于识别团队服务器和检索信标的不同技术和策略。有些甚至跳过了识别部分,直接去请求信标。这种方式可能很复杂,但对于某些威胁参与者来说值得重视。

如果运行面向公众的Web服务器,可以通过检查HTTP访问日志中常见的checksum8类似请求来验证这种增加的扫描,例如,使用图1所示的grep命令:

图1 针对x86和x64信标的checksum8请求

上面显示的请求是在2021年2月访问了托管真实网站的普通网络服务器的checksum8请求(针对x86和x64信标)。

此外也可以使用作者团队提供的checksum8-accesslogs.py脚本完成扫描识别。采用checksum8验证的该方式检测结果更准确,还可以输出统计信息。图2是一个输出为x86和x64信标的HTTP请求,该请求命中一个蜜罐并生成相应的统计信息:

图2 checksum8-accesslog.py脚本在访问日志中发现可能的信标阶段请求

如图3所示,在输出中还可以看到正在使用的不同信标扫描技术。通过绘制统计数据,可以看到蜜罐上的信标扫描明显增加:

图3 Cobalt Strike信标扫描增长趋势

Cobalt Strike版本更替情况

鉴于拥有多年的信标元数据,作者团队可以很好地描绘Internet上活跃的Cobalt Strike服务器以及其使用的版本的情况。

为了提取Cobalt Strike版本数据,使用了以下两种方法:

(1) 使用信标设置常量

当引入新的Cobalt Strike信标配置设置时,设置常量会增加然后进行分配。可以根据提取的信标配置中的最高可用常量来推断版本。

(2) 使用PE导出时间戳

BlackBerry在《在黑暗中寻找信标:网络威胁情报指南》一书中也记录了这一方式,这是确定确切版本的更准确方法。

dissect.cobaltstrike支持这两种推断版本号的方法,并且更倾向于使用PE导出时间戳的方法。

为方便起见,数据集已包含该beacon_version字段,并且基于PE导出时间戳。使用此字段,可以生成图4所示图表,其显示了Internet上使用的不同Cobalt Strike版本随时间变化的情况:

图4 Cobalt Strike版本随时间变化趋势

可以看出,在2021年4月,在线Cobalt Strike服务器和信标出现了相当突出的高峰,但除了当月修改的(可能是恶意的)信标增加了3%外不确定是什么原因造成的。

图5更清晰地显示了不同版本之间的采用度和流行度:

图5 Cobalt Strike各版本使用百分比

可以看出,Cobalt Strike 4.0(2019年12月发布)在2020年1月至2021年1月期间仍然很受欢迎。

信标水印统计

自Cobalt Strike 3.10(2017年12月发布)以来,信标包含一个名为SETTING_WATERMARK的设置。这个水印值由授权服务器发行,在每个Cobalt Strike安装中是唯一的。

但是,破解或盗版版本通常会将其修补为固定值,这样可以轻松识别哪些信标更有可能是恶意的。这种可能性与迄今为止的事件响应活动一致,其中与网络攻击相关的信标使用了已知的不良水印。

恶意行为者很难申请试用或购买Cobalt Strike的合法副本,因为每个合法用户都要经过审查和筛选。由于这些措施,在暗网上购买Cobalt Strike副本的要价很高。例如,Conti投资60.000美元购买了一份Cobalt Strike的有效副本。图6是排名前50的Cobalt Strike信标水印,如果在这前50个信标水印中发现带有水印的信标,那么它很可能是恶意的。

图6 排名前50的Cobalt Strike信标水印

定制信标

在解析收集到的信标时,会发现一些信标被修改了,例如,使用自定义shellcode存根、非默认XOR密钥或重新分配的信标设置。因此,具有大量自定义的信标无法正确转储并且不包含在数据集中。

信标有效负载中的配置块通常使用单字节XOR密钥进行混淆。根据Cobalt Strike版本,默认密钥是0x2e或0x69。使用非默认XOR密钥需要用户修改信标或团队服务器,因为默认情况下无法配置。图7是在信标数据集上看到的XOR密钥的全貌:

图7 自定义XOR密钥

虽然使用自定义XOR密钥可能会使信标成为异常值,但确实可以保护自己免受一些现有的Cobalt Strike配置转储程序的影响。dissect.cobaltstrike支持在默认XOR密钥不起作用时尝试使用所有XOR密钥。例如,可以将命令行标志--all-xor-keys传递给beacon-dump命令。

PE组件

虽然大多数现有的Cobalt Strike转储程序都专注于信标设置,但Malleable C2配置文件中的一些设置不会最终出现在有效载荷的嵌入式信标配置中。例如,Malleable C2 配置文件中的一些可移植执行文件(PE)设置直接应用于信标负载。dissect.cobaltstrike支持提取此信息,数据集包括以下提取的PE标头元数据:

  • magic_mz:MZ标头

  • magic_pe:PE标头

  • pe_compile_stamp:PE编译时间戳

  • pe_export_stamp:导出表的时间戳

  • stage_prepend:附加到信标载荷前面的(shellcode)字节

  • stage_append:附加到信标载荷后面的字节

作者列举了所有常见的 ASCII字节形式的stage_prepend字节,如图8所示。这些字节位于MZ标头前面,并且必须是有效的汇编代码,但在作为shellcode执行时会导致无法操作。

图8 常见ASCII stage_prepend shellcode 字节

图9是stage_prepend shellcode “JFIFJFIF”的反汇编示例,可以看到它主要由ESI单增和EDX单减指令构成,所以不完全是一个无操作的shellcode,但很可能也不影响暂存过程。

图9 反汇编shellcode JFIFJFIF

使用空格加水印的releasenotes.txt

Cobalt Strike在HTTP 服务器标头中的空格之后,还有一个称为SETTING_SPAWNTO的信标设置,其填充为文件releasenotes.txt(或者同一文件目录中具有相同checksum8值152和相同文件名长度的另一个文件)的MD5哈希值。

当激活或更新Cobalt Strike服务器时,会自动从许可证服务器下载releasenotes.txt。这个文件很可能是使用空白字符加水印的,从而使该文件及其MD5哈希值在每次安装时都是唯一的。许可证服务器可能会跟踪所有这些唯一生成的文件,以帮助打击盗版和阻止Cobalt Strike的泄漏。在一些盗版信标中,该字段全为零,或者不可用,这意味着盗版制作者知道此文件的作用,并决定不将其发送到盗版版本中,否则字段值已被修补。尽管如此,在使用时,该字段仍可用于搜索或关联信标。两个版本的差别如图10所示,注意文件之间行尾的细微空格变化:

图10 两个releasenotes.txt文件间的空格变化

使用dissect.cobaltstrike分析信标有效载荷

作者团队开源了用于解析Cobalt Strike的Python库,名为dissect.cobaltstrike。该库在PyPI上可用,但需要Python 3.6或更高版本。可以使用pip安装:

图11 pip安装dissect.cobaltstrike命令

项目的GitHub存储库为:https ://github.com/fox-it/dissect.cobaltstrike

目前存储库安装了三个命令行工具:

(1) beacon-dump—用于从信标载荷中导出配置(也适用于内存转储)。

(2) beacon-xordecode—用于经过异或编码的载荷解码的独立工具。

(3) c2profile-dump—用于读取和解析Malleable C2配置文件。

如图12所示,信标转储的一个简洁功能是将信标配置转储回来,因为它是与可扩展 C2 配置文件兼容的等效项:

图12 将信标设置转储为可扩展 C2 配置文件

结束语

信标数据集已被证明非常有用,尤其是数据集包含的历史特性,提高了在事件响应参与期间的洞察力。作者团队提供的这个数据集, 可用于C2基础设施映射、威胁主体跟踪、威胁狩猎、高质量威胁指标提取、检测工程实现等等。希望这个数据集以及相关Python库能够对社区有所帮助。另外,读者可从以下几方面拓展:

(1) 使用DBSCAN等聚类算法对信标和C2配置文件特征进行聚类。

(2) 改进恶意信标的分类。

(3) 使用GeoIP ASN数据确定最恶意信标的托管位置。

(4) 分析x509证书数据,例如是否自签名。

(5) 确定信标是否使用域前置技术以及使用的是哪个CDN。

原文:

https://research.nccgroup.com/2022/03/25/mining-data-from-cobalt-strike-beacons/

编辑 | 陈蓉

审校 | 何双泽、金矢

本文为CNTIC编译整理,不代表本公众号观点,转载请保留出处与链接。

声明:本文来自国家网络威胁情报共享开放平台,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。