新型C2方案:基于AzureBlobStorage与Mythic构建隐蔽通信

admin 2026-02-03 01:11:21 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文介绍基于AzureBlobStorage的MythicC2方案,利用企业白名单规则绕过防火墙。方案通过独立容器和限定作用域SAS令牌实现隔离,防止凭据泄露。文章阐述了通信机制与配置流程,并计划集成ProxyBlob提升SOCKS速度,为红队提供了隐蔽通信新思路。 综合评分: 85 文章分类: 红队,渗透测试,内网渗透,安全工具,云安全


cover_image

新型C2方案:基于Azure Blob Storage与Mythic构建隐蔽通信

Dubito Dubito

云原生安全指北

2026年2月2日 08:35 日本

注:本文翻译自 SpecterOps 的文章《Weaponizing Whitelists: An Azure Blob Storage Mythic C2 Profile》[1],可点击文末“阅读原文”按钮查看英文原文。

全文如下:

太长不看: 成熟的企业通常会锁定出站流量,但往往为可信的云服务设置宽泛的例外规则。本文展示了如何通过审查部署指南来识别这些例外,并利用一个名为 azureBlob 的新型 Mythic C2 配置文件将其武器化。

一、引言

在最近的一次黑客马拉松中,我们讨论了一些运营者遇到的一些常见问题。其中一个不幸的常见情况是:在高度成熟的企业环境中,严格限制的出站防火墙规则或网络代理规则会阻止运营者从其目标接收回调(callbacks)。为了解决这些障碍,我们审查了各种安装和部署指南,发现许多供应商会建议在防火墙和代理中以宽泛的通配符设置例外情况,以确保云服务在初始部署期间能够正常工作。

例如,Zscaler 关于 Azure 流量转发[2] 的指南、Parallels Remote Application Server 针对 Azure Virtual Desktop[3] 的指南,以及 Nerdio Enterprise Manager[4] 的指南都包含了以某种方式允许出站访问 *.blob.core.windows.net 的规则。

这一发现促使我们构建了一个新的 Mythic 命令与控制(C2)配置文件 azureBlob[5]。该配置文件利用 Azure Blob 存储,并将其集成到 Medusa[6] 的修改版本中,作为概念验证(PoC)。

Azure Blob Storage[7] 是微软针对云环境的对象存储解决方案,专为存储海量非结构化数据而优化。使用 Azure Blob Storage进行 C2 通信并非新方法(像 Loki[8] 这样的工具已经证明了这一点),但我们希望开发一个PoC,能够扩展到其他 Mythic 代理并支持 SOCKS 代理功能。我们还采取了一些额外的操作安全预防措施,涉及 Azure 容器和令牌范围,详细内容见下文的 “容器隔离与令牌安全” 部分。

接下来,我们将深入介绍如何设置和安装这个 Mythic C2 配置文件 azureBlob,并讨论其工作原理!

二、Mythic C2 配置文件设置

在深入配置 Mythic C2 配置文件之前,我们需要先在 Azure 中进行一些设置。首先,你需要在 Azure 门户中创建一个存储账户(Storage Account)。

  1. 1. 访问 https://portal.azure.com[9]
  2. 2. 在搜索栏中输入 “Storage accounts”
  3. 3. 选择 “+ Create”(创建)
  4. 4. 创建或分配一个资源组(resource group)
  5. 5. 选择一个区域(Region)
  6. 6. 选择 “Premium Performance”(高级性能等级)
  7. 7. 选择 “Block Blobs” 账户类型
  8. 8. 选择 “Local-redundant storage”(本地冗余存储)选项
  9. 9. 选择 “Review + Create”(检查+创建)

Azure Storage账户设置

接下来,你需要在 “Security + Networking”(安全+网络) -> “Access Keys”(访问密钥)下获取存储账户的访问密钥。

获取Storage账户访问密钥

然后,在你的 Mythic 服务器上安装 C2 配置文件和代理(agent)。

sudo ./mythic-cli install github https://github.com/senderend/azureBlob
sudo ./mythic-cli install github https://github.com/KingOfTheNOPs/Medusa

Mythic C2 配置文件和代理安装命令

