如前文所述,Cobalt Strike 网络流量可以使用正确的 AES 和 HMAC 密钥进行解密。之前也讲述了如何通过解密 Cobalt Strike 元数据的方法获取密钥,本文将会重点描述从内存 Dump 中提取密钥的方法。

通过共享密钥解密 Cobalt Strike 流量

Avenger,公众号:威胁棱镜破解版密钥相同,部分CobaltStrike加密流量可解

如果发现了正在运行的 Beacon 进程,可以使用 Sysinternals 的 procdump 来生成内存 Dump。并不需要完整的内存 Dump,只使用 procdump.exe -mp pid dump 可写进程内存即可。其中, -mp 是获取可写内存 dump 的参数, pid 是正在运行的 Beacon 进程的 PID。

对于 Cobalt Strike 3.x 的 Beacon,未加密的元数据头通常可以使用 0x0000BEEF 作为特征在内存中检索。获取内存 Dump 的时间越早,也就越有可能包含未加密的元数据。

进而可以使用 cs-extract-key.py 查找并解码元数据:

元数据中包含 16 字节的随机密钥,通过对该密钥计算 SHA256。SHA256 的前半部分作为 HMAC 密钥,后半部分作为 AES 密钥。

得到了密钥和原来描述的使用方式基本类似,也可以通过 cs-parse-http-traffic.py 来解密流量。

值得注意的是, cs-extract-key.py 可能存在误报。发现以 0x0000BEEF 开头的字节序列并不都是元数据。上篇文中的示例就是好例子,第一个例子包含机器名称和用户的确实是有效的元数据,这些元数据也可以在进程内存的其他位置中发现。但是第二个例子实际上没有得到可识别的名称,在其他位置也找不到 AES 和 HMAC 密钥,这就是一个误报。

对于 Cobalt Strike 4.x 的 Beacon,通过内存直接提取未加密元数据的可能性变得极低了。因为此时已经没有数据头来进行标识了,单纯的 16 字节长序列没有可区分的特征。只能通过在进程内存中找到所有可能的 16 字节长非空序列作为密钥字典,不断尝试解密 C&C 通信,碰撞成功就找到了密钥。

提取方式例如 cs-parse-http-traffic.py -k unknown capture.pcapng-k 表示密钥未知,该工具尝试提取加密数据流量:

数据包 103 是对数据包 97 的 GET 请求的 HTTP 响应,响应数据长 64 字节(d12c14aa698a6b85a8ed3c3c33774fe79acadd0e95fa88f45b66d8751682db734472b2c9c874ccc70afa426fb2f510654df7042aa7d2384229518f26d1e044bd)。

这应该就是 Team Server 发送给 Beacon 的加密数据,通过 cs-extract-key.py -t d12c14aa698a6b85a8ed3c3c33774fe79acadd0e95fa88f45b66d8751682db734472b2c9c874ccc70afa426fb2f510654df7042aa7d2384229518f26d1e044bd rundll32.exe_211028_205047.dmp 尝试提取密钥:

之后就可以使用提取的 AES 和 HMAC 密钥解密流量(-k HMACkey:AESkey):

可以看到解密后的命令是 DATA_JITTER,该命令表示服务器向 Beacon 发送可以忽略的随机数据。使用默认配置文件的 Cobalt Strike 不会发送随机数据,也不会使用 Malleable 进行处理。这表示,只要没有需要 Beacon 执行的命令,就不会向 Beacon 发送数据,HTTP 响应长度为 0。这样即使流量是加密的,也可以确定 Beacon 是否收到了命令。

为了避免这种明显的特征,Cobalt Strike 支持交换随机数据,使数据包保持唯一性。不过这反而对防御者有用:如果不发送随机数据,观测不到加密数据,也就不能识别进程内存中的加密密钥了。

Beacon 回传给 Team Server 的数据通过 POST 请求发送,该数据也可以用于查找解密密钥。使用方式类似,区别在于使用 -c 而不是 -t 参数,原因在于Team Server 的加密方式和 Beacon 的加密方式略有不同。

一些注意事项

  • 较大的内存 Dump 需要较长的时间来进行密钥字典碰撞。

  • 使用完整内存 Dump 需要的时间更长

  • 4.x 版本的方法也适用于 3.x 版本

NVISO 的研究人员正在开发能够解析 Dump 文件的数据结构,提取最可能包含密钥的内存部分,加快密钥提取过程的工具。

cs-analyze-processdump.py

https://github.com/DidierStevens/Beta/blob/master/cs-analyze-processdump.py

Beacon 可以配置为在不活动时对其可写内存进行编码,来进行保护。此时,AES 和 MHAC 密钥也会被编码,且无法使用上述的方法进行恢复。

思考

想要解密 Cobalt Strike 流量,最好是存在相对应的 RAS 私钥。如果没有,也可以使用内存 Dump 来恢复 HMAC 和 AES 密钥。

防御者对 Cobalt Strike 的理解应该更加深入,只有在技术原理和实际实现的层面深入理解,才能发现更有效的检测方式。以不断地深入研究总结经验,应对千变万化的攻击形式。实际上不仅是防御者,Cobalt Strike 一路走来的不断更新都是攻防对抗不断升级的结果,从旁观到亲历的视角转变也许可以让每一个攻击者来主动思考 Cobalt Strike 之所以成功的原因。

声明:本文来自威胁棱镜,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。