Havoc C2框架 HTTP流量分析
Havoc C2是一款基于加密通信的多功能C&C框架,使用Golang和C实现。由三部分组成:Havoc_Teamserver(服务端)、Havoc_Client(客户端)、Havoc_Demon(被控端)。
一、 源代码分析
Havoc中C&C的实现:客户端生成payload,在受害主机中下载并运行payload,二者通过http进行交互。
A. 被控端payload基于C实现
目录:Havoc/payload/Demon/Source/
Demon.c:
- DemonMetaData(): 初始化 connect请求的元数据 Instance.MetaData
- DemonRoutine():循环监测 Instance.Session.Connected参数,为True则调用CommandDispatcher(),否则调用TransportInit()连接服务端监听器
Transport.c:TransportInit():用 PackageTransmit(Instance.MetaData) 函数发送连接请求,控制 Instance.Session.Connected参数
Package.c:PackageTransmit() 对数据包进行AES加密并发送
Command.c:CommandDispatcher() 对数据包解密解析指令并作出相应反应
B. 服务端基于GO实现
目录:Havoc/teamserver/pkg
服务端接收数据:(未加密数据:AgentID、Command)
handlers/handlers.go: handleDemonAgent() 解析请求头,4种情况:
1、未注册AgentID 且 Command== agent.DEMON_INIT(0x63),调用agent/agent.go中的ParseDemonRegisterRequest()进行注册
已注册AgentID :
2、Command== agent.DEMON_INIT,判定为reconnect
3、Command== agent.COMMAND_GET_JOB(0x1),为客户端命令的回显,调用agent/demons.go的TaskDispatch() 进行数据解密解析
4、Command!= agent.COMMAND_GET_JOB (0x1)见下
服务端发送数据:在任务队列中选取任务(如没有任务则发送NO_JOB),用agent/agent.go 中BuildPayloadMessage() 将任务队列中的任务命令转换为加密数据发送
二、 agent 注册上线
上线部分逻辑:
受控主机发来的注册请求 如图字段分析如下:
AgentID:6e839708
CommandID: 0x63 ( ==DEMON_INIT)
AESKey: 561e9ce822ccee2c82dc1cc87c2856ecfcd2e00c7cfe349ea02e0296b6d21c02
AESIV:f43802300e8e8242fc709618c6a00e30
之后为加密数据:
用上述密钥解密可得:
可以在服务端输出的日志中看到,解析完 Agent注册请求的数据包后,将数据打印出来,并将AgentID 经过AES加密后发送给受控主机 (AgentID:6e839708)结束注册请求
受控主机收到加密ID,并发送GET_JOB数据包(Command位为 0x1)
三、命令交互流量分析
客户端构造命令发送:
binary.LittleEndian.PutUint32(RequestID, job.RequestID) PayloadPackage=append(PayloadPackage,RequestID...)
binary.LittleEndian.PutUint32(DataCommandID, job.Command)
PayloadPackage =append(PayloadPackage,DataCommandID...)
binary.LittleEndian.PutUint32(PayloadPackageSize, uint32(len(DataPayload)))
PayloadPackage =append(PayloadPackage,PayloadPackagesize...)
logger.Debug("!!!!!DataCommandID:\n",hex.Dump(DataCommandID)) logger.Debug("!!!!!DataPayload:\n",hex.Dump(DataPayload))
if len(DataPayload) > 0 {
DataPayload =crypt.XCryptBytesAES256(DataPayload,AesKey,AesIv)
logger.Debug("!!!!!DataPayload:\n",hex.Dump(DataPayload))
PayloadPackage =append(PayloadPackage,DataPayload...)
DataPayload=nil
}
1、pwd命令
由源码知:
CommandID: 0f (15) == COMMAND_FS
Payload: 09 == DEMON_COMMAND_FS_GET_PWD
所以最后发送的数据为
RequestID:71d062af
CommandID: 0f000000
PayloadPackagesize: 04000000
加密DataPayload: 80e93cc5
2、cat命令
命令:cat a.txt
从受控端接收到的数据包分析:
RequstID: 145c2a98
CommandID: 0f000000
PayloadPackagesize: 14000000
解密 Payload:
0a000000: Subcommand: DEMON_COMMAND_FS_CAT
0c000000: PayloadSize
61002e007400780074: a.txt
受控端回复:
AgentID: 6e839708
对应RequstID 的 ResponseID: 982a5c14
回应的CommandID: 0000000f
加密部分: