Empire C 模块开发指南:YAML 结构与 Empire-Compiler 编译链路解析

发布时间:2026/10/13 6:30:02

Empire C 模块开发指南:YAML 结构与 Empire-Compiler 编译链路解析 渗透测试网络安全应用安全【免费下载链接】EmpireEmpire is a post-exploitation and adversary emulation framework that is used to aid Red Teams and Penetration Testers.项目地址https://gitcode.com/gh_mirrors/empi/Empire点击查看免费下载本指南以 Empire 官方文档 C# Modules 为骨架系统讲解 C# 模块language: csharp的 YAML 定义格式、csharp编译段落的全部字段、以及从模块 YAML 到可执行程序集的编译执行链路。你将掌握如何阅读、编写和调试一个 C# 模块并理解custom_generate高级生成机制与 Empire-Compiler 的底层调用关系可直接用于开发或移植 Rubeus、Seatbelt、SharpSploit 等 C# 工具的 Empire 模块。C# 模块的定位与历史沿革Empire 模块体系中C# 模块是少数不依赖 PowerShell/Python 解释器、直接以 .NET 程序集形式在目标内存中执行的模块类型。官方文档明确指出其历史渊源Empire originally adopted Covenants YAML format for C# modules but has since forked this into Empire-Compiler, which has gradually evolved away from the original Covenant implementation.也就是说Empire 最初采用了 Covenant 的 C# 模块 YAML 格式后来将该实现分叉为独立的Empire-Compiler项目并逐步偏离了 Covenant 原版实现。因此当前仓库中的 C# 模块虽然 YAML 观感上与 Covenant 相似但实际编译工作由 Empire-Compiler 通过 .NET Roslyn 编译器完成。从源码看这一演进在数据模型上也留有痕迹模块模型 EmpireModule 中为 C# 模块单独保留了csharp: CSharpOption | None与compiler_yaml: str | None两个字段其中compiler_yaml正是加载时动态生成、最终交给 Empire-Compiler 的编译描述文件。仓库中现存 C# 模块按攻击阶段分布在 empire/server/modules/csharp 下覆盖 code_execution、credentials、management、persistence、privesc、situational_awareness 六大类典型代表包括csharp_code_execution_assembly/assemblyreflect内存中反射加载 .NET 程序集并调用其 EntryPointcsharp_code_execution_runcoffC# 实现的 COFF 加载器兼容 Cobalt Strike Beacon Object FilesBOFcsharp_credentials_rubeus封装 Rubeus实现 Kerberos 票据枚举与操作csharp_situational_awareness_seatbelt封装 Seatbelt 主机安全审计工具csharp_management_spawn动态生成 Sharpire 可执行程序集并反射执行派生新的 C# agent。模块 YAML 总体结构与各语言通用字段官方文档给出的典型 C# 模块 YAML 结构如下其余字段含义与其它语言模块一致name: ModuleName authors: - name: Author Name handle: AuthorHandle link: https://twitter.com/AuthorHandle description: Module description software: tactics: [TA0002, TA0005] techniques: [T1620] background: false output_extension: needs_admin: false opsec_safe: true language: csharp min_language_version: options: - name: OptionName description: Option description required: true value: Default value strict: false suggested_values: [] csharp: UnsafeCompile: false CompatibleDotNetVersions: - Net35 - Net40 Code: | using System; using System.IO; public static class Program { public static void Main(string[] args) { // Module implementation } } ReferenceSourceLibraries: - Name: LibraryName Description: Library description Location: LibraryPath Language: CSharp CompatibleDotNetVersions: - Net35 - Net40 ReferenceAssemblies: - Name: Assembly.dll Location: net35\Assembly.dll DotNetVersion: Net35 - Name: AnotherAssembly.dll Location: net40\AnotherAssembly.dll DotNetVersion: Net40 EmbeddedResources: [] ReferenceAssemblies: [] EmbeddedResources: []如文档所述除csharp段之外的所有字段与其它模块语言完全一致。这些通用字段在仓库加载逻辑中由 EmpireModule 模型约束加载器ModuleService.load_modules会扫描modules目录下所有*.y*ml文件跳过*template.yaml逐个解析见 module_service.py。通用字段要点字段说明name模块显示名用于 UI 与search检索authors作者信息name/handle/linkdescription模块功能描述多行文本可用 YAML 折叠块\|software若封装已知 ATTCK 软件条目则填其 ID如 Rubeus 对应S1071否则留空tacticsATTCK 战术 ID 列表至少填一个techniquesATTCK 技术/子技术 ID 列表background是否默认以后台任务运行output_extension输出文件扩展名C# 模块通常为空needs_admin/opsec_safe是否需要管理员权限 / 是否 OPSEC 安全language必须为csharpoptions模块可配置项列表MITRE ATTCK 字段的完整规范可参考 Module Development README 中的 “MITRE ATTCK Fields” 一节tactics使用TA0001~TA0043格式techniques使用T####或子技术T####.###格式。csharp段编译设置与代码本体csharp段是 C# 模块区别于其它语言模块的核心源自 Covenant YAML包含实际 C# 代码与编译设置。该段在 module_models.py 中对应CSharpOption模型class CSharpOption(BaseModel): UnsafeCompile: bool False CompatibleDotNetVersions: list[str] [] Code: str ReferenceSourceLibraries: list[dict] | None [] ReferenceAssemblies: list[dict] | None [] EmbeddedResources: list[dict] | None []各字段逐一说明UnsafeCompile是否允许在 C# 代码中使用unsafe块与指针操作。需要直接操作内存如运行时 patchEnvironment.Exit、修改内存页保护属性的模块必须开启。仓库实例Rubeus.yaml 中UnsafeCompile: true其代码通过VirtualQueryEx/VirtualProtectEx与*(byte*)target指针读写完成对Environment.Exit的运行时挂钩Assembly.yaml 中UnsafeCompile: false纯反射调用不需要不安全代码。CompatibleDotNetVersions声明模块代码兼容的 .NET Framework 版本通常为Net35、Net40部分模块在 YAML 中也写作小写net40。该列表有两个关键作用决定编译目标框架加载时由 module_service.py 自动为模块追加一个名为DotNetVersion的选项my_model.options.append( EmpireModuleOption( nameDotNetVersion, valuemy_model.csharp.CompatibleDotNetVersions[0], description.NET version to compile against, requiredTrue, suggested_valuesmy_model.csharp.CompatibleDotNetVersions, strictTrue, ) )也就是说即使你在 YAML 的options中没有显式定义DotNetVersion模块执行时也必然携带它默认值取CompatibleDotNetVersions的第一项可选项为完整列表。执行时该值经params[DotNetVersion].lower()传给编译器见下文编译链路。Code模块本体 C# 源码入口固定为public static void Main(string[] args)。模块选项options中的值会被序列化后作为命令行参数传入args。仓库实例中普遍使用“重定向输出捕获”模式在Main中用StringWriter接管Console.Out/Console.Error执行后把捕获文本统一写回标准输出确保 agent 能拿到模块结果见 Assembly.yaml 与 Rubeus.yaml 的Program类。ReferenceSourceLibraries源代码级引用的第三方 C# 库Source Library列表每个条目包含字段说明Name库名Description库功能描述Location库源码在 Empire-Compiler 源码树中的相对路径Language库语言通常CSharpCompatibleDotNetVersions该库兼容的 .NET 版本ReferenceAssemblies该库内部引用的程序集清单EmbeddedResources随库嵌入的资源列表仓库实例Rubeus 模块将整个Rubeus库作为 Source Library 引用Location: Rubeus\Rubeus.yaml代码中using Rubeus.Asn1;等命名空间均来自该库RunCoff 模块则引用CS_COFFLoader\CoffLoader\RunCoff.yaml。ReferenceAssemblies 与 EmbeddedResourcesReferenceAssemblies编译时引用的预编译 DLL 列表Name/Location/DotNetVersionEmbeddedResources需要嵌入到输出程序集中的资源文件列表。当前仓库中的绝大多数 C# 模块这两个字段均为空如 Assembly.yaml说明主流实现偏好“源码级引用 内嵌代码”的方式而非二进制引用。加载与编译执行链路从 YAML 到可执行程序集理解 C# 模块执行的关键在于Empire 并不会把 YAML 里的代码直接交给 agent而是经历“YAML → compiler_yaml → Empire-Compiler 编译 → 压缩二进制 → agent 内存执行”的完整链路。第一步加载时生成 compiler_yamlModuleService._load_module对language csharp的模块做特殊处理module_service.py以模块路径生成唯一idslug 化将 YAML 中的csharp段取出补充Name、Language、TokenTask字段规范化ReferenceSourceLibraries各子字段用 PyYAML 将上述内容 dump 成compiler_yaml字符串存入模块模型按CompatibleDotNetVersions追加DotNetVersion选项。第二步执行时调用 DotnetCompiler模块执行分派时C# 模块走generate_script_csharpmodule_service.pyscript_file self.dotnet_compiler.compile_task( module.compiler_yaml, module.name, dot_net_versionparams[DotNetVersion].lower(), confuseobfuscate, ) filtered_params {} for key, value in params.items(): if key.lower() not in [agent, dotnetversion] and value and value ! : if key.lower() file: base64_assembly value.get_base64_file() filtered_params[key] base64_assembly else: filtered_params[key] value param_json json.dumps(filtered_params) base64_json base64.b64encode(param_json.encode(utf-8)).decode(utf-8) return ModuleExecutionRequest(command, dataf{script_file}|,{base64_json}, files[script_file])要点Agent与DotNetVersion两个选项被过滤不进入模块参数File类型选项自动转为 base64其余选项序列化为 JSON 再 base64与编译产物路径以|,拼接作为任务数据发送给 agent。第三步DotnetCompiler 与 Empire-Compiler 交互DotnetCompiler.compile_task 是底层实现以EmpireCompiler可执行文件调用子进程参数为--output 临时路径 --dotnet-version 版本 --yaml base64 编码的 compiler_yaml若启用混淆则追加--confuse参数校验返回码与输出中是否包含Final Task Path:标记失败时抛出带 stderr/stdout 诊断信息的ModuleExecutionException成功后把生成的 exe 重命名为任务名_随机6位.exe再用 zlib 压缩去掉 2 字节头与 4 字节尾写入.compiled后缀文件作为任务产物。compile_stagerdotnet.py路径类似但产物不压缩用于 stager/launcher 场景。test_dotnet.py中的参数化测试test_dotnet.py专门验证了编译失败时错误信息必须包含返回码与诊断输出的行为包括被信号杀死rc-9这类边界情况。编译失败与可用性降级C# 编译属于“可选能力”启动时若 Empire-Compiler 获取失败服务器不会崩溃而是记录错误并置compiler_dir Nonedotnet.py直到真正调用编译时才抛出明确错误Empire Compiler is not available. It could not be downloaded at startup (see logs — most often a GitHub API rate-limit). Set GITHUB_TOKEN in the environment or configure empire_compiler.directory to a local build.test_dotnet.py中的test_init_does_not_crash_when_sync_returns_none与test_compile_task_raises_clear_error_when_compiler_unavailabletest_dotnet.py正是对这一降级行为的回归测试。Empire-Compiler 的获取与配置编译器由sync_empire_compilerdata_manager.py管理逻辑为若配置了empire_compiler.directory且目录存在直接使用本地自编译版本否则检查DATA_DIR/empire-compiler下的缓存目录命中则复用无需网络未命中时根据平台linux/osx × x64/arm64见_resolve_compiler_platform从配置的 GitHub Releases API 下载 tar 包并解压首次配置时会根据confuser_proj模板生成混淆项目empire.crproj。配置项定义在 config_manager.pyclass EmpireCompilerConfig(EmpireBaseModel): repo: str ref: str confuser_proj: str # This is only used if you are using a self-compiled # version that is not already tarred and published. directory: str | None None下载逻辑使用 GitHub Releases API/repos/{repo}/releases/tags/{ref}未认证请求受 60 次/小时速率限制约束因此注释与代码都建议在环境中设置GITHUB_TOKEN或GH_TOKEN以使用 Bearer 认证data_manager.py。仓库中的 confuser.crproj 即混淆模板项目的示例其中empire_compiler.confuser_proj指向的正是这类文件。高级生成advanced.custom_generate官方文档指出对于需要访问 Empire 内部逻辑的复杂模块典型如横向移动模块需要动态生成 listener launcher可以编写自定义generate函数并在 YAML 中声明advanced.custom_generate: true。声明与加载机制模块模型 EmpireModuleAdvanced 提供class EmpireModuleAdvanced(BaseModel): option_format_string: str -{{ KEY }} {{ VALUE }} option_format_string_boolean: str -{{ KEY }} custom_generate: bool False custom_generate_path: str | None None generate_class: Any None加载时若advanced.custom_generate为真加载器要求同目录下存在同名.py文件并将路径存入custom_generate_path该类采用惰性加载策略在首次执行时才导入并实例化以节省冷启动时间module_service.py。实例一RunCoffBOF 加载RunCoff.yaml 声明advanced.custom_generate: true其自定义实现 RunCoff.py 的核心逻辑script_file main_menu.dotnet_compiler.compile_task( module.compiler_yaml, module.name, dot_net_versionparams[DotNetVersion].lower(), confuseobfuscate, ) params_dict {} params_dict[Entrypoint] params[EntryPoint] params_dict[File] params[File].get_base64_file() params_dict[HexData] process_arguments(params[Format String], params[Arguments]) param_json json.dumps(params_dict) base64_json base64.b64encode(param_json.encode(utf-8)).decode(utf-8) return f{script_file}|,{base64_json}该模块把用户上传的 BOF 文件转 base64并用bof_packer的process_arguments按格式字符串b/i/s/z/Z把参数打包成十六进制数据作为HexData传给 COFF 加载器。这正是模块名“必须由用户提供 Format String、Entry Point 和 Arguments”这一约束的代码体现。实例二Spawn动态派生 C# agentSpawn.yaml 同样启用custom_generate其实现 Spawn.py 演示了文档所述“访问 Empire 逻辑”的完整场景根据Language选项调用main_menu.stagergenv2.generate_launcher生成 launcherC# 直接生成PowerShell 还需经generate_powershell_exe打包校验 exe 生成成功读取为 base64 程序集通过main_menu.modulesv2.get_by_id(csharp_code_execution_assembly)查找 Assembly 模块并编译其compiler_yaml以反射执行的方式把新程序集在内存中拉起返回ModuleExecutionRequest(command, data..., files[script_file])。注意其Obfuscate、ObfuscateCommand选项使用了depends_on依赖仅当Languagepowershell时出现Language选项本身strict: true且带suggested_values——这些组合在 Module Development README 的 “Advanced Options” 与 “Internal Options” 小节中有完整讲解编写 C# 模块时同样适用。与其它语言模块的差异要点从源码结构看C# 模块与 PowerShell/Python 模块存在三点本质差异无脚本文件代码内嵌 YAMLC# 模块的代码即csharp.Code字段加载时不存在script_path/script校验分支module_service.py 对language csharp直接pass编译而非解释执行任务产物是经 Empire-Compiler 编译、zlib 压缩的 .NET 程序集agent 端反射加载执行自动注入 DotNetVersion 选项其它语言模块无此选项C# 模块则强制具备且加载时还会自动追加T1620规避检测作为解释器相关技术_get_interpreter_techniquemodule_service.py。此外C# agent 与模块语言的兼容矩阵可在 module_service.py 中查看csharpagent 可以执行bof、powershell、csharp三类模块而test_module_service.py的test_execute_csharp_module等用例test_module_service.py直接验证了 C# 模块在 C# agent 上的执行路径。实战编写清单编写一个新 C# 模块时建议按以下顺序确认YAML 骨架按本文第一部分的通用字段写好name/authors/description/tactics/techniques/language: csharpoptions 设计声明模块参数文件类参数用type: file枚举参数用strict: truesuggested_values需要条件展示的用depends_on/internalcsharp 段确定UnsafeCompile涉及指针/内存 patch 必须为 true、CompatibleDotNetVersions决定默认编译版本与DotNetVersion选项、编写Code入口Main(string[] args)参数顺序与 options 顺序对应、按需配置ReferenceSourceLibraries/ReferenceAssemblies/EmbeddedResources是否需要 custom_generate若模块需要生成 launcher、查询其它模块或调用 Empire 内部服务则设置advanced.custom_generate: true并编写同名.py验证将 YAML 放入empire/server/modules/csharp/对应分类目录启动服务确认模块成功加载加载日志在ModuleService.load_modules并参照 test_dotnet.py 与 test_module_service.py 了解编译失败与执行路径的预期行为。更多与模块开发相关的通用主题——特殊选项Agent/Background/OutputFunction、动态选项依赖、内部选项等——可继续阅读 Module Development README以及同一目录下的 PowerShell Modules、Python Modules 与 BOF Modules 文档。赞分享渗透测试网络安全应用安全【免费下载链接】EmpireEmpire is a post-exploitation and adversary emulation framework that is used to aid Red Teams and Penetration Testers.项目地址https://gitcode.com/gh_mirrors/empi/Empire点击查看免费下载相关推荐Open-Meteo 免费天气 API 快速接入指南:免注册免密钥,五分钟接入全球气象数据Open Meteo 免费天气 API 快速接入指南:免注册免密钥,五分钟接入全球气象数据 Open Meteo 是一个开源的免费天气 API:面向非商业使用,渗透测试网络安全应用安全Empire PowerShell 模块开发指南从 YAML 模板到自定义 Generate 的完整实战Empire PowerShell 模块开发指南从 YAML 模板到自定义 Generate 的完整实战 导读 本文以 Empire 仓库中的 powersh渗透测试网络安全应用安全TobudOS 中的 MicroPython 外部 C 模块开发指南结构与编译全解析TobudOS 中的 MicroPython 外部 C 模块开发指南结构与编译全解析 在物联网终端上运行 MicroPython 时纯 Python 环境常上一篇openYuanrong数据系统源码编译安装从零构建高性能分布式缓存系统下一篇K-NET共线程技术揭秘在业务线程直接驱动协议栈的终极技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/13 6:30:02

