GraphStrike

发布博客:GraphStrike:利用Microsoft Graph API使Beacon流量消失
开发者博客:GraphStrike:攻击性工具开发剖析
简介
GraphStrike 是一套工具套件,使 Cobalt Strike 的 HTTPS Beacon 能够通过 Microsoft Graph API 进行 C2 通信。所有 Beacon 流量将通过攻击者 SharePoint 站点中创建的两个文件传输,并且来自 Beacon 的所有通信将路由至 https://graph.microsoft.com:

GraphStrike 包含一个配置器,用于创建通过 Graph API 实现 Cobalt Strike HTTPS 所需的 Azure 资产:

GraphStrike 不会在 Azure 中创建任何付费资产,因此使用 GraphStrike 或其配置器不会产生额外成本。
为什么?
已有威胁情报披露了多个不同 APT 组织利用 Microsoft Graph API 和其他微软服务进行攻击活动的情况:
- BLUELIGHT - APT37/InkySquid/ScarCruft
- Graphite - APT28/Fancy Bear
- Graphican - APT15/Nickel/The Flea
- SiestaGraph - 未知
威胁行为者持续利用合法服务进行非法目的。利用 graph.microsoft.com 等高信誉域名进行 C2 通信极为有效且令人向往,但从时间和精力角度来看往往复杂且难以实现。大多数 C2 框架不支持获取或轮换访问令牌的方法,因此无法使用 Graph API。这使红队难以复现这些技术,也剥夺了防御者观察和开发此类活动签名特征的机会。GraphStrike 旨在减轻这一负担,提供可靠且可重复的流程来利用 Microsoft Graph API,同时保持 Cobalt Strike 用户体验的熟悉性和可靠性。
这是 External C2 吗?
严格来说不是。此前曾构建过真正的 利用 Graph API 的 External C2(通过 Microsoft Teams 消息发送 Beacon 流量),但开发、维护和集成一个符合 External C2 规范并能完成任务的定制植入体的负担过于熟悉。GraphStrike 转而利用一个开源的 用户自定义反射加载器(UDRL),即 Kyle Avery 开发的 AceLdr(在本项目中改编为 'GraphLdr'),来 Hook Beacon 正常调用的 WinINet 库函数,并按需操纵这些调用以使用 Graph API。没有定制植入体或额外进程,只有带有几个 Hooked Windows API 的 Beacon 进程。在服务端,有一个 Python3 程序将 Cobalt Strike Team Server 流量转换为 Graph API 流量,反之亦然。
特性
GraphStrike 支持几乎所有正常的 Cobalt Strike 活动,包括:
- 通过 Cobalt Strike SOCKS 代理使用 Proxychains(尽管速度非常慢……)
- 上传/下载大文件
- BOF、execute-assembly 等
还包括 GraphStrike 对 sleep、exit 和 remove 命令的集成,使 GraphStrike Server 的睡眠时间与 Beacon 匹配,并在 Beacon 退出或被移除时删除 SharePoint 中的文件。
GraphStrike 还整合了原始 AceLdr 的所有特性和功能,并额外添加了一些利用调用栈欺骗的 API。
需求
开始之前,GraphStrike 需要满足以下条件:
- 一个具有 SharePoint/O365 许可证并已创建站点的 Microsoft Azure 租户。默认站点即可。
- 一个在该租户中具有全局管理员权限的 Azure 账户。
- Python 3.8-3.11注 #4(以及在设置过程中将安装的额外依赖项)
防火墙规则
- 确保运行 Cobalt Strike 客户端的每台机器能够通过端口 443 和 5000 连接到 Cobalt Strike Team Server 机器。
设置
在继续设置过程之前,请注意以下事项:
1. 某些组件使用相对路径定位其他资产。请按以下说明切换目录。
2. Cobalt Strike 配置文件只能在以下设置过程的步骤 5 之前进行编辑注 #1。
在将要运行 Cobalt Strike Team Server 的机器上:
- 克隆仓库。
- 从仓库目录运行
sudo setup/install_dependencies.sh 安装所需的系统依赖项。
- 运行
python3 -m venv virtual 然后 source virtual/bin/activate 创建并进入虚拟环境。
- 切换到 setup 目录并运行
pip3 install -r requirements.txt。
- 运行
./provisioner.py new 并完成设置过程。
- 使用 graphstrike.profile 作为 malleable C2 配置文件启动 Cobalt Strike Team Server。
- 启动一个 Cobalt Strike 客户端实例(可以在客户端机器上执行,也可以在 TS 机器上执行后将其关闭),并在 HTTPS Hosts 和 HTTPS Host(Stager) 字段中使用
graph.microsoft.com 创建一个监听端口 443 的 Cobalt Strike HTTPS 监听器。
- 切换回主仓库目录并运行
./GraphStrike.py 启动 GraphStrike Server。
在将要运行 Cobalt Strike 客户端的 ALL 机器上:
- 将 GraphStrike/client 目录从 TS 机器复制到客户端机器。这必须在完成配置之后进行!
- 使用脚本管理器将 GraphStrike.cna 导入到 Cobalt Strike。
- 创建 Cobalt Strike 载荷,无论是原始 shellcode 还是使用 Artifact Kit 或替代载荷生成框架编译的产物。Artifact Kit 用户请见下文!
- 收割成果。
Artifact Kit 用户
由于 GraphLdr 的大小,Artifact Kit 用户需要使用特定选项重新编译它,以便 GraphStrike 与 Artifact Kit 生成的载荷兼容。具体来说,需要指定 'Stage Size' 和 'RDLL Size' 字段以使用 100K RDLL 大小。以下提供两个有效语法示例:
./build.sh pipe VirtualAlloc 505029 100 false false none /opt/cobaltstrike/artifacts
./build.sh peek HeapAlloc 492376 100 false true indirect /opt/cobaltstrike/artifacts
清理
在运行 TS + GraphStrike Server 的机器上:
- 停止 GraphStrike 服务器
- 切换回 setup 目录并运行
./provisioner.py delete 以删除创建的 Azure 资产。
注释
以下是一些有助于充分利用 GraphStrike 的建议和观察,无特定顺序。
- GraphStrike 包含的配置文件非常简洁,这是有意为之。更改配置文件中现有字段可能会/将会破坏 GraphStrike! 您应该能够向其他尚未定义的配置部分(例如自定义管道名称、注入行为等)添加额外的配置语言/行为。对配置文件的任何编辑必须在运行配置器之前完成!
- 用于 Beacon 和 GraphStrike Server 进行 C2 通信的 Azure 应用程序的请求速率限制为 1200 次/分钟。GraphStrike Server 以 120 次/分钟为基准运行。Beacon 的睡眠时间越短,发出的请求就越多;此外,每个使用 GraphStrike 创建的 Beacon 都会消耗部分 1200 次/分钟的限制。与单个 Beacon 进行交互是可行的,但与多个 Beacon 同时交互可能不行。如果遇到速率限制问题,请考虑增加 Beacon 的睡眠时间,减少运行的 Beacon 数量,或两者兼施。
- 虽然 GraphStrike Server 的睡眠时间会根据发出的 sleep 命令在每个 Beacon 的基础上变化,但这实际上意味着 GraphStrike Server 在向 TS 检查任务之前会睡眠指定的时间。这并不意味着 Beacon 会在 GraphStrike Server 从 TS 获取任务后立即接收并处理该任务。Beacon 会在向 SharePoint 请求 TS 任务之前睡眠指定的时间,但由于异步 C2 的性质,这不会与 GraphStrike Server 上传任务的时间步调一致。
- 如果 Beacon 在没有正常退出的情况下死亡(例如被 AV 杀掉、崩溃等),Beacon 将看起来仍在向 TS 回连,而它已死亡的事实只有在您向其发出命令时才会显现。实际上连接到 TS / 使 Beacon 看起来仍在回连的是 GraphStrike 服务器,因此这实际上并不反映 Beacon 的健康状况。这就是异步 C2 的性质。
- GraphStrike 采用 1:1:1 模型:1 个 SharePoint 站点关联 1 个 GraphStrike 服务器,该服务器关联 1 个 TS。如果尝试将两个 TS/GraphStrike 服务器连接到一个 SharePoint 站点,将会出现问题。当然,您可以将多个 Cobalt Strike 客户端连接到一个 TS / GraphStrike 服务器,每个客户端只需要一份配置过程生成的 'client' 文件夹副本即可。
- 有一个 已知问题 关于 GraphStrike 使用的 az 工具与 Python 3.12 的兼容性。
- 建议您查阅 AceLdr 的文档,因为该项目的所有注释在此同样适用。
限制
GraphStrike 存在以下限制:
- 仅支持 x64 Beacon。
- 不支持分阶段 Beacon。
- GraphStrike 仅与 WinINet 库兼容;不支持新的 WinHTTP 库选项。
- 不支持通过 Beacon 的右键菜单发出 sleep 命令。请改用命令行选项设置 Beacon 的睡眠时间。
- GraphStrike 仅支持 Linux 版的 Cobalt Strike。Windows 支持当然可以实现,主要只需要更改 Python 文件和 Aggressor 脚本中的部分路径即可。
致谢
GraphStrike 的实现离不开以下个人的贡献:
- Kyle Avery 提供了 AceLdr
- Didier Stevens 提供了 cs-decrypt-metadata.py
- Red Siege 团队的 Mike Saunders、Corey Overstreet、Chris Truncer 和 Justin Palk,他们友好地进行了 GraphStrike 的 Beta 测试,并指出了在发布前已修复的多个问题。