文章总结: 本文详细分析了AdaptixC2Teamserver服务端的完整启动流程,该C2平台采用Go语言开发,基于Gin框架提供HTTPS服务,使用SQLite进行数据持久化,并通过GoPlugin机制实现动态插件扩展。启动过程包括解析命令行参数、初始化日志系统、加载配置文件、设置JWT认证、动态加载Listener/Agent插件,最后启动网络服务并恢复数据。文档特别强调了生产环境建议使用-profile参数配置,并提供了完整的路由注册和中间件实现细节。 综合评分: 85 文章分类: 红队,内网渗透,安全工具,恶意软件,安全开发
AdaptixC2 Teamserver 服务端启动流程分析
0xNaNa 0xNaNa
0x33 SEC
2026年4月8日 08:30 贵州
AdaptixC2 Teamserver 服务端启动流程分析
概述
TeamServer 使用 Go 语言编写,基于 Gin 框架提供 HTTPS 服务,以 SQLite 作为本地持久化存储,并通过 Go Plugin 机制实现运行时插件扩展。
本文从 main 函数入手,逐步拆解 Teamserver 的完整启动流程。
技术栈
| 组件 | 技术 | 说明 |
| — | — | — |
| Web 框架 | Gin | 高性能 HTTP 路由框架 |
| 编程语言 | Go | 服务端核心语言 |
| 数据库 | SQLite | 轻量级本地持久化 |
| 身份认证 | JWT | 访问令牌 + 刷新令牌机制 |
| 插件系统 | Go Plugin | 运行时动态加载 .so 共享库 |
启动流程总览
main()
├── 1. 打印 Banner & 解析命令行参数
├── 2. 初始化日志系统
├── 3. 创建 Teamserver 实例 & 加载配置
├── 4. 初始化 JWT 配置
├── 5. 加载插件(Listener / Agent)
└── 6. 启动服务
├── 枚举网络接口
├── 初始化 HTTP 路由(Gin)
├── 启动 HTTPS 服务(goroutine)
├── 恢复数据库数据
├── 启动 Agent 心跳更新(goroutine)
└── 阻塞等待退出信号
详细流程分析
1. 程序入口:解析启动参数
main.go 中的 main 函数是程序的入口点。启动时首先打印 Banner 及版本信息,随后解析命令行参数获取配置。
支持的命令行参数包括:
- IP、端口:服务监听地址
- 登录 URI:自定义接入端点路径
- 密码:操作员认证凭据
- SSL 证书:TLS 加密所需的证书与密钥
- profile:JSON 格式配置文件路径(推荐使用,更简洁)
建议生产部署时使用
-profile参数指定配置文件,而非逐一传递命令行参数。
程序入口参数解析
2. 初始化日志系统
使用 logs.NewPrintLogger 初始化日志记录器,支持设置日志级别(如开启 Debug 模式)。
日志初始化
3. 创建实例与加载配置
此阶段完成以下操作:
- 创建
Teamserver实例,同时初始化 SQLite 数据库 - 加载配置:
- 若指定了
profile参数,调用SetProfile方法从 JSON 文件加载 - 否则从命令行参数逐项读取配置
- 调用
IsValid方法校验配置合法性,避免携带非法参数启动
创建实例与加载配置
4. 初始化 JWT 配置
AdaptixC2 使用 JWT 进行操作员身份认证,包含两类令牌:
-
accessTokenHours:访问令牌有效期(小时) -
refreshTokenHours:刷新令牌有效期(小时)
JWT 配置初始化
5. 加载插件(Listener / Agent)
Go Plugin 机制简介
Go 的 Plugin 机制支持将 Go 代码编译为 .so 动态共享库,程序运行时按需加载并调用其中的函数或变量,实现运行时可插拔扩展。
参考资料:Go 语言的动态库和插件系统
编译插件为 .so 文件:
注意:导出函数名的首字母必须大写。
CGO_ENABLED=1 go build -buildmode=plugin -o hello.so plugin.go
插件源码示例:
package main
import "fmt"
func SayHello(name string) {
fmt.Println(name)
}
主程序加载插件:
package main
import (
"plugin"
)
func main() {
plug, err := plugin.Open("plugin.so") // 加载 .so 文件
if err != nil {
panic(err)
}
sym, err := plug.Lookup("SayHello") // 查找导出函数
if err != nil {
panic(err)
}
f, ok := sym.(func(string)) // 类型断言
if !ok {
panic("unexpected type for SayHello")
}
f("AdaptixC2") // 调用函数
}
基于 Plugin 机制,AdaptixC2 的 Agent 和 Listener 均以插件形式实现,无需修改主程序即可动态扩展,这也是官方着重强调其可扩展性的原因。
Go Plugin 插件加载示意
插件加载流程
调用入口:
ts.Extender.LoadPlugins(ts.Profile.Server.Extenders)
遍历配置文件中声明的所有插件路径,逐一执行:
- 检查插件文件是否存在
- 尝试解析(
plugin.Open),失败则跳过并记录错误 - 根据插件类型分别注册为 Listener 插件或 Agent 插件
6. 启动 Teamserver
所有配置与插件加载完成后,调用:
ts.Start()
6.1 枚举网络接口
遍历系统全部网络接口,提取 IPv4 地址,写入 ts.Parameters.Interfaces 供后续绑定使用:
interfaces, err := net.Interfaces()
if err == nil {
ts.Parameters.Interfaces = append(ts.Parameters.Interfaces, "0.0.0.0")
for _, i := range interfaces {
iAddrs, err := i.Addrs()
if err == nil {
for _, addr := range iAddrs {
ipNet, ok := addr.(*net.IPNet)
if ok {
if ipNet.IP.To4() != nil {
ts.Parameters.Interfaces = append(ts.Parameters.Interfaces, ipNet.IP.String())
}
}
}
}
}
}
6.2 初始化 HTTP 路由
调用 connector.NewTsConnector 创建 Gin 实例并完成路由注册:
ts.AdaptixServer, err = connector.NewTsConnector(ts, *ts.Profile.Server, *ts.Profile.ServerResponse)
伪造默认响应页面:
为防止被网络测绘引擎(如 Shodan、FOFA)识别,服务器默认会返回伪造的错误页面(如模拟 Tomcat 报错、CloudFlare 错误页等)。
推荐项目(伪造 CloudFlare 错误页):cloudflare-error-page
NewTsConnector 完整实现:
func NewTsConnector(ts Teamserver, tsProfile profile.TsProfile, tsResponse profile.TsResponse) (*TsConnector, error) {
gin.SetMode(gin.ReleaseMode)
if tsResponse.PagePath != "" {
fileContent, _ := os.ReadFile(tsResponse.PagePath)
tsResponse.PageContent = string(fileContent)
}
var connector = new(TsConnector)
connector.Engine = gin.New()
connector.Engine.Use(gin.Recovery()) // 防止单请求崩溃导致服务中断
connector.teamserver = ts
connector.Interface = tsProfile.Interface
connector.Port = tsProfile.Port
connector.Endpoint = tsProfile.Endpoint
connector.Hash = krypt.SHA256([]byte(tsProfile.Password))
connector.OnlyHash = tsProfile.OnlyPassword
connector.Operators = make(map[string]string, len(tsProfile.Operators))
for username, password := range tsProfile.Operators {
connector.Operators[username] = krypt.SHA256([]byte(password))
}
connector.Key = tsProfile.Key
connector.Cert = tsProfile.Cert
// 登录相关路由(无需认证)
login_group := connector.Engine.Group(tsProfile.Endpoint)
login_group.Use(limitTimeoutMiddleware(), default404Middleware(tsResponse))
{
login_group.POST("/login", connector.tcLogin)
login_group.POST("/refresh", token.RefreshTokenHandler)
}
// OTP 相关路由(轻量级认证)
otp_group := connector.Engine.Group(tsProfile.Endpoint)
otp_group.Use(ts.ValidateOTP(), default404Middleware(tsResponse))
{
otp_group.POST("/otp/upload/temp", connector.tcOTP_UploadTemp)
otp_group.GET("/otp/download/sync", connector.tcOTP_DownloadSync)
}
// API 路由(需要有效 JWT Access Token)
api_group := connector.Engine.Group(tsProfile.Endpoint)
api_group.Use(limitTimeoutMiddleware(), token.ValidateAccessToken(), default404Middleware(tsResponse))
{
api_group.POST("/sync", connector.tcSync)
api_group.GET("/connect", connector.tcConnect)
api_group.GET("/channel", connector.tcChannel)
api_group.POST("/otp/generate", connector.tcOTP_Generate)
// ... 其余业务路由
}
// 兜底 404 处理
connector.Engine.NoRoute(limitTimeoutMiddleware(), default404Middleware(tsResponse), func(c *gin.Context) {
_ = c.Error(errors.New("NoRoute"))
})
return connector, nil
}
身份验证说明:
- 密码以 SHA256 哈希形式存储,不明文传输
OnlyPassword为false时,启用操作员用户名强制校验- API 路由组通过
token.ValidateAccessToken()中间件强制验证 JWT
路由注册与中间件配置
6.3 正式启动服务
go ts.AdaptixServer.Start(&stopped)
logs.Success("", "Starting server -> https://%s:%v%s", ts.Profile.Server.Interface, ts.Profile.Server.Port, ts.Profile.Server.Endpoint)
ts.RestoreData()
logs.Success("", "The AdaptixC2 server is ready")
go ts.TsAgentTickUpdate()
<-stopped
logs.Warn("", "Teamserver finished")
os.Exit(0)
各步骤说明:
启动 HTTPS 服务(goroutine):
err := server.ListenAndServeTLS(tc.Cert, tc.Key)
if err != nil {
logs.Error("", "Failed to start HTTP Server: "+err.Error())
return
}
恢复持久化数据:
ts.RestoreData()
从 SQLite 数据库中恢复历史会话、Agent 信息等数据,保证服务重启后状态延续。
启动 Agent 心跳更新(goroutine):
go ts.TsAgentTickUpdate()
周期性检查各 Agent 的在线状态,维护心跳超时判断逻辑。
阻塞等待退出信号:
<-stopped
logs.Warn("", "Teamserver finished")
os.Exit(0)
通过 channel 阻塞主 goroutine,当服务异常或收到退出信号时,安全退出进程。
总结
AdaptixC2 的 Teamserver 启动流程设计清晰,层次分明:
- 参数解析 → 支持 CLI 和 JSON profile 两种配置方式
- 日志 & 配置校验 → 早期发现配置错误,快速失败
- JWT 认证体系 → 双令牌机制,兼顾安全性与可用性
- Plugin 插件系统 → 运行时动态加载,无需重编译主程序即可扩展 Agent/Listener
- Gin 路由分组 → 按认证级别划分路由,中间件职责清晰
- goroutine 并发 → HTTPS 服务与 Agent 心跳各自独立运行,主线程通过 channel 阻塞保活
整体架构体现了 Go 语言在系统工具开发中的典型实践:轻量、并发、可扩展。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:0x33 SEC 0xNaNa 0xNaNa《AdaptixC2 Teamserver 服务端启动流程分析》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。







![暗网泄露:云端在线视频制作工具[500万用户]](/images/random/titlepic/6.jpg)


评论