// Package c2 实现 CyberStrikeAI 内置 C2(Command & Control)框架。 // // 设计概述: // - Manager 作为统一入口,被 internal/app 实例化并注入到所有需要操控 C2 的组件 // (HTTP handler、MCP 工具、HITL 桥、攻击链记录器等)。 // - Listener 是抽象接口,下挂 tcp_reverse / http_beacon / https_beacon / websocket // 等不同传输方式的具体实现,全部通过 listener.Registry 工厂创建。 // - 任务调度走数据库(c2_tasks 表)+ 内存事件总线(EventBus)混合: // * 状态变化与历史记录靠 SQLite 实现持久化与重启恢复; // * 高频实时通知(如新任务结果)通过 EventBus 推送给 SSE/WS 订阅者,避免轮询。 // - Crypto 层固定 AES-256-GCM,每个 Listener 独立 32 字节密钥;密钥仅服务端持有 // 和编译期注入到 implant,事件流不允许导出明文密钥。 package c2 import ( "errors" "strings" "time" ) // ListenerType 监听器类型,与 c2_listeners.type 字段一致 type ListenerType string const ( ListenerTypeTCPReverse ListenerType = "tcp_reverse" ListenerTypeHTTPBeacon ListenerType = "http_beacon" ListenerTypeHTTPSBeacon ListenerType = "https_beacon" ListenerTypeWebSocket ListenerType = "websocket" ) // AllListenerTypes 列出所有受支持的监听器类型,便于校验与前端枚举 func AllListenerTypes() []ListenerType { return []ListenerType{ ListenerTypeTCPReverse, ListenerTypeHTTPBeacon, ListenerTypeHTTPSBeacon, ListenerTypeWebSocket, } } // IsValidListenerType 校验前端/MCP 入参是否为合法 type func IsValidListenerType(t string) bool { t = strings.ToLower(strings.TrimSpace(t)) for _, lt := range AllListenerTypes() { if string(lt) == t { return true } } return false } // SessionStatus 与 c2_sessions.status 一致 type SessionStatus string const ( SessionActive SessionStatus = "active" SessionSleeping SessionStatus = "sleeping" SessionDead SessionStatus = "dead" SessionKilled SessionStatus = "killed" ) // TaskStatus 与 c2_tasks.status 一致 type TaskStatus string const ( TaskQueued TaskStatus = "queued" TaskSent TaskStatus = "sent" TaskRunning TaskStatus = "running" TaskSuccess TaskStatus = "success" TaskFailed TaskStatus = "failed" TaskCancelled TaskStatus = "cancelled" ) // TaskType 任务类型(与 beacon 端协商,避免硬编码字符串) type TaskType string const ( // 通用任务 TaskTypeExec TaskType = "exec" // 执行任意命令(shell -c) TaskTypeShell TaskType = "shell" // 交互式命令(保持 cwd) TaskTypePwd TaskType = "pwd" // 当前目录 TaskTypeCd TaskType = "cd" // 切目录 TaskTypeLs TaskType = "ls" // 列目录 TaskTypePs TaskType = "ps" // 列进程 TaskTypeKillProc TaskType = "kill_proc" // 杀进程 TaskTypeUpload TaskType = "upload" // 推文件到目标 TaskTypeDownload TaskType = "download" // 拉文件回本机 TaskTypeScreenshot TaskType = "screenshot" // 截图 TaskTypeSleep TaskType = "sleep" // 调整心跳节律 TaskTypeExit TaskType = "exit" // 让 implant 退出(不会自删二进制) TaskTypeSelfDelete TaskType = "self_delete" // 退出 + 自删二进制(持久化清理) // 高级任务 TaskTypePortFwd TaskType = "port_fwd" TaskTypeSocksStart TaskType = "socks_start" TaskTypeSocksStop TaskType = "socks_stop" TaskTypeLoadAssembly TaskType = "load_assembly" TaskTypePersist TaskType = "persist" ) // AllTaskTypes 全部 task_type,便于工具 schema 列出 enum func AllTaskTypes() []TaskType { return []TaskType{ TaskTypeExec, TaskTypeShell, TaskTypePwd, TaskTypeCd, TaskTypeLs, TaskTypePs, TaskTypeKillProc, TaskTypeUpload, TaskTypeDownload, TaskTypeScreenshot, TaskTypeSleep, TaskTypeExit, TaskTypeSelfDelete, TaskTypePortFwd, TaskTypeSocksStart, TaskTypeSocksStop, TaskTypeLoadAssembly, TaskTypePersist, } } // IsDangerousTaskType 标记需要 HITL 二次确认的任务类型; // 与 internal/handler/hitl.go 现有的 tool_whitelist 概念呼应:白名单外 → 走审批。 func IsDangerousTaskType(t TaskType) bool { switch t { case TaskTypeKillProc, TaskTypeUpload, TaskTypeSelfDelete, TaskTypePortFwd, TaskTypeSocksStart, TaskTypeLoadAssembly, TaskTypePersist: return true } return false } // ListenerConfig 解码后的监听器运行配置(来自 c2_listeners.config_json) type ListenerConfig struct { // HTTP/HTTPS Beacon 公共字段 BeaconCheckInPath string `json:"beacon_check_in_path,omitempty"` // 默认 "/check_in" BeaconTasksPath string `json:"beacon_tasks_path,omitempty"` // 默认 "/tasks" BeaconResultPath string `json:"beacon_result_path,omitempty"` // 默认 "/result" BeaconUploadPath string `json:"beacon_upload_path,omitempty"` // 默认 "/upload" BeaconFilePath string `json:"beacon_file_path,omitempty"` // 默认 "/file/" // HTTPS 专属 TLSCertPath string `json:"tls_cert_path,omitempty"` TLSKeyPath string `json:"tls_key_path,omitempty"` TLSAutoSelfSign bool `json:"tls_auto_self_sign,omitempty"` // true:找不到证书时自动生成自签 // 客户端默认参数(写到 c2_sessions 初值,beacon 也可在 check-in 时覆写) DefaultSleep int `json:"default_sleep,omitempty"` // 秒,默认 5 DefaultJitter int `json:"default_jitter,omitempty"` // 0-100,默认 0 // OPSEC:可选命令黑名单(正则) CommandDenyRegex []string `json:"command_deny_regex,omitempty"` // 任务并发上限(每个会话同时下发的最大任务数,0 表示不限制) MaxConcurrentTasks int `json:"max_concurrent_tasks,omitempty"` // CallbackHost 植入端/Payload 使用的回连主机名(可选);与 bind_host 分离,便于 NAT/ECS 等场景 CallbackHost string `json:"callback_host,omitempty"` } // ApplyDefaults 对未填字段填默认值;调用方负责持久化时序列化新值 func (c *ListenerConfig) ApplyDefaults() { if strings.TrimSpace(c.BeaconCheckInPath) == "" { c.BeaconCheckInPath = "/check_in" } if strings.TrimSpace(c.BeaconTasksPath) == "" { c.BeaconTasksPath = "/tasks" } if strings.TrimSpace(c.BeaconResultPath) == "" { c.BeaconResultPath = "/result" } if strings.TrimSpace(c.BeaconUploadPath) == "" { c.BeaconUploadPath = "/upload" } if strings.TrimSpace(c.BeaconFilePath) == "" { c.BeaconFilePath = "/file/" } if c.DefaultSleep <= 0 { c.DefaultSleep = 5 } if c.DefaultJitter < 0 { c.DefaultJitter = 0 } if c.DefaultJitter > 100 { c.DefaultJitter = 100 } } // ImplantCheckInRequest beacon → 服务端的注册/心跳请求体(已解密后的明文) type ImplantCheckInRequest struct { ImplantUUID string `json:"uuid"` Hostname string `json:"hostname"` Username string `json:"username"` OS string `json:"os"` Arch string `json:"arch"` PID int `json:"pid"` ProcessName string `json:"process_name"` IsAdmin bool `json:"is_admin"` InternalIP string `json:"internal_ip"` UserAgent string `json:"user_agent,omitempty"` SleepSeconds int `json:"sleep_seconds"` JitterPercent int `json:"jitter_percent"` Metadata map[string]interface{} `json:"metadata,omitempty"` } // ImplantCheckInResponse 服务端回执 type ImplantCheckInResponse struct { SessionID string `json:"session_id"` NextSleep int `json:"next_sleep"` NextJitter int `json:"next_jitter"` HasTasks bool `json:"has_tasks"` ServerTime int64 `json:"server_time"` } // TaskEnvelope 服务端 → beacon 的任务派发载体 type TaskEnvelope struct { TaskID string `json:"task_id"` TaskType string `json:"task_type"` Payload map[string]interface{} `json:"payload"` } // TaskResultReport beacon → 服务端的任务结果回传 type TaskResultReport struct { TaskID string `json:"task_id"` Success bool `json:"success"` Output string `json:"output,omitempty"` Error string `json:"error,omitempty"` BlobBase64 string `json:"blob_b64,omitempty"` // 如截图二进制 BlobSuffix string `json:"blob_suffix,omitempty"` // 如 ".png" StartedAt int64 `json:"started_at"` EndedAt int64 `json:"ended_at"` } // CommonError C2 模块统一错误类型,便于 handler 层映射 HTTP 状态码 type CommonError struct { Code string Message string HTTP int } func (e *CommonError) Error() string { if e == nil { return "" } return e.Message } // Sentinel errors,便于 errors.Is 比较 var ( ErrListenerNotFound = &CommonError{Code: "listener_not_found", Message: "监听器不存在", HTTP: 404} ErrSessionNotFound = &CommonError{Code: "session_not_found", Message: "会话不存在", HTTP: 404} ErrTaskNotFound = &CommonError{Code: "task_not_found", Message: "任务不存在", HTTP: 404} ErrProfileNotFound = &CommonError{Code: "profile_not_found", Message: "Profile 不存在", HTTP: 404} ErrInvalidInput = &CommonError{Code: "invalid_input", Message: "参数非法", HTTP: 400} ErrAuthFailed = &CommonError{Code: "auth_failed", Message: "鉴权失败", HTTP: 401} ErrPortInUse = &CommonError{Code: "port_in_use", Message: "端口已被占用", HTTP: 409} ErrListenerRunning = &CommonError{Code: "listener_running", Message: "监听器已在运行", HTTP: 409} ErrListenerStopped = &CommonError{Code: "listener_stopped", Message: "监听器未运行", HTTP: 409} ErrUnsupportedType = &CommonError{Code: "unsupported_type", Message: "不支持的监听器类型", HTTP: 400} ) // SafeBindPort 校验端口范围 func SafeBindPort(port int) error { if port < 1 || port > 65535 { return errors.New("port must be in 1..65535") } return nil } // NowUnixMillis 统一时间戳工具 func NowUnixMillis() int64 { return time.Now().UnixNano() / int64(time.Millisecond) }