安装好 C2 配置文件和代理后,下一步是配置 C2 配置文件。选择 “Installed Services”(安装服务) -> “C2”,然后选择 “View/Edit Config”(查看/编辑配置)。

Mythic 已安装服务

填入存储账户名称和密钥,然后选择 “Submit”(提交)。

Azure Blob C2 配置

接下来,创建一个载荷(payload),并选择 Medusa 代理。

Medusa 构建参数

Azure Blob C2 参数

出于演示目的,我们禁用了 HTTPS 验证和载荷混淆(payload obfuscation),并将 AESPSK 和加密交换(encrypted exchange)设置为 “false”。在实际操作中,我们建议将这些值设为 “true”。在最后一页,检查载荷配置并选择 “Build Payload”(构建载荷)。

构建过程概览

在后端生成该载荷时,Medusa 项目中的 builder.py[10] 脚本会被执行。我们修改了这个脚本,以检查操作员选择了哪个配置文件(profile)。如果操作员选择了 azureBlob 配置文件,系统会发起一个 RPC 调用到 C2 配置文件,以生成一个 Azure Blob Storage 容器。此容器专属于该特定载荷,其名称以 “agent-*” 为前缀。容器创建后,容器名称、SAS 令牌和 Blob 端点会返回给构建器(builder),以最终完成载荷的创建。让我们深入了解一下这个容器创建的 RPC 调用过程。

三、服务器端基础设施配置

我们的一个设计目标是消除从代理(agent)到 Azure 管理 API 的任何不必要流量。所有 Azure 基础设施的配置都在生成载荷时,于 Mythic 服务器端完成。代理从不调用 Azure 管理 API;它们只对分配给它们的容器执行 PUT、GET 和 DELETE  blob 操作。

C2 配置文件公开了一个名为 generate_config 的自定义 RPC 函数,PayloadType 可以在构建过程中调用它。当你通过 Mythic UI 构建载荷时,会发生以下情况:

# 在你的 PayloadType 的 builder.py 中
config_data = await SendMythicRPCOtherServiceRPC(MythicRPCOtherServiceRPCMessage(
    ServiceName="azure_blob",
    ServiceRPCFunction="generate_config",
    ServiceRPCFunctionArguments={
        "killdate": killdate,
        "payload_uuid": self.uuid
    }
))

if config_data.Success:
    blob_endpoint = config_data.Result['blob_endpoint']
    container_name = config_data.Result['container_name']
    sas_token = config_data.Result['sas_token']
    # 将这些值嵌入到你的代理代码中

这个 RPC 函数会从服务器的 config.json 读取存储账户凭据,创建容器,生成限定作用域的 SAS 令牌,并返回代理所需的所有信息。代理永远不会触发 Azure 管理 API;它只向分配给它的容器发起 GET、PUT 和 DELETE 请求。

这种方法也意味着 C2 服务器可以通过列出以 agent-* 为前缀的容器来自动发现新的代理,而无需代理自行注册。

四、容器隔离与令牌安全

存储账户密钥(Storage Account key)永远不会离开 Mythic 服务器。每个代理都拥有自己独立的容器,并且只接收一个容器作用域的 SAS 令牌,该令牌限制其只能访问分配给它的容器。这与其它 Azure Blob C2 实现的工作方式有本质不同,是我们刻意为之的设计。

现有的实现通常会将一个账户级别的 SAS 令牌嵌入到每个代理中。这意味着 一个被泄露或被逆向的代理会暴露其凭据[11],这些凭据可以访问其他代理的 blob、列出存储账户中的所有容器、跨整个操作读取和删除数据,甚至如果攻击者获取了 AES 加密密钥,还可以向代理发送恶意任务。

使用容器作用域的令牌,一个被攻破的代理只能访问它自己的容器。影响范围被限制在该单一代理内。

SAS 令牌的过期时间与在 Mythic 中生成载荷时选择的“终止日期”(kill date)绑定,因此令牌会在载荷到期时自动失效。在了解了服务器端配置的工作原理后,我们来剖析一下 C2 通信是如何运作的。

五、C2 通信工作原理

Azure Blob C2 通信流程

