ZeroPoint Security red team ops I CRTO 4 Cobalt Strike Primer

4 Cobalt Strike

市场领先的C2框架,提供后渗透agent

4.1 Components 组成

4.1.1 Beacon 信标

是 Cobalt Strike 的后渗透agent,负责与团队服务器通信,获取后渗透任务并将结果发送回服务器。Beacon 本身以 Windows DLL 的形式实现,但可以打包成各种格式的有效载荷,包括可执行文件、PowerShell 脚本和位置无关 shellcode。

4.1.2 Team Server 团队服务器

团队服务器是中央控制和日志系统,以及互动某些 Beacon 工作流程。

4.1.3 Client 客户端

红队队员使用客户端连接到一个或多个团队服务器,与 Beacon 有效载荷进行交互

4.2 Distributed operations 分布式操作

Cobalt Strike 的分布式运维设计模式是为作战的每个阶段(例如初始访问、后渗透和持久化)搭建专用的团队服务器。其原理是,如果部分运维活动被发现并阻止,其他通道仍可用于维持访问。Cobalt Strike 拥有多种基础设施整合功能,使这种模式易于实现。

4.3 Listeners 监听器

4.3.1 What is a listener? 什么是监听器?

配置 Cobalt Strike 的第一步是创建一个或多个监听器。监听器定义了 Beacon 有效载荷与团队服务器通信所使用的协议和参数。Cobalt Strike 默认提供的协议包括 DNS、HTTP、HTTPS、SMB 和 TCP。这些协议能够伪装 Beacon 生成的网络活动,使其看起来像是企业网络中常见的流量。

4.3.2 Listener Types 监听器类型

4.3.2.1 Egress 出口

出口信标会通过目标环境的网络边界直接与团队服务器通信。DNS 和 HTTP/S 都是出口监听器。

4.3.2.2 Peer-to-Peer 点对点

P2P 信标不直接与团队服务器通信,而是将其流量路由到另一个信标。多个 P2P 信标可以串联起来,但最终它们都会连接到一个出口信标,以便流量能够到达团队服务器。SMB 和 TCP 是 P2P 监听协议。

4.3.3 HTTP listener HTTP 监听器

HTTP 监听器指示 Beacon 通过 HTTP GET 和/或 POST 请求与团队服务器通信。默认情况下,它会使用 GET 请求从团队服务器获取任务,并使用 POST 请求将结果发送回服务器。团队服务器会启动一个内置的 Web 服务器来处理这些请求。

4.3.4 HTTP hosts HTTP 主机

这些是 Beacon 将 HTTP 请求发送到的主机,可以以 IP 地址或域名的形式提供。您可以使用直接解析回团队服务器的 IP 地址或域名;也可以使用解析到重定向器的 IP 地址/域名。重定向器是位于 Beacon 和团队服务器之间的中间主机,负责代理两者之间的流量。本课程不会深入讲解重定向器,但常用的重定向器软件包括 iptables、socat、Apache 和 NGINX。

4.3.5 Host rotation strategy 轮换策略

如果提供了多个 HTTP 主机,轮换策略会告诉 Beacon 如何使用每个主机。这有助于抵御频率分析技术对系统性 C2 流量的检测,并在一个或多个 HTTP 主机被阻塞的情况下提供弹性。可选策略包括: 轮询(round-robin) 、 随机(random) 、 故障转移(failover) 和轮换(rotate) 。

4.3.5.1 Round robin 循环

Beacon 简单地从上到下循环遍历列表。每个主机只处理一个请求,然后才会移动到下一个主机。

4.3.5.2 Random 随机的

Beacon 会为每个请求随机选择一个不同的主机

4.3.5.3 Failover 故障转移

failover-x 和 failover-m/h/d 。此配置指示 Beacon 持续使用同一主机,直到满足选定的故障转移条件——连续失败次数 x,或在指定时间段(以分钟、小时或天为单位)内连续发生故障。之后,Beacon 将切换到下一个主机,直到所有主机都无法继续使用为止。

