用于与 Cobalt Strike 的 External C2 规范配合使用的 Python 框架,该规范见规范。
主要设计目标是成为 external c2 规范的一种高度模块化实现,提供足够的抽象,以便轻松为 Cobalt Strike 实现 C2 信道。理想情况下,用户只需创建一个 transport 模块、一个 encoder 模块,并填写一个配置文件,即可实现新的信道。
在开始运行之前,你需要完成几项配置更改。你需要:
builds/client/dbox/dbox_client.py 中,将 token 改为第 2 步中生成的令牌。builds/server/utils/transports/transport_dbox.py 中进行与第 3 步相同的更改。cd builds/client/dbox && ./compile_dll.sh 编译你的 DLL。start_externalc2.cna 脚本。cd builds/server/ && ./dbox_server.py 启动服务器。本项目由三个主要部分组成:
构建器根据指定的配置动态构建客户端和服务端部署。理想情况下,客户端可以作为单个编译文件(如 dll 或 exe)分发。
客户端本质上是在端点上运行的 payload,规范中称之为 third-party client。客户端的逻辑主要是静态的:
transport 所需的一切准备工作transport 将 beacon 的元数据转发到 C2 服务器transport 中的新任务transport 转发 beacon 的响应transport 与编码机制所需的配置会被静态复制到客户端中。传输和编码机制的函数逻辑也会从各自模块静态复制到客户端中。
进程注入逻辑由构建器确定。
服务器是在 client 与 c2 server 之间转发通信的应用程序,规范中称之为 third-party Client Controller。服务器逻辑主要是静态的,但支持详细输出和调试输出,以辅助开发:
encoder 模块对 stager 进行编码transport 模块传输 stagertransport 接收来自客户端的元数据响应encoder 模块解码元数据transport 将新任务转发给客户端transport 接收来自客户端的响应encoder 模块解码响应服务器导入哪个 encoder 和 transport 模块,取决于 config.py 中存储的值。
不会导入未使用的 transport 或 encoder 模块。
下表描述了 encoding 和 transport 模块与客户端之间的共享函数。共享函数本质上就是完全相同的代码。
非常重要的说明: 发送到客户端的 sendData 和 recvData 函数的数据应为原始数据,而发送到 transport 模块的 sendData 和 retrieveData 函数的数据应已经按需进行编码或解码。
| Transport 函数 | 客户端函数 | 描述 |
|---|---|---|
| prepTransport | prepTransport | 执行使用 transport 机制所需的任何预配置 |
| sendData | sendData | 定义数据如何通过 transport 机制发送 |
| retrieveData | recvData | 定义数据如何通过 transport 机制接收 |
| 编码器函数 | 客户端函数 | 描述 |
|---|---|---|
| encode | encode | 定义对原始数据进行修改以准备传输 |
| decode | decode | 定义对从 transport 收到的原始数据进行修改,以便转发到其目的地 |
首先,确定你要使用的 transport 和编码模块。在以下示例中,我们将使用 transport_gmail 和 encoder_b64url。
接下来,根据你的需要修改 server/config.py,确保 ENCODER_MODULE 和 TRANSPORT_MODULE 已正确配置,并指向你想要的模块:
EXTERNAL_C2_ADDR = "127.0.0.1"
EXTERNAL_C2_PORT = "2222"
C2_PIPE_NAME = "foobar"
C2_BLOCK_TIME = 100
C2_ARCH = "x86"
IDLE_TIME = 5
ENCODER_MODULE = "encoder_b64url"
TRANSPORT_MODULE = "transport_gmail"
verbose = False
debug = False
接下来,为你选择的 transport 和 encoder 模块修改配置部分。
确保 client/mechanism/$mechanism_client.py 的配置部分与你目前定义的任何配置一致。
在运行服务器的机器上,执行:
python server.py
如需更详细的输出,可以运行:
python server.py -v
如需更详细的输出以及有助于调试的额外输出,可以运行:
python server.py -d
接下来,在目标端点上执行客户端。
如果一切正常,Cobalt Strike 控制台中将会注册一个新的 beacon,你可以与之交互。
为什么写这个?: 针对该规范的已发布实现并不多,而已发布的实现要么使用的不是我所熟悉的语言,要么不具备我所寻求的模块化和抽象性。
为什么用 Python 2?: 我很懒,而且用它实现新的 transport 和编码信道很容易。
你的代码很烂: 这不是一个问题。
我可以提交新的 transport 和/或 encoder 模块吗?: 当然可以!提交一个 pull request,我会很乐意审查。
类似的抽象和模块化也将在客户端组件中实现,以支持针对 beacon payload 的不同进程注入方法以及路线图上的其他功能。
目前缺少 builder 功能;该功能计划用于动态构建客户端和服务端部署,但它已在路线图上。