消息流遵循 Mythic 标准的 “postMessageAndRetrieveResponse” 和 “getMessageAndRetrieveResponse” 模式,这使得集成到其他代理中变得非常直接。

agent-{uuid[:12]}/
├── ats/
│   └── {message-id}.blob     # Agent-to-Server 消息
└── sta/
    └── {message-id}.blob     # Server-to-Agent 响应

发送消息的步骤:

  1. 1. 代理生成一个唯一的消息 ID。
  2. 2. 代理通过 PUT 操作将加密的消息上传到 ats/{message-id}.blob
  3. 3. 代理轮询 sta/{message-id}.blob 以获取响应。
  4. 4. 代理在读取后删除响应 blob。

C2 服务器运行一个轮询循环,该循环执行以下操作:

  1. 1. 列出所有以 agent-* 为前缀的容器。
  2. 2. 对于每个容器,列出 ats/ 文件夹中的 blob。
  3. 3. 下载并删除每条代理消息,将其转发给 Mythic。
  4. 4. 将 Mythic 的响应写入对应的 sta/{message-id}.blob

每条消息都包含一个 UUID 前缀,后跟 JSON 数据,这符合 Mythic 预期的格式。

六、Pegasus 测试代理

azureBlob[5] 代码库中包含 Pegasus,这是一个最小化的 Python 代理,主要有两个用途:

  1. 1. 验证你的 C2 配置,或者无需进行任何代理开发即可试用该配置文件。
  2. 2. 作为参考实现,其代码简单、精简,可以作为将 C2 配置文件支持集成到其他代理中的模板。

该代理代码包含一些占位符,Mythic 会在生成载荷时替换它们:

BLOB_ENDPOINT = "BLOB_ENDPOINT_PLACEHOLDER"
CONTAINER_NAME = "CONTAINER_NAME_PLACEHOLDER"
CONTAINER_SAS = "CONTAINER_SAS_PLACEHOLDER"
CALLBACK_INTERVAL = int("CALLBACK_INTERVAL_PLACEHOLDER" or "30")
CALLBACK_JITTER = int("CALLBACK_JITTER_PLACEHOLDER" or "10")
AGENT_UUID = "AGENT_UUID_PLACEHOLDER"

当载荷构建时,代理的 builder.py 会调用 C2 配置文件的 generate_config RPC 函数来配置容器并获取 SAS 令牌,然后将这些值嵌入到代理代码中。账户密钥不会被嵌入;只有限定作用域的 SAS 令牌会被写入。

Pegasus 支持 shell、whoami、pwd、hostname 和 exit 命令。它作为一个参考实现,展示了完整的消息生命周期(签入 checkin、获取任务 get_tasking、提交响应 post_response)。

此外,这个测试代理不支持加密,因此我们不建议将其用于实际作战。我们构建这个代理仅用于实验室和个人测试。

要测试你的设置,请执行:

sudo ./mythic-cli install github https://github.com/senderend/azureBlob

通过 Mythic UI 构建一个 Pegasus 载荷。如果它成功签入(checks in),说明你的配置是正确的,然后你就可以继续进行,将该配置文件集成到你实际的代理中。

七、集成到你的代理中

我们设计的配置文件可以与任何 Mythic 代理协同工作。你需要:

  1. 1. 在你的 builder.py 中: 在构建期间调用 generate_config RPC 函数,以配置容器并返回限定作用域的 SAS 令牌,然后用结果替换代理代码中的占位符变量。
  2. 2. 在你的代理代码中: 定义占位符变量,这些变量将被上述过程替换;并针对 ats/ 和 sta/ 路径,使用构建时嵌入到这些占位符变量中的值,实现 blob 的 PUT/GET/DELETE 操作。

代理与 Azure Storage 的通信是简单的 HTTP REST API 调用,使用大多数编程语言都具备的标准请求库即可完成。你可能会注意到,我们在 C2 配置文件(不是代理端)中,对于服务器端的容器配置和账户级别管理,使用了 Microsoft Azure Storage Blobs Python 库[12]。虽然 Azure Storage为多种语言提供了客户端库和 SDK,但对于代理所需的简单读/写/删除操作来说,这些并非必需。我们选择使用标准库自行构建简单的请求,以避免载荷的额外依赖,并为操作员提供自定义选项。