4.3.5.4 Rotate 旋转

这种策略只有一种形式: rotate-m/h/d 。它类似于轮询,但每个主机只使用指定的时间段,然后就会切换到列表中的下一个主机。

4.3.6 Max retry strategy 最大重试策略

配置 Beacon 在所有 HTTP 主机丢失或被阻止(即我们完全失去与其通信的能力)的情况下的自毁策略。

4.3.6.1 None 没有

除非通过其他方式终止,否则 Beacon 将不会退出,并将无限期地继续运行。

4.3.6.2 Exit 出口

exit-[最大尝试次数]-[增加尝试次数]-[持续时间][分钟/小时/天]
max_attempts 是 Beacon 退出前允许连续失败的次数。
increase_attempts 是 Beacon 增加睡眠时间前连续失败的次数。
持续时间是指要设置的新睡眠时间的小时数、分钟数或天数。
exit-50-25-1h 告诉 Beacon 在 25 次尝试失败后将其睡眠时间增加到 1 小时,如果达到 50 次尝试失败则退出

4.3.7 HTTP host (stager) HTTP 主机(stager)

此主机仅供stager 有效负载使用。即使您配置了多个 HTTP 主机,暂存器有效负载也只能使用单个主机来获取完整的有效负载阶段。您可以使用与现有 HTTP 主机条目相同的 IP/域名,也可以使用完全不同的主机,只要它能解析回您的团队服务器即可。

4.3.8 Profile 配置

可灵活配置的 C2 配置文件可以设置多个流量变体,您可以从此下拉菜单中选择。除非您加载的配置文件中已配置了多个变体,否则您将看不到除默认设置之外的任何其他选项。

4.3.9 HTTP port (C2) HTTP 端口 (C2)

Beacon 将尝试连接到团队服务器的 HTTP 端口。除非您想使用非标准端口,否则大多数情况下,您应该将其设置为与协议相符的端口。例如,HTTP 协议通常使用 80 或 8080 端口。

4.3.10 HTTP port (bind) HTTP 端口(绑定)

团队服务器将绑定其内置 Web 服务器的端口。如果未指定任何选项,则将使用与上述相同的端口。只有在需要执行端口重定向(即使用重定向器监听 C2 端口,但将流量重定向到团队服务器的不同端口)时,才需要将其设置为不同的端口。这对于在同一团队服务器上运行多个 HTTP 监听器,同时保持所有 Beacon 都通过 80 端口对外通信非常有用。

4.3.11 HTTP host header HTTP 主机头

在此处设置主机头会将其传播到 Beacon 有效负载中,而无需在可塑性 C2 配置文件中显式设置。这使得利用域名伪装更加便捷,无需在任何配置文件中硬编码域名。

4.3.12 HTTP proxy HTTP 代理

默认情况下,Beacon 会尝试使用其运行所在系统的互联网代理配置。但是,如果需要,您可以为 Beacon 硬编码 HTTP 或 SOCKS 代理信息。此配置不适用于有效负载stager。

4.3.13 Guardrails 护栏/安全模式

Guardrails 会阻止stageless(无阶段) Beacon 有效载荷运行,除非满足指定的条件。这在有效载荷被复制或转发到目标环境之外的情况下非常有用。两种可能的场景包括:受害者将钓鱼邮件转发给外部人员;或者蓝队成员尝试在沙箱中分析有效载荷。可用的选项包括:主机的 IP 地址;帐户用户名;主机名;以及主机加入的域名。

4.4 DNS listener DNS 监听器

DNS 监听器指示 Beacon 通过 DNS 请求(具体来说是 A、AAAA 或 TXT 记录查找)与团队服务器通信。团队服务器启动一个内置的 DNS 服务器来处理这些请求。

要使 DNS 信标正常工作,您必须添加必要的 DNS 记录,使您的团队服务器对一个或多个子域具有权威性。在大多数情况下,您的域名注册商等机构将对您的顶级域名 (TLD) 具有权威性。

