通过 mTLS 使用 x509 证书的原型恶意软件 C2 通道

作者:Sec-Labs | 发布时间:

项目地址

https://github.com/jconwell/secret_handshake

Secret Handshake - 恶意软件 C2 通道,使用基于 mTLS 的 x509 证书

678b6b2d10180044

 

动机

首先,我为什么要开源这个?

MITRE ATT&CK 只谈论被盗或自签名证书,而 NDR(据我所知)很少关注颁发 CA 之外的 x509 证书的内容。一般来说,x509 证书是可信的,可以不受惩罚地通过我们的防火墙。但本质上,它们只是可以像其他任何文件一样轻松包含恶意负载的文件。我们信任并忽略它们,因为它们是我们认为理所当然的加密过程的核心组成部分。该项目的主要目标是提高人们对我们信任的一类安全指标的认识,并强调可用于检测其恶意使用的方法。

背景

我一直想知道威胁参与者是否曾使用 x509 证书作为其 C2 通信的一部分,不是为了加密网络流量,而是将 C2 通信实际嵌入到 x509 证书中。在野外搜索了 5 年这样的东西之后,我终于决定自己编写代码,看看是否可行……是的。

通过 HTTPS/TLS 发送的每条加密消息都通过 x509 证书的传输启用。建立 TLS 握手时(下图),在第四步中服务器将其 x509 证书发送给客户端。客户端验证证书,比较服务器支持的加密算法并选择用于所有进一步通信的算法。

8961b765e6180105

 

如图所示,这只是 x509 证书从服务器到客户端的单向传输。这不适合 C2 通信,因为客户端无法响应服务器。充其量,它只能用作一种单向数据传输机制(参见下面的现有技术部分)。

但是还有另一种类型的 TLS 会话称为相互 TLS 身份验证 (mTLS),其中客户端和服务器交换 x509 证书作为相互验证的方式。

2f643d8706180128

 

如上图所示,相互认证时先将服务器的x509证书发送给客户端进行认证,再将客户端的x509证书发送给服务器进行认证。这种工件交换代表了为 C2 服务器创建双向通信通道的机会。

通过 x509 证书创建双向通信通道

由于服务器和客户端证书由底层 SSL 库交换,因此客户端没有机会从服务器证书中提取消息、运行命令并生成响应证书,所有这些都在单个 mTLS 连接中完成。这意味着 C2 通道需要设计成请求-回复交换发生在两个不同的相互 TLS 连接上,有点像伪半双工传输模式。

f768eedde1180146

 

请求/响应过程遵循以下步骤:

  • 第一步:客户端和C2服务器都生成各自的证书。客户端的证书包含通用的“信标”消息,而服务器的证书包含它希望客户端运行的命令。如果没有客户端执行的命令,服务器会生成一个通用的“睡眠”证书,以告诉客户端在下一个信标之前要休眠多长时间。
  • 步骤2:客户端和C2服务器都使用步骤1中生成的证书配置网络套接字。
  • 第三步:客户端与服务器建立连接。
  • 第 4 步:在 mTLS 握手期间交换服务器和客户端证书。
  • 第五步:服务端和客户端都关闭各自的套接字。
  • 第六步:客户端从服务器证书中提取要执行的命令。由于客户端的证书只包含一个通用的“信标”消息,因此服务器会将其丢弃。
  • 第七步:客户端执行命令并收集命令输出。
  • 第八步:客户端和C2服务器都生成各自的证书。客户端的证书包含它刚刚执行的命令的输出,服务器生成一个通用的“睡眠”证书来告诉客户端在下一个信标之前要休眠多长时间。
  • 步骤9:客户端和C2服务器都使用步骤8中生成的证书配置网络套接字。
  • 第十步:客户端与服务器建立连接。
  • 第 11 步:在 mTLS 握手期间交换服务器和客户端证书。
  • 第十二步:服务端和客户端都关闭各自的套接字。
  • 步骤13:客户端从服务器证书中提取休眠时长,服务器从客户端证书中提取命令输出。
  • 第14步:客户端休眠服务器指定的时间间隔。

