ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Havoc Demon Agent 源码结构深度解析:C2 植入体的模块化设计与实现

Havoc Demon Agent 源码结构深度解析:C2 植入体的模块化设计与实现 网络安全【免费下载链接】HavocThe Havoc Framework项目地址https://gitcode.com/gh_mirrors/ha/Havoc点击查看免费下载Demon 是 Havoc 框架Havoc Framework中的 Windows 端植入体Agent其源码完全使用 C 语言与汇编编写位于仓库的 payloads/Demon 目录。本文以该目录下的 README.md 为核心骨架结合源码逐目录拆解 Demon 的设计从汇编层的返回地址栈欺骗Return Address Stack Spoofing到核心层的动态 API 解析与系统调用Syscall封装再到加密、注入与三种 PE 入口点的实现并澄清构建系统的正确使用方式。读完本文你将能够按图索骥地理解 Havoc 客户端载荷的完整代码组织掌握每个源文件在 Agent 生命周期中所承担的角色并知道如何配合 teamserver 构建器 将源码编译为可用的载荷。一、总体概览一个自给自足的 Windows Agentpayloads/Demon/README.md 开宗明义Demon Agent 的源码由 C 与汇编构成其核心职责是与 TeamserverC2 服务端建立连接、接收并执行任务。从 src/Demon.c 可以看出Agent 的启动流程被设计为四步初始化指针、模块与 Win32 APIDemonInit初始化元数据DemonMetaData解析内嵌配置DemonConfig进入主连接与任务循环DemonRoutine。整个源码按功能划分为五个目录README 中给出了它们各自的职责目录职责src/asm汇编代码返回地址栈欺骗src/core核心功能连接服务端、动态加载 Win32 API / 系统调用src/crypt加解密函数src/inject注入函数与工具src/mainPE 可执行文件的入口点此外include 目录集中存放全部头文件其中 Demon.h 定义了贯穿整个 Agent 的全局实例结构体INSTANCE——它集中管理会话信息Session、配置Config、动态解析的函数指针表Win32、系统调用表Syscall、已加载模块基址Modules以及各类链表令牌、作业、下载、Socket、Pivot、COFF 等。理解 Demon 的代码组织本质上是理解这个INSTANCE结构体被各模块如何读写。二、src/asm汇编层与返回地址栈欺骗README 明确指出 src/asm 存放的是return address stack spoofing返回地址栈欺骗汇编代码。目录内按架构拆分为四个文件Spoof.x64.asm / Spoof.x86.asm负责在调用敏感函数时伪造栈上的返回地址使调用链溯源例如 ETW、EDR 的栈回溯难以还原真实的函数调用来源Syscall.x64.asm / Syscall.x86.asm提供syscall指令的直通与间接调用桩。这两个主题在核心层均有对应支撑Demon.h的Config.Implant中有StackSpoof布尔开关而Syscall结构体保存了间接系统调用所需的SysAddresssyscall指令地址与各Nt*函数的 Service NumberSSN。构建时汇编对象会由 NASM 先编译成.o再与 C 源码一起链接进最终载荷见下文构建章节。三、src/coreAgent 的心脏——连接、API 解析与主循环src/core 是源码体量最大的目录README 将其职责概括为连接服务端、动态加载 Win32 API / 系统调用。从 Demon.c 与 CMakeLists.txt 的源文件清单看核心层覆盖了二十余个 C 文件本节按运行顺序拆解其关键实现。3.1 DemonMain 与主循环DemonRoutinesrc/Demon.c 定义了 Agent 的调度骨架。DemonMain在栈上分配INSTANCE后依次调用DemonInit、DemonMetaData、DemonRoutine。其中DemonRoutine是一个永不返回的循环_Noreturn VOID DemonRoutine() { for ( ;; ) { if ( ! Instance-Session.Connected ) { if ( TransportInit() ) { ... } /* 连接监听器 */ } if ( Instance-Session.Connected ) { CommandDispatcher(); /* 任务队列派发 */ } SleepObf(); /* 睡眠按配置加密内存 */ } }这个循环揭示了 Agent 的核心行为模式未连接则尝试通过TransportInit建立通道已连接则进入任务派发每次循环末尾都执行SleepObf睡眠混淆见 core/SleepObf.h。TransportInit的语义在 core/Transport.h 中定义为建立到 C2 服务器的 HTTP/HTTPS 连接或到父级 Pivot 的 SMB 连接并发送收集到的主机信息。3.2 动态加载 Win32 API 与系统调用DemonInit是整个 Agent 的地基阶段其核心工作是不依赖导入表地解析所需函数通过 PEB进程环境块定位ntdll.dll、kernel32.dll等模块基址LdrModulePeb再用LdrFunctionAddr按哈希查找函数地址哈希由 scripts/hash_func.py 生成填充Instance-Win32中数百个函数指针。这一点在Demon.h的函数指针表中体现得淋漓尽致从NtAllocateVirtualMemory、NtProtectVirtualMemory等原生 API到WinHttpOpen、CreateProcessW、NetUserEnum、SafeArrayCreate、LsaCallAuthenticationPackage等跨模块 API全部以WIN_FUNC宏声明为结构体成员运行时逐一解析。系统调用侧DemonInit在解析完基础 API 后检查Config.Implant.SysIndirect若开启间接系统调用则调用SysInitialize从 ntdll 中提取每个所需Nt*函数的syscall指令地址与 SSN填充Instance-Syscall对应 core/SysNative.c 与 core/Syscalls.c。3.3 内嵌配置解析DemonConfigAgent 的运行时配置睡眠时间、抖动、注入方式、C2 地址等并不是运行时从外部读取而是在构建期由 Teamserver 序列化后以内嵌字节数组的形式编译进载荷源码中的AgentConfig[]由宏CONFIG_BYTES填充默认值见 CMakeLists.txt 的add_compile_definitions( CONFIG_BYTES{} )。DemonConfig使用 core/Parser.c 提供的解析器按固定顺序读取这些字节依次还原出Sleeping/Jitter睡眠秒数与抖动百分比内存分配 / 执行技术Memory.Alloc/Memory.ExecuteSpawn64/Spawn86注入用派生进程路径如 notepad.exe植入体选项SleepMaskTechnique睡眠混淆技术、SleepJmpBypass、StackSpoof栈欺骗、ProxyLoading模块代理加载、SysIndirect间接系统调用、AmsiEtwPatchAMSI/ETW 补丁传输层选项TRANSPORT_HTTP编译开关下KillDate终止日期若当前时间已超过则直接退出线程、WorkingHours工作时间窗口、HTTPMethod、HostRotation主机轮换策略、主机列表、SecureSSL、UserAgent、HTTPHeaders、Uris以及可选的Proxy代理URL / 用户名 / 密码TRANSPORT_SMB编译开关下管道名Name与KillDate、WorkingHours。值得注意的默认值HTTP 传输下下载分块大小DownloadChunkSize为0x80000512 KBSMB 传输下为0xfc00约 63 KB源码注释说明需小于PIPE_BUFFER_MAX即 Transport.h 中定义的0x10000。3.4 元数据上报DemonMetaData连接建立后Agent 需要向 Teamserver 上报主机信息。src/Demon.c 的DemonMetaData先通过PackageCreateWithMetaData( DEMON_INITIALIZE )创建数据包随后生成 32 字节 AES Key 与 16 字节 IV通过RandomNumber32并作为包首部字段发送——这构成了后续通信的会话密钥依次写入Agent ID、计算机名、用户名、域名、内网 IP、进程路径、PID/TID/PPID、进程架构、是否管理员BeaconIsAdmin、模块基址、操作系统版本信息RtlGetVersion的 Major/Minor、产品类型、SP、Build、OS 架构、睡眠与抖动、KillDate、WorkingHours。源码注释给出了该包的完整内存布局Header MetaData字段长度与顺序与 Teamserver 侧的 parser 严格对应。四、src/cryptAES-256 通信加密README 将 src/crypt 概括为加密/解密函数。该目录的核心是 AesCrypt.c一个自实现的 AES 纯 C 实现头文件 AesCrypt.h 定义AES_BLOCKLEN 16、AES_KEYLEN 32即 AES-256并默认启用CTR计数器模式与AES256宏密钥长度为 8 个 32 位字Nk 8轮数为 14Nr 14与 AES-256 规范一致对外仅暴露两个接口AesInit初始化轮密钥与 IV与AesXCryptBufferCTR 模式下的流式加解密加密与解密共用同一函数。这一实现与通信流程的对应关系是DemonMetaData中随机生成的 32 字节 Key 16 字节 IV 在 Agent 侧保存于Config.AES后续 TransportSend 发送的所有数据均先经AesXCryptBuffer加密Teamserver 侧则通过 aes.go 做对称解密从而保证 C2 信道的机密性。五、src/inject注入与派生进程src/inject 对应 README 所述injection functions and utilities。头文件 inject/Inject.h 定义了注入技术枚举INJECTION_TECHNIQUE_WIN321传统 Win32 API 注入INJECTION_TECHNIQUE_SYSCALL2系统调用注入且为默认值INJECTION_TECHNIQUE_DEFAULTINJECTION_TECHNIQUE_APC3APC 注入。同时定义了派生Spawn技术的默认值为系统调用方式SPAWN_TECHNIQUE_SYSCALL并封装了统一的Inject入口区分三种操作方式INJECT_WAY_SPAWN派生进程执行、INJECT_WAY_INJECT注入现有进程、INJECT_WAY_EXECUTE。注入相关的错误码如INJECT_ERROR_PROCESS_ARCH_MISMATCH也在此定义用于在注入 32/64 位进程架构不匹配时给出明确反馈。实现细节分布在 Inject.c 与 InjectUtil.c 中。六、src/main三种 PE 入口点README 明确指出 src/main 是PE 可执行文件的入口点并给出三个文件对应的产物类型。三者最终都汇聚到DemonMain但启动方式截然不同。6.1 MainExe.c —— Windows EXEMainExe.c 是最直接的入口WinMain收到参数后仅打印调试信息并直接调用DemonMain( NULL, NULL )随后返回 0。它是独立 EXE 形态的入口由 Teamserver 以-e WinMainx64或-e _WinMainx86链接。6.2 MainSvc.c —— Windows Service EXEMainSvc.c 实现标准 Windows 服务框架全局维护SERVICE_STATUS接受 STOP 与 SHUTDOWN 控制码WinMain构建SERVICE_TABLE_ENTRY服务名来自SERVICE_NAME编译宏默认DemonService并调用StartServiceCtrlDispatcherA注册分发表服务管理器回调SvcMain后先RegisterServiceCtrlHandlerA注册控制处理器再调用DemonMain启动 Agent控制处理器SrvCtrlHandler在收到SERVICE_CONTROL_STOP或SERVICE_CONTROL_SHUTDOWN时更新状态为SERVICE_STOPPED并上报SetServiceStatus。服务形态的好处是无需交互登录即可随系统自启且在任务管理器等常规工具下表现为系统服务。6.3 MainDll.c —— DLL 与 ShellcodeMainDll.c 的处理最为精细因为它同时服务 DLL 与 Shellcode 两种形态通过SHELLCODE编译宏区分非SHELLCODE模式普通 DLL导出Start函数注释注明为rundll32等加载器预留TODO 计划将函数名改为可配置内部用 PEB 解析Sleep后进入死循环以防止进程退出DllMain在DLL_PROCESS_ATTACH时新建线程执行DemonMain源码注释解释了原因在DllMain内直接发起 HTTP 请求会因 WinHTTP 的限制触发ERROR_INVALID_STATE因此必须在线程中执行DEBUG模式下还会AllocConsole以便输出调试打印SHELLCODE模式跳过Start导出DllMain直接调用DemonMain( hDllBase, Reserved )因为 Shellcode 加载器已经接管了线程上下文无需再开新线程。DLL 形态可由rundll32或进程侧加载执行Shellcode 形态则由 DllLdr 与 Shellcode 加载器配合最终把 DLL 载荷封装为位置无关的原始字节流。七、构建系统CMakeLists 的真实用途README 专门用一整节对 CMakeLists.txt 做出重要澄清Do not modify it or use it. This is only for developing and editing the Demon source code in CLion……It is only there to make Clion happy.即该 CMake 文件仅供开发者在 CLion 等支持 CMake 的 IDE 中阅读与编辑源码时使用用于提供代码引用与索引并非官方构建入口读者不应以它作为编译载荷的手段。从内容看它也确实是一个示例级配置指定x86_64-w64-mingw32-gcc交叉编译器、C_STANDARD 11、CONFIG_BYTES{}空配置与默认SERVICE_NAMEDemonService并同时启用TRANSPORT_HTTP、TRANSPORT_SMB、AES256三个宏真实构建中这些开关由 Teamserver 按监听器类型注入。真实的生产构建链路在 Teamserver 侧。构建器 builder.go 展示了完整流程将用户界面配置睡眠、抖动、注入技术、代理加载、AMSI/ETW 补丁、监听器信息等通过PatchConfig序列化为字节流生成CONFIG_BYTES{0x..,0x..,...}编译宏注入到-D参数按目标架构ARCHITECTURE_X64/ARCHITECTURE_X86选择 x64/x86 mingw 编译器与 NASM将 src/asm 的汇编按架构过滤编译为.o后与全部 C 源文件含 src/Demon.c一起编译按产物类型选择入口EXE 用MainExe.c、服务 EXE 用MainSvc.c额外定义SVC_EXE并链接ntdll、DLL 用MainDll.c-shared -e DllMainRAWShellcode产物则先编译带SHELLCODE宏的 DLL再与前置于 payloads/Shellcode.x64.bin / payloads/Shellcode.x86.bin 的加载器模板拼接。构建时还依据配置文件如 profiles/havoc.yaotl 中的Teamserver.Build段指定Compiler64、Compiler86、Nasm路径进行字符串替换与 MZ 头部魔数修补。注意 profiles/havoc.yaotl 中的Demon段Sleep、Jitter、Injection.Spawn64/Spawn32即对应DemonConfig解析出的字段两个文件共同决定了最终载荷的行为参数。八、小结从源码结构理解 Demon 的设计取向综合五个源码目录与三种入口点可以归纳出 Demon Agent 的几个设计主线规避优先汇编层做返回地址栈欺骗核心层用 PEB 动态解析替代导入表、可选间接系统调用SleepObf在睡眠期加密内存构建期提供 Ekko / Foliage / Zilean 等睡眠混淆技术与jmp rax/jmp rbx跳板选项见 builder.go 的常量定义配置内嵌运行时行为全部由CONFIG_BYTES编译期注入避免落盘配置文件传输可插拔通过TRANSPORT_HTTP/TRANSPORT_SMB编译宏在 Transport.c、TransportHttp.c、TransportSmb.c 之间切换SMB 传输同时承担父/子 Pivot 的通信形态多样同一份核心代码通过 src/main 的三个入口适配 EXE、服务、DLL/Shellcode 三种投递场景。对于希望深入研究的读者建议按以下路径阅读源码先通读 Demon.c 把握生命周期再对照 Demon.h 的INSTANCE结构体理解各模块的数据契约随后分别进入 src/core、src/crypt 与 src/inject 验证具体实现最后回到 builder.go 理解编译期参数如何落到运行时的DemonConfig。这一条阅读路径覆盖了 Agent 从构建到上线再到任务执行的完整闭环。赞分享网络安全【免费下载链接】HavocThe Havoc Framework项目地址https://gitcode.com/gh_mirrors/ha/Havoc点击查看免费下载相关推荐HelloAgents Code Agent CLI 项目结构深度解析模块化智能体框架的架构设计与源码实现HelloAgents Code Agent CLI 项目结构深度解析模块化智能体框架的架构设计与源码实现 本文以 YYHDBL HelloCodeAgent教程文档AI Agent人工智能大模型当游戏逻辑多到卡帧bitECS 用三种数据布局思路让你的 TypeScript 项目跑出 C 语言手感当游戏逻辑多到卡帧bitECS 用三种数据布局思路让你的 TypeScript 项目跑出 C 语言手感 你有没有过这样的体验一个网页游戏刚开始只有几十个对象SBOM工具API深度使用C集成与自定义扩展开发指南SBOM工具API深度使用C 集成与自定义扩展开发指南 SBOM工具Software Bill of Materials是一款高度可扩展的企业级工具用于供应链安全SBOMCLI开发工具上一篇wger数据备份策略结合全量、增量与差异备份的方案下一篇小米笔记本Hackintosh无线网卡终极解决方案Intel Wi-Fi驱动 vs 更换模块创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表