【免费下载链接】Empire
Empire 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 作为一款后渗透与对抗模拟(adversary emulation)框架,其服务器端日志体系承担着运行状态追踪、Listener 通信审计与排错定位的关键职责。本文以 docs/settings/logging.md 为核心,结合仓库内配置与源码实现(log_util.py、config.yaml、arguments.py),系统讲解服务器日志与 Listener 日志的落盘路径、级别控制、格式化规则、配置文件字段与命令行参数,并给出可复制的排查与调优方案。读完本文,你将能独立完成 Empire 日志级别的动态调整、控制台格式切换、Listener 独立日志的读写以及"最后任务输入"调试开关的配置。
日志体系总览:双通道输出模型
Empire 服务器采用文件 + 控制台双通道的日志输出模型:所有日志同时写入磁盘文件与控制台(终端)。默认情况下:
- 服务器日志文件:~/.local/share/empire/logs/empire_server.log
- 控制台输出:跟随日志级别过滤(默认 INFO)
从源码看,日志根目录由 config_manager.py 中的 DATA_DIR 决定,即 ~/.local/share/empire(测试模式下为 ~/.local/share/empire-test),log_util.py 中的 get_log_dir() 在其下创建 logs/ 子目录:
def get_log_dir():
log_dir = config_manager.DATA_DIR / "logs"
log_dir.mkdir(parents=True, exist_ok=True)
return log_dir
setup_logging() 在服务器启动流程 server.py 的 run() 中于启动早期被调用,完成 root logger 的初始化。
Listener 独立日志:每个监听器一个文件
Listener(监听器)拥有独立的日志配置,与服务器 root 日志分离:
- 文件输出:所有 DEBUG 及以上级别的日志写入 ~/.local/share/empire/logs/listener_<listener_name>.log
- 控制台输出:所有 WARNING 及以上级别的日志打印到控制台
即:文件记录完整明细(含 debug),控制台只呈现告警与错误,避免高频 agent 心跳信息淹没终端。
如何在代码中使用 Listener 日志
若希望某条消息进入 Listener 专属日志,请使用 self.instance_log;若希望消息同时出现在服务器日志文件与控制台,则还需额外调用模块级 logger 的 log.info()。以 http 监听器为例,官方推荐写法为:
self.instance_log.info()
从源码看,instance_log 的初始化发生在监听器启动阶段。以 http.py 为例,start_server() 中通过 get_listener_logger() 按监听器名称创建独立 logger:
self.instance_log = log_util.get_listener_logger(
LOG_NAME_PREFIX, self.options["Name"]["Value"]
)
其中 LOG_NAME_PREFIX = __name__(即 empire.server.listeners.http),logger 名称形如 empire.server.listeners.http.<listener_name>。http_foreign、http_hop、http_malleable、port_forward_pivot、smb 等监听器实现同样遵循该模式。
get_listener_logger()(log_util.py)的核心实现要点:
log = logging.getLogger(f"{log_name_prefix}.{listener_name}")
# return if already initialized
if log.handlers:
return log
log.propagate = False
log_dir = get_log_dir()
log_file = log_dir / f"listener_{listener_name}.log"
listener_log_file_handler = logging.FileHandler(log_file)
listener_log_file_handler.setLevel(logging.DEBUG) # 文件端记录 DEBUG 及以上
…
listener_stream_handler = logging.StreamHandler()
listener_stream_handler.setLevel(logging.WARNING) # 控制台端仅 WARNING 及以上
注意两点实现细节:
另外,http.py 中还会将 Flask 内置的 werkzeug logger 级别压制到 ERROR,以减少 Web 框架噪音刷屏。
服务器日志与 Listener 日志的协同
实际代码中常采用"双写"策略:例如 http.py 中在任务处理的关键路径上先写 self.instance_log.info(message) 再写 log.info(message),前者进入 listener_<name>.log,后者进入服务器日志与控制台。这也是官方文档"若希望消息同时进入服务器日志与控制台,就额外调用 log.info()"建议的具体落地方式。
格式化器:Simple 与 Expanded 两种格式
日志格式由 log_util.py 中定义的两个常量决定:
LOG_FORMAT = "%(asctime)s [%(filename)s:%(lineno)d] [%(levelname)s]: %(message)s "
SIMPLE_LOG_FORMAT = "[%(levelname)s]: %(message)s "
| Simple(简单格式) | 仅日志级别 + 消息 | 控制台默认格式 |
| Expanded(扩展格式) | 时间戳 + 触发日志的源码文件与行号 + 级别 + 消息 | 服务器日志文件;可通过 logging.simple_console 启用为控制台格式 |
控制台输出还经过 ColorFormatter 按级别着色:DEBUG 灰色、INFO 蓝色、WARNING 黄色、ERROR/CRITICAL 红色,便于在终端中快速区分日志严重程度。
文件端 handler 始终使用扩展格式 LOG_FORMAT;控制台端则根据配置选择格式,setup_logging() 中:
simple_console = config.logging.simple_console
stream_format = SIMPLE_LOG_FORMAT if simple_console else LOG_FORMAT
配置文件详解
当前仓库的默认配置
Empire 的服务器配置位于 ~/.config/empire/config.yaml(首次启动由 config_manager.py 从仓库内 empire/server/config.yaml 复制而来)。当前仓库默认的日志相关配置为:
logging:
level: INFO
simple_console: true
debug:
last_task:
enabled: false
file: debug/last_task.txt
对应的配置模型定义在 config_manager.py:
class LoggingConfig(EmpireBaseModel):
level: str = "INFO"
simple_console: bool = True
class LastTaskConfig(EmpireBaseModel):
enabled: bool = False
file: Path = Path("debug/last_task.txt")
class DebugConfig(EmpireBaseModel):
last_task: LastTaskConfig
各字段说明
- logging.level:服务器 root 日志的级别,默认 INFO。控制台端 handler 以此级别过滤(见下文 setup_logging 源码)。
- logging.simple_console:布尔值,为 true 时控制台使用 Simple 格式(仅级别 + 消息),为 false 时切换为 Expanded 格式(含时间戳与源码行号)。
- debug.last_task.enabled:布尔值,为 true 时 Empire 会把最后一条下发给 agent 的任务输入保存到文件,便于复现与调试。
- debug.last_task.file:任务输入保存路径。默认相对路径为 debug/last_task.txt;结合 EmpireBaseModel.set_path 将相对路径解析到 DATA_DIR 下的行为,可以推断默认落盘位置为 ~/.local/share/empire/debug/last_task.txt。字段为 Path 类型,也支持配置为绝对路径。
关于文档示例与仓库默认值的差异说明
原文档给出的配置示例为:
logging:
level: INFO
directory: empire/server/downloads/logs/
simple_console: true
debug:
last_task:
enabled: false
file: empire/server/data/last_task.txt
对照当前仓库 config.yaml 与 LoggingConfig 定义可知:
- 文档示例中的 logging.directory 字段在当前版本的 LoggingConfig 中并未定义;日志目录实际由 DATA_DIR/logs(即 ~/.local/share/empire/logs)决定,get_log_dir() 每次调用都会自动 mkdir 确保目录存在。
- debug.last_task.file 的默认值在仓库中为 debug/last_task.txt,而非文档示例中的 empire/server/data/last_task.txt。
因此实际使用时,请以当前仓库 empire/server/config.yaml 及 ~/.config/empire/config.yaml 为准。日志级别与格式化相关行为受源码实现约束,两者一致。
命令行参数:–log-level 与 –debug
日志级别可以在启动服务器时通过命令行覆盖,优先级高于配置文件。
–log-level <level>
设置服务器日志级别,取值必须是以下之一(大小写不敏感):DEBUG、INFO、WARNING、ERROR、CRITICAL。
# 以 DEBUG 级别启动(最详细的日志输出)
./ps-empire server –log-level DEBUG
# 仅输出告警及以上
./ps-empire server –log-level WARNING
参数定义见 arguments.py:-l / –log-level,type=str.upper 自动转为大写,choices 限定了五档合法取值,非法值会被 argparse 直接拒绝。
–debug
–debug 是 –log-level DEBUG 的便捷等价写法(arguments.py 中使用 store_const 将 log_level 置为 DEBUG):
./ps-empire server –debug
级别解析的优先级逻辑
setup_logging()(log_util.py)中的解析顺序为:
def setup_logging(args, override_config=None):
config = override_config or empire_config
if args.log_level:
log_level = logging.getLevelName(args.log_level.upper())
else:
log_level = logging.getLevelName(config.logging.level.upper())
即:命令行 flag 优先,未传 flag 时回退到配置文件 logging.level。无论配置何种级别,root logger 本身始终被设置为 DEBUG(源码注释明确指出:"If this isn't set to DEBUG, then we won't see debug messages from the listeners"),实际过滤由文件 handler 与控制台 handler 各自的 setLevel 完成——文件端不设过滤(保留全部),控制台端使用最终计算出的 log_level。
源码级工作流:日志从产生到落盘
一次日志记录的完整路径如下:
测试验证:日志行为有据可查
仓库在 empire/test/test_logs.py 中提供了日志行为的自动化测试,可作为排错与回归依据:
- test_simple_log_format:验证配置 simple_console: true 时,控制台 handler 使用 ColorFormatter 且格式为 SIMPLE_LOG_FORMAT。
- test_extended_log_format:验证 simple_console: false 时控制台切换为 LOG_FORMAT(Expanded)。
- test_log_level_by_config:验证级别取自配置文件,且大小写不敏感(测试中写入 "WaRNiNG" 仍解析为 WARNING)。
- test_log_level_by_arg:验证 –log-level ERROR 覆盖配置文件的 WARNING。
- test_log_level_by_debug_arg:验证 –debug 将 root logger 级别置为 DEBUG。
这些测试直接对应本文所述的配置项与参数行为,修改配置后如遇日志异常,可运行 pytest empire/test/test_logs.py 快速验证。
开发规范:使用 logging 替代 print
自 Empire 5 起,项目约定打印到控制台时应使用 logging 模块,而非 print 语句。原因在于 logging 可统一受级别、格式器与文件输出管理,而 print 无法被日志体系捕获与过滤。仓库中仍残留少量 print(多为历史代码未完成迁移),官方建议:
- 能用 logging 替换的,替换为 logging;
- 无保留价值的,直接删除;
- 需要由 API 返回给前端的输出(如 stager 生成结果),应通过 API 返回值传递,而不是 print。
未来特性展望
原文档同时列出了两个规划中的增强方向,可作为二次开发或插件作者的参考:
- JSON 日志:计划支持 JSON 格式输出,便于日志解析与对接外部工具(如 structlog、python-json-logger 等结构化日志生态)。
- 插件独立日志:计划为每个插件分配独立日志文件,并配套"拉取 / tail 指定插件日志"的 API 端点,便于在 Starkiller 中查看单次插件执行产生的大量输出,辅助调试。
这两项均处于规划阶段,当前仓库尚未落地,使用时应以现有 logging.level、logging.simple_console 与 debug.last_task 配置为准。
小结
Empire 的日志体系围绕"服务器日志 + Listener 独立日志"的双通道设计展开:日志目录固定于 ~/.local/share/empire/logs/,级别由命令行 –log-level/–debug 优先于配置文件 logging.level 决定,控制台格式由 simple_console 切换,调试期可借助 debug.last_task 落盘最近一次任务输入。掌握这些配置与源码实现,即可在实战排错中快速定位问题:先看 listener_<name>.log 查通信明细,再以 –log-level DEBUG 重启服务器获得完整调用轨迹。
赞
【免费下载链接】Empire
Empire 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
点击查看 免费下载
相关推荐
Web3UIKit通知系统完全指南:如何使用useNotification和NotificationProvider构建DApp用户反馈
终极漏洞搜索神器Findsploit:渗透测试必备的10个高效技巧
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网硕互联帮助中心





评论前必须登录!
注册