SimpleC2框架设计文档
SimpleC2 框架设计文档
本文档为项目SimpleC2的设计文档,仅作为设计思路参考。
1. 引言
1.1 目的
本文档旨在定义一个采用分离式架构、以接口驱动、高度模块化和通信协议无关为核心原则的C2框架架构。其关键目标是实现核心业务逻辑 (TeamServer) 与通信传输层 (Listener 服务) 的物理和逻辑解耦。通过定义清晰的远程过程调用 (RPC) 接口契约,允许独立部署和扩展 Listener 服务,无缝集成多样化的隐蔽通信信道和 Beacon 实现,以满足设计需求。
1.2 范围
本文档详细描述了框架的分离式架构、核心组件职责、TeamServer 面向 Listener 的 gRPC 接口规范 (TeamServerBridgeService)、Listener 服务的管理要求、关键数据流、数据模型、Operator API 设计、安全性、扩展性和运维考量。
1.3 非目标
本文档不规定以下内容:
Listener与Beacon之间具体的通信协议实现细节(如 HTTP/S 请求/响应格式、DNS 查询/响应构造、SMB 管道协议等)。Listener与Beacon之间数据在传输过程中的具体编码(如 Base64, Hex 等)和加密算法(如 AES, RSA 等)的选择与实现。- 流量特征的具体定义(如 C2 Profile / Malleable C2 的具体参数和行为)。
这些传输层和协议层的具体实现留给 Listener 及其对应的 Beacon 实现者根据需求自定义,以最大化隐蔽性和灵活性。
1.4 术语定义
- TeamServer: C2 框架的核心后端服务,作为业务逻辑中心和数据存储中心。
- Listener Service: 独立运行的服务进程,负责监听特定网络端点,处理与 Beacon 的通信,并通过 RPC 与 TeamServer 交互。
- Beacon / Implant: 部署在目标主机上的代理程序,负责执行指令并与 Listener 通信。
- Operator Client: 操作员使用的前端界面(GUI/CLI),通过 TeamServer API 与 C2 框架交互。
- Staging: Beacon 首次与 Listener/TeamServer 建立连接并注册的过程。
- CheckIn: 已注册 Beacon 定期向 Listener/TeamServer 发送心跳以表明存活并请求任务的过程。
- PushOutput: Beacon 将任务执行结果回传给 Listener/TeamServer 的过程。
- SessionKey: TeamServer 为每个 Beacon 会话生成的对称加密密钥,用于加密/解密 CheckIn 后的任务和结果数据。
- SharedSecret: Listener Service 配置中用于初始连接或元数据验证/解密的共享密钥。
- Task: TeamServer 下发给 Beacon 的指令单元,包含任务 ID、指令 ID 和参数。
- CommandID: 标识特定操作(如执行 shell 命令、下载文件等)的数字代码或唯一标识符。
- TeamServerBridgeService: 定义 Listener Service 与 TeamServer 核心业务逻辑交互的 gRPC 服务接口。
- Listener Management API: TeamServer 提供的用于管理 Listener Service 配置和定义的 API (通常供 Operator Client 或部署脚本使用)。
- RPC (Remote Procedure Call): 远程过程调用,本文档推荐使用 gRPC。
- gRPC: Google 开发的高性能、开源通用 RPC 框架。
- mTLS (Mutual TLS): 双向 TLS 认证,用于确保 TeamServer 和 Listener Service 之间的通信安全和相互身份验证。
2. 系统架构
2.1 概述
框架采用物理分离的多层架构:
- 核心服务层 (TeamServer): 单独部署,负责核心业务和数据。
- 通信适配层 (Listener Services): 一个或多个独立部署的 Listener 服务实例,每个实例处理一种或多种通信协议。
- 代理执行层 (Beacon/Implant): 部署在目标。
- 操作员接口层 (Operator Client): 连接 TeamServer API。
2.2 架构图
1 | graph TD |
2.3 组件职责详述
- TeamServer:
- 管理
Listener的逻辑配置(通过 Operator API),包括名称、类型、配置参数(如监听地址建议、SharedSecret等),但不直接管理Listener Service进程。 - 维护所有已注册
Beacon的会话状态(基于结构化的BeaconMetadata),包括 ID、SessionKey、心跳时间、任务队列、关联目标、状态等。 - 提供安全的 RESTful API 供
Operator Client进行认证 (JWT)、资源管理、任务下发与结果查询。 - 实现
TeamServerBridgeServicegRPC 接口,处理来自已认证Listener Service的远程调用。 - 负责任务的生命周期管理:创建、排队、分发给
Beacon(通过TaskResult)、跟踪状态、处理结果(来自PushBeaconOutput)。 - 利用数据库(推荐 PostgreSQL)持久化存储框架状态和操作数据。
- 提供事件通知机制(如 WebSocket)将实时状态变更推送给
Operator Client。 - 管理框架级别的配置、日志记录和用户认证。
- 负责生成和管理 mTLS 证书以及 Listener Service 的应用层认证凭据(如 API Key)。
- 管理
- Listener Service:
- 作为独立的、可横向扩展的服务进程运行。
- 根据配置监听指定的网络端点,实现特定的通信协议(HTTP/S, DNS, SMB 等)。
- 协议适配 & 数据转换: 完全负责将
Beacon的原始流量转换为TeamServerBridgeService要求的 gRPC 请求消息,反之亦然。 - 加密/编码:
- Ingress: 使用自身配置的
SharedSecret(通过 RPC 从 TeamServer 获取或静态配置)解密/解码 Beacon 初始连接/元数据;使用GetBeaconSessionKeyRPC 调用获取的SessionKey解密/解码后续的结果数据。 - Egress: 使用
GetBeaconSessionKeyRPC 调用获取的SessionKey加密从CheckInBeaconRPC 调用获取的原始任务数据;根据协议需要进行编码和封装。
- Ingress: 使用自身配置的
- gRPC 客户端: 实现
TeamServerBridgeService的 gRPC 客户端,负责:- 建立到 TeamServer 的安全连接 (mTLS)。
- 进行应用层认证(如在 gRPC Metadata 中附加 API Key)。
- 发起
StageBeacon,CheckInBeacon,PushBeaconOutput等 RPC 调用。 - 处理 RPC 错误和网络中断。
- 状态与配置: 独立管理自身的运行时配置(监听地址、端口、TeamServer gRPC 地址、mTLS 证书/密钥、API Key 等)和状态。通过
LogListenerEventRPC 调用向 TeamServer 报告关键事件和错误。
- Beacon/Implant:
- 与特定
Listener Service的通信协议、加密、编码机制紧密耦合。 - 负责执行
Task.Arguments中包含的具体指令。 - 按照约定格式打包元数据、心跳和结果。
- 与特定
- Operator Client:
- 通过 TeamServer 的 RESTful API 进行交互。
- 对 Listener Service 的存在和具体通信协议无感知。
- 负责呈现 TeamServer 提供的统一视图,接收操作员指令。
2.4 核心数据流图
Staging Flow (gRPC):
1 | sequenceDiagram |
CheckIn & Tasking Flow (gRPC):
1 | sequenceDiagram |
Push Output Flow (gRPC):
1 | sequenceDiagram |
2.5 并发模型
- TeamServer:
- gRPC 服务端应使用 Go 的标准库或成熟框架实现,具备高并发处理能力。
- 业务逻辑层处理每个 gRPC 请求时应是并发安全的,使用互斥锁、读写锁或 Channel 保护共享资源(如 Beacon 状态 map、任务队列)。
- 数据库操作应使用连接池。
- 对于可能耗时的操作(如处理大型文件上传/下载关联的结果),考虑使用后台 Goroutine 或任务队列进行异步处理,避免阻塞 gRPC 响应。
- Listener Service:
- 应能高效处理大量并发的 Beacon 连接/请求。
- 对于每个 Beacon 连接或请求,通常启动一个 Goroutine 处理其生命周期内的所有逻辑,包括协议处理、加解密和 gRPC 调用。
- gRPC 客户端应配置连接池以复用与 TeamServer 的连接。
- 需要考虑资源限制,防止过多并发连接耗尽系统资源。
3. TeamServer - Listener Service RPC 接口 (TeamServerBridgeService)
技术选型: gRPC (基于 Protocol Buffers)
通信安全: 强制 mTLS + 可选的应用层认证 (如 API Key in Metadata)
Protocol Buffers 定义 (bridge.proto):
1 | syntax = "proto3"; |
关键交互说明:
-
认证: 所有 gRPC 调用必须通过 mTLS 验证。TeamServer 可选地检查请求 Metadata 中的应用层凭据(如 API Key)。
-
错误处理约定:
- gRPC Status Codes: TeamServer 应使用标准的 gRPC 状态码来指示 RPC 调用的基本结果。
OK (0): 请求成功处理。NOT_FOUND (5): 请求的资源(如 BeaconID, ListenerName)不存在。UNAUTHENTICATED (16): Listener Service 的 mTLS 证书或应用层凭据无效/缺失。PERMISSION_DENIED (7): Listener Service 认证成功,但无权执行请求的操作。INVALID_ARGUMENT (3): 请求消息中的参数格式错误、缺失必要字段或值无效。FAILED_PRECONDITION (9): 操作无法执行,因为系统状态不满足前提条件(例如,尝试对已下线的 Beacon 下发任务)。INTERNAL (13): TeamServer 内部发生未预期的错误。UNAVAILABLE (14): TeamServer 暂时无法处理请求(例如,过载、维护中)。
- gRPC Error Details: 对于需要传递更具体业务错误信息的场景(例如,
StageBeacon失败的具体原因),TeamServer 可以在 gRPC 错误中附加google.rpc.Status消息,并在其details字段中包含自定义的 Protobuf 消息或google.rpc.ErrorInfo,提供详细的错误代码和描述。Listener Service 应准备处理这些 Details。
- gRPC Status Codes: TeamServer 应使用标准的 gRPC 状态码来指示 RPC 调用的基本结果。
-
数据打包约定 (
Task.arguments,PushBeaconOutputRequest.output):- 约定: TeamServer 与 Beacon 之间传递的
arguments和output字段 (bytes) 必须遵循统一的内部二进制打包格式。 - 推荐格式:
- 基础类型: 使用 Go
encoding/binary包,统一采用大端序 (BigEndian) 进行读写。int8/uint8: 1 字节int16/uint16: 2 字节int32/uint32: 4 字节int64/uint64: 8 字节
- 变长数据 (
string,[]byte): 前缀 4 字节大端序uint32表示后续数据的字节长度,然后紧跟数据本身。字符串应使用 UTF-8 编码,不需要以\x00结尾(长度已明确)。
- 基础类型: 使用 Go
- 职责:
TeamServer: 在构造Task.arguments时,按照此格式打包。在处理PushBeaconOutputRequest.output时,按照此格式解包。Beacon: 在解析Task.arguments时,按照此格式解包。在构造output数据时,按照此格式打包。Listener Service: 不关心此内部格式的具体内容,仅负责将Task.arguments(从TaskResult获得后) 和output(在调用PushBeaconOutput前) 作为bytes进行加密/解密和透传。
- 示例: 打包
CommandID=1 (uint32),Arg1="C:\path" (string),Arg2=[]byte{0xDE, 0xAD}:[00 00 00 01] [00 00 00 07] [43 3A 5C 70 61 74 68] [00 00 00 02] [DE AD](方括号仅为分隔示意)
- 约定: TeamServer 与 Beacon 之间传递的
-
GetBeaconSessionKey缓存: Listener Service 应当在其内部缓存从GetBeaconSessionKey获取的SessionKey,以BeaconID作为键。缓存应设置合理的过期策略(例如 LRU 或基于时间的 TTL),并在 gRPC 调用返回NOT_FOUND或认证错误时清除缓存项。这可以显著减少 RPC 调用次数。
4. Listener Service 管理
- 注册与发现:
- 手动配置: 操作员在 TeamServer UI/API 创建 Listener 配置(生成
SharedSecret, mTLS 证书签名请求 CSR 或提供证书/密钥对),然后将 TeamServer gRPC 地址、SharedSecret、客户端证书/密钥、可选 API Key 等信息配置到 Listener Service 实例。
- 手动配置: 操作员在 TeamServer UI/API 创建 Listener 配置(生成
- 配置管理与 TeamServer 关联:
- TeamServer Operator API (
/listeners) 用于管理 Listener 的逻辑定义,包括:name(唯一标识符)type(如 “http”, “dns”, 对应 Listener Service 实现的类型)config(一个 JSON 对象,包含 TeamServer 希望 Listener 使用的配置,如建议的监听地址/端口、SharedSecret、C2 Profile 参数等)。
- 操作流程:
- 操作员通过 Operator Client 调用
/listeners(POST) 创建一个新的 Listener 逻辑配置。 - TeamServer 生成
SharedSecret,可能还包括该 Listener Service 连接 TeamServer 所需的 mTLS 客户端证书/密钥对(或 CSR)和应用层 API Key,并将这些敏感信息与配置模板一起返回给 Operator Client。 - 操作员手动将这些配置(监听地址、端口、
SharedSecret、TeamServer gRPC 地址、mTLS 凭据、API Key 等)部署到实际运行的 Listener Service 实例上(通过配置文件、环境变量等)。
- 操作员通过 Operator Client 调用
- 解耦: TeamServer 不直接控制 Listener Service 进程的启动、停止或运行时配置更新。它只维护逻辑配置,并依赖 Listener Service 在启动时或运行时根据其获取到的配置连接 TeamServer。
- TeamServer Operator API (
- 健康检查: TeamServer 可选地提供一个 gRPC 健康检查端点 (
grpc.health.v1.Health)。Listener Service 应定期检查 TeamServer 健康状态。TeamServer 也应能(通过 Operator API 或内部机制)大致了解哪些 Listener Service 实例在活动(例如基于最近的 RPC 调用时间戳)。
5. Beacon 实现考量
- 配置: 需要安全存储 Listener Service 地址、
SharedSecret(或用于协商的密钥)、自身 ID、公/私钥(如果使用非对称加密)。 - 通信: 实现与目标 Listener Service 完全匹配的协议、加密、编码。需要处理网络中断和重试。
- 密钥交换 (Staging): 如果使用非对称加密,Beacon 需生成密钥对,将公钥包含在 Staging 请求中,接收并解密 TeamServer(经 Listener 转发)返回的加密后的
SessionKey。 - 任务处理: 实现任务循环,接收加密任务,使用
SessionKey解密,解包Task结构,根据CommandID分发给执行函数,执行,打包结果(含TaskID,CommandID,Status,Output),使用SessionKey加密,然后发送给 Listener Service。 - 错误处理: 任务执行失败时,需打包包含错误状态码和信息的
OutputInfo进行回传。
6. 核心数据模型 (TeamServer 内部)
- Beacon Session: 存储
BeaconID,BeaconMetadata,SessionKey,ListenerName,RemoteAddr,FirstSeen,LastSeen,Status(Active/Inactive),TaskQueue(待处理任务列表),CompletedTasks(最近完成的任务ID,用于去重)。 - Listener Instance: 存储
Name,Type,Config(ListenerConfig),Status(Running/Stopped), 关联的IListener实例。 - Task Record: 存储
TaskID,BeaconID,CommandID,Arguments,Status(Queued/Sent/Processing/Completed/Error),RequestTime,SentTime,CompletionTime,Output。 - Operator: 存储用户名、密码哈希、角色/权限、上次登录时间等。
- Credential: 存储从目标获取的凭据信息。
- Target: 存储关于目标主机的信息(可能通过
BeaconMetadata或手动添加)。 - Event Log: 记录关键操作和事件(Beacon 上线/下线, 任务下发/完成, 操作员登录等)。
7. TeamServer API 设计
- 认证:
/auth/login(POST, user/pass -> JWT),/auth/refresh(POST, refresh token -> new JWT)。API 请求需携带有效的 JWT Bearer Token。 - Listeners:
/listeners(GET: list, POST: create),/listeners/{name}(GET: details, PUT: update, DELETE: delete, POST /start, POST /stop)。 - Beacons:
/beacons(GET: list active/inactive),/beacons/{beacon_id}(GET: details, DELETE: remove),/beacons/{beacon_id}/tasks(POST: queue new task)。 - Tasks:
/tasks(GET: list all/filtered tasks),/tasks/{task_id}(GET: details including output)。 - Generation:
/generate/beacon(POST: config -> beacon binary/payload)。 - Real-time Events: WebSocket 端点
/events用于推送 Beacon 上线/下线、新任务输出等事件。 - 数据格式: 所有 API 端点使用 JSON 进行请求和响应。
8. 安全性考量
- TeamServer-Listener 通信:
- 强制 mTLS: 使用强加密套件,确保证书有效性检查。证书应包含可识别 Listener 实例的信息(如 CN 或 SAN)。
- 应用层认证: Listener Service 在每次 gRPC 调用时,应在请求的 Metadata 中附加认证凭据。推荐使用由 TeamServer 为每个 Listener 实例生成的、长期有效的 API Key。格式示例:
metadata.Append("authorization", "Bearer <ListenerAPIKey>")。TeamServer 的 gRPC 服务端拦截器 (Interceptor) 负责验证此 Key 的有效性,并可据此进行访问控制。API Key 应具备足够的熵,并通过安全渠道分发给 Listener Service。 - 网络隔离: TeamServer 的 gRPC 端口应仅对受信任的 Listener Service 网络开放。
- Listener Service 安全:
- 最小权限运行。
- 安全存储客户端证书私钥和 API Key(使用文件权限、Secrets Management 工具等)。
- 输入验证和协议解析健壮性,防止针对 Listener 的攻击。
- 限制 Listener Service 对 TeamServer 的访问权限(如果 TeamServer 支持基于 API Key 的细粒度授权)。
- TeamServer Operator API 安全:
- 强制 HTTPS。
- 使用强密码策略和 MFA(如果可能)。
- 基于 JWT 的会话管理,设置合理的过期时间。
- RBAC 权限控制。
- API 速率限制和输入验证。
- 数据库安全:
- 使用强凭据,限制数据库用户权限。
- 考虑对敏感数据进行加密存储。
- 定期备份。
- Beacon 安全:
- 配置信息加密存储。
- 使用内存执行、反调试、代码混淆等技术增加逆向难度。
- 确保
SessionKey的安全存储和使用。
- 密钥管理:
SessionKey应为每个 Beacon 会话唯一,使用强随机源生成。- 考虑使用 Key Management System (KMS) 或 Hardware Security Module (HSM) 存储敏感密钥(如 TeamServer 的私钥)。
9. 可扩展性设计
- Listener Service 开发: 提供清晰的文档和示例,说明如何实现一个新的 Listener Service,包括:
- 实现 gRPC 客户端逻辑以调用
TeamServerBridgeService。 - 处理自身协议的监听、数据收发、加解密、编码解码。
- 配置管理和日志记录。
- 实现 gRPC 客户端逻辑以调用
- Command 扩展:
- 定义 CommandID 时,建议采用枚举或常量定义,并在 TeamServer 和 Beacon 之间共享(例如,通过代码生成或共享库)。
- TeamServer 需要注册新的命令处理器来解析 Operator 输入、构建
Task.arguments(遵循打包约定)以及处理对应的OutputInfo.output(遵循打包约定)。 - Beacon 需要添加新的命令处理器来解包
Task.arguments、执行逻辑并打包output。
- TeamServer 内部模块化: TeamServer 内部也应采用模块化设计,例如将 Beacon 管理、任务处理、数据存储等功能分离到不同的包或服务中,便于独立维护和扩展。
10. 持久化设计
- 数据库: PostgreSQL。
- 数据模型: 使用 GORM 映射 Go 结构体到数据库表。核心模型应包含 Beacons, Listeners, Tasks, Outputs, Operators, Credentials, Targets, EventLogs 等。
- 模式迁移: 应包含数据库模式迁移 (Schema Migration) 方案(如使用
golang-migrate)。
11. 部署与运维
- TeamServer:
- 部署为独立服务(二进制或容器)。
- 需要配置数据库连接、gRPC 服务端口、mTLS 证书/密钥、Operator API 端口等。
- 高可用:可部署多个实例,通过负载均衡器分发 Operator API 请求。gRPC 服务可能需要更复杂的负载均衡策略或服务发现。数据库应采用主从或集群模式。
- Listener Service:
- 部署为独立服务(二进制或容器),可部署在不同网络区域。
- 需要配置监听端口/协议参数、TeamServer gRPC 地址、mTLS 客户端证书/密钥、API Key、
SharedSecret等。 - 可根据负载轻松进行水平扩展。
- 配置管理: 推荐使用配置管理工具(Ansible, Chef, Puppet)或 Secrets Management(Vault)来安全地分发和管理 TeamServer 和 Listener Service 的配置及凭据。
- 监控: 对 TeamServer 和所有 Listener Service 实例进行健康检查、性能监控(CPU, Mem, Network I/O, gRPC QPS/Latency)和日志聚合(如 ELK Stack, Grafana Loki)。
- 证书管理: 建立证书颁发、续期和吊销流程 (如使用内部 CA 或 Let’s Encrypt)。