使用已知私钥解密Cobalt Strike流量第2部分

使用已知私钥解密Cobalt Strike流量第2部分

我们使用找到的 6 个私钥之一解密 Cobalt Strike 流量。

在这篇博文中,我们将通过查看感染期间捕获的完整数据包来分析 Cobalt Strike 感染。此分析包括解密 C2 流量。

如果您还没有阅读,我们邀请您先阅读第 1 部分:使用已知私钥解密Cobalt Strike流量第1部分

对于此分析,我们使用捕获文件2021-02-02-Hancitor-with-Ficker-Stealer-and-Cobalt-Strike-and-NetSupport-RAT.pcap.zip,这是众多恶意软件流量捕获文件之一Brad Duncan 在他的网站Malware-Traffic-Analysis.net 上分享

我们从最少的知识开始:捕获文件包含 Cobalt Strike 信标与其团队服务器通信的加密 HTTP 流量。

如果您想了解更多关于 Cobalt Strike 及其组件的信息,我们强烈推荐以下博文

第一步:我们用 Wireshark 打开捕获文件,并通过 stager shellcode 查找完整信标的下载。

尽管信标可以有多种形式,但我们可以确定两大类:

  1. 一小段 shellcode(几百字节),又名 stager shellcode,用于下载完整的信标
  2. 完整的信标:一个可以反射加载的 PE 文件

在第一步中,我们在捕获文件中搜索 stager shellcode 的迹象:我们使用以下显示过滤器执行此操作:
http.request.uri matches “/….$”.

使用已知私钥解密Cobalt Strike流量第2部分
图 1:Cobalt Strike 流量的数据包捕获

我们一击必中。GET 请求中用于下载完整信标的路径由 4 个满足条件的字符组成:字符值总和的字节值(又名校验和 8)是一个已知常量。我们可以使用工具metatool.py进行检查,如下所示:

metatool.py下载地址

github.com/DidierStevens/Beta/blob/master/metatool.py

云中转网盘:
yunzhongzhuan.com/#sharefile=fuDUwdqL_16225
解压密码: www.ddosi.org

使用已知私钥解密Cobalt Strike流量第2部分
图 2:使用 metatool.py

可以在此处找到有关此校验和过程的更多信息。
该工具的输出显示这是下载 32 位完整信标 (CS x86) 的有效路径。
完整信标的下载也被捕获:

使用已知私钥解密Cobalt Strike流量第2部分
图 3:完整的信标下载

我们可以提取这个下载:

使用已知私钥解密Cobalt Strike流量第2部分
图 4:导出 HTTP 对象
使用已知私钥解密Cobalt Strike流量第2部分
图 5:选择下载 EbHm 进行保存
使用已知私钥解密Cobalt Strike流量第2部分
图 6:将选定的下载保存到磁盘

一旦完整的信标作为 EbHm.vir 保存到磁盘,就可以使用工具 1768.py对其进行分析。1768.py 是一个可以解码/解密 Cobalt Strike 信标并提取其配置的工具。Cobalt Strike 信标有许多配置选项:所有这些选项都存储在一个编码和嵌入的表中。

这是分析的输出

使用已知私钥解密Cobalt Strike流量第2部分
图 7:提取信标配置

让我们仔细看看其中的一些选项。

首先,选项 0x0000 告诉我们这是一个 HTTP 信标:它通过 HTTP 进行通信。
它通过连接到端口 8080(选项 0x0002)上的 192.254.79[.]71(选项 0x0008)来实现。
GET 请求使用路径 /ptj(选项 0x0008),POST 请求使用路径 /submit.php(选项 0x000a)
并且对我们的分析很重要:对于这个信标使用的公钥,有一个已知的私钥(Has known private key) (选项 0x0007)。

因此,有了这些信息,我们知道信标将向团队服务器发送 GET 请求,以获取指令。如果团队服务器有信标要执行的命令,它将以加密数据回复 GET 请求。当信标必须将其命令的输出发送回团队服务器时,它将使用带有加密数据的 POST 请求。

如果团队服务器没有针对信标的命令,则不会发送加密数据。这并不一定意味着对 GET 请求的回复不包含任何数据:运营商可以通过配置文件伪装通信。例如,加密数据位于 GIF 文件中。但对于这个信标,情况并非如此。我们知道这一点,因为在这个配置文件中没有所谓的可塑性 C2 指令:选项 0x000b 等于 0x00000004 -> 这意味着在解密之前不应对数据执行任何操作(我们将在后面更详细地解释这一点博文)。

让我们创建一个显示过滤器来查看这个 C2 流量:http and ip.addr == 192.254.79[.]71

使用已知私钥解密Cobalt Strike流量第2部分
图 8:完整的信标下载和带有加密 Cobalt Strike 流量的 HTTP 请求