容器 URL 的格式为:https://{storage_account}.blob.core.windows.net/{container_name}/{blob_path}?{sas_token}

八、未来工作:更快的 SOCKS

在使用 Medusa 和 azureBlob 配置文件测试 SOCKS 代理时,我们观察到的速度最高可达 19-21 KB/s。

SOCKS 速度测试

这样的速度绝对谈不上理想。为此,Andrew Luke[13] 和 Paul Kim[14] 牵头,将 ProxyBlob[15] 的客户端从 Go 移植到了 Python,以便将其集成到支持 Azure Blob Storage C2 配置文件的代理中。ProxyBlob 是 Quarkslab 专门为 Azure Blob Storage 传输设计的 SOCKS5 代理,其吞吐量可达约 1.5 MB/s。与我们测试的约 21KB/s 相比,这样的速度将带来巨大的提升,并使代理通过 Azure Blob Storage 实现的 SOCKS 能力达到能够稳健支持代理进攻工具的水平。待我们完善了这个PoC后,请关注我们后续的博客文章!

九、总结

对于防御者和攻击者来说,部署指南都是信息的宝库。通常,这些指南为开发技术留下了机会,可以藏身于组织已经信任的架构之中。Azure Blob Storage 并非 C2 通信的新方法,像 Loki 这样的流行工具已经证明了这一点;我们只是想扩展已经奠定的基础!我们设计这个 Mythic 配置文件,是为了帮助其他人将 Azure Blob Storage 集成到他们的 Mythic C2 代理中。

非常感谢 Cody Thomas[16] 帮助构建这个工具以及他制作的 Mythic 开发系列教程[17]。如果有人有兴趣在 Mythic 中开发自己的 C2 配置文件或代理,我强烈推荐观看他的系列视频!同时,也要感谢 Andrew Luke 和 Paul Kim 在开发这个 Mythic 配置文件过程中提供的帮助。

引用链接

[1] 《Weaponizing Whitelists: An Azure Blob Storage Mythic C2 Profile》: https://specterops.io/blog/2026/01/30/weaponizing-whitelists-an-azure-blob-storage-mythic-c2-profile/ [2] Azure 流量转发: https://help.zscaler.com/zscaler-technology-partners/zscaler-and-azure-traffic-forwarding-deployment-guide [3] Azure Virtual Desktransform: translateY( https://docs.parallels.com/parallels-ras-managem)ent-portal-20/appendix/port-reference/azure-virtual-desktop [4] Nerdio Enterprise Manager: https://nmehelp.getnerdio.com/hc/en-us/articles/26124299857549-Required-outbound-internet-access-from-AVD-session-host-VMs [5] azureBlob: https://github.com/senderend/azureBlob [6] Medusa: https://github.com/kingOfTheNOPs/Medusa [7] Azure Blob Storage: https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction [8] Loki: https://github.com/boku7/Loki [9] https://portal.azure.com: https://portal.azure.com/ [10] builder.pyhttps://github.com/KingOfTheNOPs/Medusa/blob/master/Payload_Type/medusa/medusa/mythic/agent_functions/builder.py [11] 一个被泄露或被逆向的代理会暴露其凭据: https://github.com/boku7/Loki/blob/main/docs/azure/create-storage-account-portal.md#-final-notes [12] Microsoft Azure Storage Blobs Python 库: https://learn.microsoft.com/en-us/python/api/overview/azure/storage-blob-readme?view=azure-python [13] Andrew Luke: https://github.com/Sw4mpf0x [14] Paul Kim: https://github.com/SpecterUser [15] ProxyBlob: https://github.com/quarkslab/proxyblob [16] Cody Thomas: https://github.com/its-a-feature [17] Mythic 开发系列教程: https://youtube.com/playlist?list=PLJK0fZNGiFU_iJI2A8S5OdloTDexi5zs8&si=ENyWvlOCmCPNcGIM

交流群


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:云原生安全指北 Dubito Dubito《新型C2方案:基于Azure Blob Storage与Mythic构建隐蔽通信》

评论:0   参与:  0