本地大模型-本地ComfyUI的使用问题/常用插件和相关配置

目录 ​编辑必装插件ComfyUI Manager 下载插件ComfyUI Model Downloader ​编辑 gguf量化支持ComfyUI-GGUF 配置文件 使用ComfyUI Manager git下载报错 安装报错安全级别 往期内容 必装插件ComfyUI Manager 作为必须安装的扩展(位于 custom_nodes 目录&…

2026/10/13 6:25:01

ZooKeeper临时节点删除机制:会话过期决定,而非连接断开

1. 临时节点的生命周期由“会话”说了算,不由“连接”说了算先丢一个反直觉的结论:当你的客户端和 ZooKeeper 之间的 TCP 连接断开时,临时节点并不会像很多人以为的那样立刻消失。它什么时候被删,取决于会话(Session&a…

2026/10/13 12:16:24

光储充换电站分时电价与用户负荷互动双层优化模型及Matlab复现

光储充换电站这个概念最近两年有多热,看看知网就明白了——尤其是“分时电价”和“用户负荷”两个词,几乎成了这类论文标题的流量密码。但真正动手复现过的人都知道,大多数公开代码只给你一张固定电价表去调度,用户完全是被动接收…

2026/10/13 12:16:24

六款Flask开源项目助力后台管理、人脸识别与自动化运维

如果你也在用 Flask 搭后台、做算法服务或者搞自动化运维,应该会有同感:框架本身很轻,写起业务来确实爽,但到了“要权限、要人脸识别、要批量跑任务”这种阶段,靠一个 main.py 从头手搓,工作量会突然爆炸。…

2026/10/13 12:16:24

九键字母组合的DFS与回溯:从递归到剪枝的算法思维

1. 不只是LeetCode:九键字母组合为什么值得深入拆解如果你刷过算法题,大概率见过这道经典题:给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合,数字到字母的映射跟电话九宫格一致。比如输入 "23"…

2026/10/13 12:16:24

考虑分时电价与用户负荷互动的光储充换电站优化模型解析

1. 项目背景与实际价值这两年新能源圈子里最卷的赛道之一,就是光储充换电站。光伏、储能、充电桩、换电柜凑到同一个场站里,看起来是"全家桶",实际上运营起来远比想象中复杂。最让我头疼的问题在于:光伏出力看天吃饭&am…

2026/10/13 12:16:24

Windows环境下SonarQube与Sonar Scanner代码质量平台搭建实战

接手过不少代码质量相关的活儿,但真正让我觉得“这玩意儿不装不行”的,还是团队被线上故障逼到墙角的那一次。一个看似不起眼的小改动,因为缺少判空,直接让核心服务在高峰期挂了。事后排查,代码里其实早就有坏味道&…

2026/10/13 12:11:24

哈工大编译原理期末复习完整笔记:从DFA到中间代码全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 5:19:27

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/12 12:01:26

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/12 12:54:07

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/13 0:04:41

基于Triton部署YOLO目标检测:从训练脚本到线上服务

简介:这份资源面向希望将目标检测模型落地到生产环境的深度学习开发者与算法工程师,聚焦于用 Triton Inference Server 部署 YOLOv9 的完整实战方案,解决从训练权重到线上推理服务之间的工程化难题。压缩包共 16 个文件,约 886KB&…

2026/10/13 0:04:41

手把手教你云端部署Qwen-Image-2.1:从GPU选型到在线文生图服务

Qwen-Image-2.1 这个开源的图像生成模型,最近在内容创作和 AI 应用圈子里热度相当高。它属于通义 Qwen 系列里的视觉生成分支,让我眼前一亮的是它对中文长文本的理解能力——以前用那些老方案生成带中文文字的图,十个里九个是“乱码印刷体”&…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