现有技术

完成这项工作后,我为自己的创造力和东西感到非常自豪。

然后我在 2018 年看到了 Jason Reaves 的 BSides 演讲, 他使用基于 TLS 的 x509 证书编写了一个恶意软件二进制植入程序。一年后,Jason 发表了这篇论文,详细介绍了使用 mTLS 的完整双向通信渠道。

运行说明

mTLS 要求客户端和服务器的证书都由同一个 CA 证书签名,因此第一步是生成您自己的 CA 私钥/证书对

创建根 CA 私钥:

openssl genrsa -des3 -out hmCA.key 2048

注意:密码短语将阻止任何获得您的私钥的人生成他们自己的根证书。

创建根 CA 证书

openssl req -x509 -new -nodes -key hmCA.key -sha256 -days 1825 -out hmCA.pem

将生成的密钥和证书文件复制到该certs/ca_certs文件夹​​中。该项目带有一个演示密钥/证书对,因此您可以根据需要跳过此步骤。

启动客户端:

python client.py

启动服务器:

python server.py

侦测

我永远不想在不详细说明如何在您的网络日志中检测它的情况下发布一些潜在的恶意内容。

您可能认为检测这种类型的 TLS 模式很容易,但事实并非如此简单。这个 C2 通道的主要特点之一是它的半双工通信方式。它需要两个相互认证流程来完成服务器和客户端之间的完整请求/回复。当服务器向客户端发送不同的命令时,这将发生多次。

这意味着您应该寻找:

  • 同一源 IP 和目标 IP 之间的多个 mTLS 会话,可能在同一端口上,尽管将其配置为每个 mTLS 连接走不同的端口并不难。
  • 由于请求-回复模式要求每个服务器命令有两个 mTLS 会话,因此查找两个 mTLS 会话非常接近,并且在下一对 mTLS 会话之间有更长的暂停时间。
  • 查找 mTLS 会话对之间的睡眠和抖动时间,方法与查找任何其他 C2 通道相同
  • 每个 mTLS 会话的证书哈希应该不同,因为每个会话都会生成新证书
  • 证书不会由受信任的证书颁发机构颁发
  • x509 证书字节大小也会因会话而异。小型服务器证书应指示发送到客户端的命令,但较大的证书很可能表示下载了恶意二进制文件。客户端证书的大小可能会比服务器命令证书的变化更大,因为它们嵌入了命令输出。大客户证书将表明数据泄露。
  • 如果短时间内同一源 IP 和目标 IP 之间存在多个 mTLS 会话,请查看是否有时会发送具有相同哈希值的证书。这可能表明命令/响应证书的重用,如“信标”客户端证书或“睡眠”服务器证书。

这似乎是一套扣人心弦的检测规则,但就像我之前说的,并不那么容易。事实证明,有一组企业服务也有类似的mTLS流量模式,包括

  • Tanium
  • Microsoft System Center Configuration Manager (SCCM)
  • Microsoft Monitoring Agent
  • Azure Hybrid Runbook Worker
  • Palo Alto Networks
  • MuleSoft
  • TrustedSource
  • Cohesity Helios
  • EMC's Global Security Organization
  • Alert Logic

其中一些似乎是资产/设备管理服务,因此理论上它们应该在每次运行所有设备时发送相同的证书集。您可以查看是否有多个 mTLS 会话集每 N 小时重复一次,然后查看两组不同的 mTLS 会话之间的证书哈希值是否匹配,或者大部分匹配。此外,可能会查找每个 mTLS 会话的客户端证书不同,但所有会话的服务器证书相同。

潜在的缓解措施

SSL 检查是一种可能阻止此类 C2 通信通道的方法,因为 SSL 检查服务器没有验证客户端证书所需的恶意 CA 证书。

标签:工具分享