DNS 信标通过对 DNS 监听器中设置的域执行 A 记录查找来向团队服务器签入。与其他信标(例如 HTTP 信标)不同,DNS 信标不会立即传输其完整的元数据。这导致新创建的 DNS 信标最初显示为“空”行,没有任何信息。元数据只有在信标被分配任务后才会发送。有一个简单的 checkin 命令,其唯一作用就是传输信标的元数据。

4.4.1 DNS resolver DNS 解析器

默认情况下,DNS 信标会使用其运行所在计算机配置的 DNS 解析器。您可以通过在此字段中输入自定义 DNS 解析器的 IP 地址或主机名来覆盖此默认设置。

4.5 SMB Listeners SMB 监听器

SMB 监听器是第一个不绑定或监听团队服务器 VM 的监听器示例——它仅用作有效负载生成的模板。

执行时,SMB Beacon 有效负载会使用监听器配置中指定的管道名称创建一个 SMB 命名管道。然后,它需要另一个 Beacon 连接到该命名管道,并在 SMB Beacon 和团队服务器之间转发流量。这是通过 Windows SMB 协议在 445 端口上实现的。

Cobalt Strike 默认使用 msagent_## ,其中 ## 是随机十六进制值。但是,您可以使用任何您想要的管道名称,只要它不与主机上已存在的名称冲突即可。您还可以创建多个具有不同管道名称的 SMB 监听器。

4.6 TCP Listeners TCP 监听器

与 SMB 监听器类似,TCP 监听器不会指示团队服务器监听任何 TCP 端口。它会在生成 TCP 信标负载时提供配置信息。

执行时,TCP Beacon 负载将绑定并监听监听器配置中指定的 C2 端口。然后,它需要另一个 Beacon 连接到该端口,并在 TCP Beacon 和团队服务器之间转发流量。如果未选中 “仅绑定到本地主机 ”,则 Beacon 将绑定到 0.0.0.0 。如果选中,则它将绑定到 127.0.0.1 。

绑定到 0.0.0.0 的 TCP 监听器可用于横向移动;绑定到 127.0.0.1 的监听器可用于提权。您可以创建多个具有不同端口号和绑定配置的 TCP 监听器。

4.7 Beacon Payloads 信标有效载荷

Beacon 本身就是一个 Windows DLL 文件。想象一下加载到 Windows 进程中的“模块”(或 DLL),你会看到诸如 ntdll.dll、kernel32.dll 等文件。进程加载这些 DLL 文件是为了访问其中所需的功能。要执行 Beacon 有效载荷,我们需要将其 DLL 文件加载到进程中,并且(通常)需要启动一个新线程来调用其入口点。
图片

所谓的“无文件落地”:Windows DLL 通常从磁盘加载,一般位于 %windir%\system32 下,但这并非理想方案,因为我们不希望在 Beacon DLL 执行前将其加载到磁盘。

因此,Beacon 基于 Stephen Fewer 的工作成果 ,被实现为反射式 DLL。这种 DLL 可以直接从内存加载到进程中,而无需从磁盘加载。这就要求 DLL 具有反射式加载器,该加载器负责将自身映像重新加载到内存中,并执行诸如加载依赖模块之类的任务。Stephen 的代码库中的“概述”部分更详细地介绍了各个步骤。
https://github.com/stephenfewer/ReflectiveDLLInjection

下面展示的是一个过于简化的 PE 结构。
图片

Beacon 的 DLL 导出了一个名为 ReflectiveLoader 的函数。调用该函数时,它会遍历自身的镜像,将自身的新副本映射到内存中,然后调用其入口点。由于该 DLL 是以 shellcode 的形式导出的,因此在 DOS 头部写入了一小段 shellcode 存根。这段 shellcode 负责将代码执行跳转到导出的 ReflectiveLoader 函数。
图片