这将显示进出团队服务器的所有 HTTP 流量。请注意,我们已经查看了此视图中的前 2 个数据包(数据包 6034 和 6703):这是信标本身的下载,并且通信未加密。因此,我们将使用以下显示过滤器过滤掉这些数据包:

http and ip.addr == 192.254.79.71 and frame.number > 6703

这为我们提供了 GET 请求及其回复的列表。请注意,每分钟都有一个 GET 请求。这也在信标配置中:60.000 毫秒的睡眠(选项 0x0003),变化为 0%(又名抖动,选项 0x0005)。

使用已知私钥解密Cobalt Strike流量第2部分
图 9:带有加密 Cobalt Strike 流量的 HTTP 请求

我们现在将遵循第一个 HTTP 流:

使用已知私钥解密Cobalt Strike流量第2部分
图 10:跟随 HTTP 流
使用已知私钥解密Cobalt Strike流量第2部分
图 11:第一个 HTTP 流

这是对 /ptj 的 GET 请求,它收到一个没有数据的 STATUS 200 回复。这意味着目前没有来自团队服务器的此信标的命令:操作员尚未在捕获文件中发出任何命令。

备注 GET 请求的 Cookie 标头。这看起来像一个BASE64字符串:

KN9zfIq31DBBdLtF4JUjmrhm0lRKkC/I/zAiJ+Xxjz787h9yh35cRjEnXJAwQcWP4chXobXT/E5YrZjgreeGTrORnj//A5iZw2TClEnt++gLMyMHwgjsnvg9czGx6Ekpz0L1uEfkVoo4MpQ0/kJk9myZagRrPrFWdE9U7BwCzlE=

该值是信标作为 BASE64 字符串发送到团队服务器的加密元数据。此元数据使用信标配置中的公钥(选项 0x0007)进行 RSA 加密,并且团队服务器可以解密此元数据,因为它具有私钥。请记住,一些私钥已被“泄露”,我们在本系列的第一篇博文中对此进行了讨论。

我们的信标分析表明,该信标使用具有已知私钥的公钥。这意味着我们可以使用工具cs-decrypt-metadata.py来解密元数据(cookie),如下所示:

使用已知私钥解密Cobalt Strike流量第2部分
图 12:解密信标元数据

我们可以在这里看到解密的元数据。对我们来说非常重要的是原始密钥:caeab4f452fe41182d504aa24966fbd0。我们将使用此密钥来解密流量(AES 和 HMAC 密钥源自此原始密钥)。

我们可以在这里找到的更多元数据是:计算机名、用户名……

我们现在将跟踪带有数据包 9379 和 9383 的 HTTP 流:这是操作员(团队服务器)向信标发送的第一个命令:

使用已知私钥解密Cobalt Strike流量第2部分
图 13:带有加密命令的 HTTP 流

在这里我们可以看到回复包含48个字节的数据(Content-length)。该数据已加密:

使用已知私钥解密Cobalt Strike流量第2部分
图 14:带有加密命令的 HTTP 流的十六进制视图

像这样加密的数据,可以用工具cs-parse-http-traffic.py解密。由于数据是加密的,我们需要提供原始密钥(选项 -r caeab4f452fe41182d504aa24966fbd0)并且由于数据包捕获包含除纯 Cobalt Strike C2 流量之外的其他流量,因此最好提供一个显示过滤器(option -Y http and ip.addr == 192.254.79.71 and frame.number > 6703) 以便工具可以忽略所有非 C2 流量的 HTTP 流量。

这会产生以下输出:

使用已知私钥解密Cobalt Strike流量第2部分
图 15:解密的命令和结果

现在我们可以看到数据包9383中的加密数据是一条睡眠命令,睡眠时间为100毫秒,抖动系数为90%。这意味着操作员指示信标与信标交互。

解密后的数据包 9707 包含一个未知命令(id 53),但是当我们查看数据包 9723 时,我们看到一个目录列表输出:这是将未知命令 53 发送回团队服务器的输出结果(注意 POST url /提交.php)。因此可以安全地假设命令 53 是一个目录列表命令。

这个抓包文件中有很多命令和结果,工具cs-parse-http-traffic.py可以解密,这里就不多说了。但我们邀请您重现此博文中的命令,并查看该工具的输出。

捕获文件中的最后一个命令是进程列表命令:

使用已知私钥解密Cobalt Strike流量第2部分
图 16:解密的进程列表命令和结果

结论

虽然我们在这里解密的抓包文件是 Brad Duncan 在半年前通过在沙箱中运行恶意 Cobalt Strike 信标生成的,但我们今天可以解密它,因为运营商使用了一个包含私钥的流氓 Cobalt Strike 包,即我们从 VirusTotal 中恢复。

如果没有这个私钥,我们将无法解密流量。

私钥不是解密流量的唯一方法:如果可以从进程内存中提取 AES 密钥,我们也可以解密流量。我们将在即将发布的博客文章中介绍这一点。

from

Leave a Reply

您的电子邮箱地址不会被公开。 必填项已用*标注