当 Cobalt Strike 生成有效载荷时,监听器配置中的相关信息会被添加到反射型 Beacon DLL 中,然后该 DLL 会被转换为位置无关代码 (PIC),即“shellcode”。随后,该 shellcode 会被嵌入到 Cobalt Strike 能够生成的每个有效载荷模板(或“工件”)中,例如 .exe 、 .dll 和 .ps1 文件。有效载荷本身使用进程注入技术来加载和执行 shellcode。伪代码可能如下所示:

// ReflectiveLoader + Beacon as PIC
unsigned char shellcode[1024] = "<shellcode>";

// Allocate new memory for shellcode
void* ptr = VirtualAlloc(0, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

// Copy shellcode into new memory region
memcpy(ptr, shellcode, 1024);

// Create a new thread to execute the ReflectiveLoader
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ptr, 0, 0, NULL);

4.7.1 The 'new' prepended loader 新的前置加载器

自 Cobalt Strike 4.11 版本以来,Beacon 开始使用一种基于 DoublePulsar 所用反射加载器的新型加载器。该加载器由美国国家安全局 (NSA) 开发,后被黑客组织“影子经纪人”(The Shadow Brokers) 泄露。该加载器因与 EternalBlue 和 WannaCry 勒索软件的关联而臭名昭著。

这是一款“前置式”加载器,也就是说,这意味着加载器是安装在 PE 前端的,而不是 PE 的一部分。下图(来自 Fortra)展示了两种装载器样式的区别。
图片

相比于直接加载,前置加载器总体上更隐蔽、更灵活。它不需要在 PE 的 DOS 头部写入 shellcode 存根;它可以反射加载任何 PE;它不需要 PE 导出任何反射加载过程所需的功能;并且它提供了更多混淆 PE 的选项。PE 本身可以进行编码、加密、压缩等处理,只要反射加载器知道如何撤销这些混淆,它仍然可以正常工作。

4.7.2 Staged vs stageless payloads 分阶段有效载荷与无阶段有效载荷

攻击框架(例如 Metasploit 和 Cobalt Strike)通常会将“漏洞利用”与“有效载荷”分离。想象一下,一个应用程序由于缓冲区溢出而存在代码执行漏洞——“漏洞利用”是触发溢出的代码,“有效载荷”则是你希望执行的代码(例如 Meterpreter 或 Beacon shellcode)。你可以传递的有效载荷大小可能受到多种因素的限制,例如漏洞本身的性质或其可访问的通道。如果你和我一样年纪大了,你可能还记得 MS08-067——Windows 系统中一个臭名昭著的远程代码执行 (RCE) 漏洞。这是一个堆栈损坏漏洞,必须在约 400 字节的限制内进行利用。

为了应对这些情况,“有效载荷暂存 payload staging ”技术应运而生。它由一个小型程序(暂存器 stager)组成,该程序执行时会通过与漏洞利用程序不同的通道(例如 HTTP)获取完整的有效载荷(暂存段 stage ),将其注入到新的内存区域,并将执行权交给该有效载荷。有效载荷暂存技术能够有效绕过此类漏洞利用限制,但它也存在一些缺点。

4.7.2.1 Payload security 有效载荷安全

Cobalt Strike 团队服务器首次启动时会生成一个新的唯一公钥/私钥对,并且该服务器生成的每个无阶段有效载荷都会嵌入该服务器的公钥。Beacon 在与团队服务器通信时使用此密钥加密其元数据,确保它只能与生成它的团队服务器通信。此外,每个 Beacon 都使用一个唯一的会话密钥,用于加密/解密与团队服务器交换的任务/输出数据。该会话密钥本身包含在加密的元数据中传输,因此只有正确的团队服务器才能加密和解密 Beacon 的 C2 流量。这样做的好处是,攻击者无法轻易对无阶段有效载荷进行中间人攻击来劫持其控制权。然而,由于其体积较小,阶段器不具备相同的安全性。执行时,阶段器会连接到其配置的主机/端口以接收有效载荷阶段的其余部分。暂存器没有进行验证以确保它正在与合法的团队服务器通信,这使得它们在首次执行时容易受到劫持。

4.7.2.2 OPSEC 行动安全

为了尽可能减小暂存器的大小,它们必须省略一些我们现在可能认为是“最佳实践”的步骤。例如,完全无暂存有效载荷避免使用 RWX(读、写、执行)内存,因为这在大多数 Windows 进程中都显得不寻常。相反,它们会先分配 RW 内存,然后在执行前将其转换为 RX。有效载荷暂存器不这样做,因为这需要额外的 API 调用,从而需要编写更多代码。暂存器通常使用手工优化的汇编语言编写,因此每个可以节省的字节都会被节省。

为了让大家对大小差异有个概念——目前,一个 Beacon 暂存器大约是 890 字节,而一个完整的 Beacon 暂存器大约是 307200 字节。这大约是原来的 345 倍。

4.7.3 Generating payloads 生成有效载荷

可以从“有效载荷”菜单生成信标有效载荷。

4.7.3.1 HTML application HTML 应用程序

此选项会生成 .hta 格式的有效载荷,该格式是 HTML 和 VBScript 的组合。VBScript 是 Internet Explorer 支持的脚本语言,因此成为网络钓鱼攻击中常用的有效载荷格式。对话框会提示您选择监听器和执行方法。

4.7.3.1.1 Executable 可执行文件

将一个可执行文件拖放到磁盘上并运行它。

4.7.3.1.2 PowerShell

使用 powershell.exe 在内存中运行暂存器。

4.7.3.1.3 VBA

使用 VBA 宏在内存中运行暂存器。该宏通过使用 VBScript 实例化 Excel.Application 并创建工作簿实例来执行。目标系统需要安装 Microsoft Office。

此 HTA 始终提供 x86 Beacon 有效载荷。

4.7.3.2 MS Office macro MS Office 宏

此选项将生成一个 VBA 宏,您可以将其粘贴到 Office 文档中——这是另一种流行的网络钓鱼有效载荷格式。

此宏始终传递 x86 Beacon 有效载荷。

4.7.3.3 Stager payload generator 舞台有效载荷生成器

这些有效载荷生成器可以生成多种语言的源代码文件,功能类似于 Metasploit 的 msfvenom 工具。当您需要一个可以导入到您自己的 shellcode 运行器中的字节数组时,它们非常有用。

例如,用 C 语言输出一个 stager 会得到以下结果:

/* length: 888 bytes */
unsigned char buf[] = "\xfc\x48\x83\xe4[...snip...]\x12\x1d\x9b\x09";

4.7.3.4 Stageless payload generator 无级有效载荷生成器

无级有效载荷生成器与有级有效载荷生成器几乎完全相同,但提供了更多选项。

4.7.3.4.1 Exit Function 退出功能

此设置控制 Beacon 执行 exit 命令时调用的 API。Process 调用 ExitProcess ,这将终止 Beacon 运行所在的整个进程;而 Thread 调用 ExitThread ,它只会终止运行 Beacon 的线程。ExitProcess (xprocess) 和 ExitThread (xthread) 有效载荷各有用途。如果 Beacon 被注入到目标系统上已运行的进程中,请使用 xthread。如果被注入到由您执行的进程中,则请使用 xprocess。
https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-exitprocess

4.7.3.4.2 system Call 系统调用

这指示 Beacon 使用系统调用而非常规 Win32 API 来进行内部操作。有两种选择:
直接使用的是 Nt* 版本的函数。
间接跳转到函数的 Nt* 版本中的相应指令。

4.7.3.5 Windows stager/stageless 有效负载

这些选项类似于分阶段/无分阶段有效载荷生成器,但它们输出的不是原始源文件,而是预编译的可执行文件。输出选项包括:
Windows EXE:一个标准的 Windows 可执行文件。
Windows 服务 EXE:一个专门设计用于与服务控制管理器交互的 Windows 可执行文件。
Windows DLL:一个包含多个导出项的 DLL,可以通过 rundll32 和 regsvr32 等实用程序调用这些导出项。

这些有效载荷也可以使用代码签名证书进行签名。

4.7.3.6 Windows Stageless Generate All Payloads Windows Stageless 生成所有有效负载

此选项将为 x86 和 x64 架构中的每个可用监听器生成所有可能的无阶段有效载荷变体。

4.7.3 Interacting with Beacon 与 Beacon 交互

当一个新的 Beacon 会话首次签入团队服务器时,事件日志( 查看事件日志 )中将出现一条记录,并且根据所选视图,表格或图表视图中将出现一个新的会话。

表格视图中的各列含义都相当直观,但这里还是做个简要概述:
external 指的是目标的外部 IP 地址。该地址由 Cobalt Strike 的 Web 服务器解析,并非由 Beacon 本身发送。
internal 是计算机的内部 IP 地址。
listener 是 Beacon 通信所用的出口监听器的名称。
user 是 Beacon 进程运行所使用的用户名。
computer 就是计算机的主机名。
note 是您可以添加自己的备注的地方。
process 是 Beacon 运行所在的进程的名称。
pid 是 Beacon 运行所在的进程 ID。
arch 是 Beacon 架构,可以是 x64 或 x86。
last 是信标与团队服务器通信的最后一次时间,单位为毫秒、秒、分、小时或天。
sleep 是指灯塔的睡眠时间。

蓝色监视器图标表示 Beacon 以中等完整性级别(即标准用户权限)运行。以高完整性级别(即本地管理员或 SYSTEM 权限)运行时,将显示红色监视器图标,并且用户名后会附加星号。

Beacon 通过 C2 协议发送元数据来向团队服务器标识自身。对于 HTTP/S 协议,元数据通常位于 GET 或 POST 请求的 URL、请求头或 Cookie 等位置。元数据本身使用生成有效负载的团队服务器的公钥进行加密。这可以防止 Beacon 与其他团队服务器通信或被其他团队服务器指派任务。

要与信标“互动”,请双击其所在行或右键单击并选择 “互动” 。这将打开一个新标签页。

要查看命令列表,请在底部的文本框中输入 help 并按回车键。这将显示每个命令的简要说明。

要获取有关特定命令的更多帮助,请使用 help <command>

要给信标发送任务,只需输入有效的命令,然后再次按回车键。这样就会将任务添加到队列中。

在等待 Beacon 签到期间,您可以将多个命令排队。可以使用 clear 命令清空队列。如果 Beacon 签到时有任务可用,团队服务器会在流量响应中提供这些任务。客户端还会打印一条简短的日志,以指示任务已发送。

Beacon 会按照任务排队的顺序处理每个任务,并将结果发送回客户端。客户端随后会将输出结果显示给操作员。

4.7.3.1 Session Graph View 会话图视图

下图显示了一个出口和两个 P2P 信标,但乍一看并不清楚哪个信标连接到哪个。这两个 P2P 信标都是直接连接到 HTTP 信标,还是以其他方式连接的?

这时,图表视图就派上用场了。虽然它显示的信息比表格视图少,但每个信标之间的关系却一目了然。

防火墙图标和虚线代表直接与团队服务器通信的出口信标。实线代表 P2P 连接。颜色也代表所使用的协议。它们分别是:
虚线绿色表示 HTTP/S。
纯黄色代表SMB。
黄色虚线代表 DNS。
TCP 为实心绿色。
在黑色背景上任意位置单击鼠标右键,即可调出包含其他布局选项的菜单。此处显示的默认布局为 “树状左视图” 。您也可以右键单击信标,调出与表格视图中相同的交互菜单。

posted @ 2026-04-13 11:53  sec875  阅读(17)  评论(0)    收藏  举报