helixmap/loghunter

GitHub: helixmap/loghunter

loghunter 是一款无需部署、本地优先的命令行威胁狩猎工作台,直接对已有的 Zeek、Pi-hole、syslog、CloudTrail 等日志运行透明检测器,发现信标活动、可疑 DNS、端口扫描等威胁。

Stars: 2 | Forks: 0

# loghunter [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/helixmap/loghunter/actions/workflows/ci.yml) loghunter 是一款本地优先的命令行威胁狩猎工作台,专为自托管用户设计。你只需 将其指向已有的日志——Zeek、Pi-hole/dnsmasq、syslog、CloudTrail——它就会 告诉你日志中的内容,并对其运行透明的检测器:信标活动 (beaconing)、可疑的 DNS、端口扫描、罕见的 syslog 事件、异常的长连接,以及不同寻常的 CloudTrail 活动。每次运行都会标明每个检测器背后的技术,因此你始终清楚,某项发现是 来源于已公开的算法,还是直观的启发式方法。 **它不是 SIEM。不是 agent。也不是魔法。** 无需部署,没有数据库,没有 daemon,也 不需要账户。安装它,将其指向日志目录,阅读输出结果。它直接运行在 管理员自己的机器上,处理静态日志。 [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](#license) ![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg) **文档:** [常见问题与检测器工作原理](docs/FAQ.md) · [路线图](docs/ROADMAP.md) · [已知问题](docs/BUGS.md) · [数据结构 (Schemas)](docs/SCHEMA.md) 每次运行都会以一个摘要横幅开始——展示了加载的内容,以及每个检测器 使用的具体技术——然后按检测器对发现进行分组(以下为演示输出;地址 使用的是 [RFC 5737](https://datatracker.ietf.org/doc/html/rfc5737) 文档 保留空间),这些结果可以直接作为纯文本显示在你的终端中(默认选项),也可以输出为 HTML 等更丰富的格式或其他可用选项:

loghunter hunting one compromised host across conn, DNS, and syslog: two periodic C2 beacons, a high-entropy DGA lookup cluster under a single .xyz apex, and the matching root SSH login plus persistence events in syslog — run against synthetic RFC 5737 / reserved-domain data

loghunter html report

## 快速开始 ``` pip install loghunter-cli # 在你 config 中启用的所有内容中进行 hunt loghunter hunt # 或直接指向一个目录 / 文件(该路径即为 intent) loghunter ~/zeek-logs loghunter syslog /var/log # 在 hunt 之前进行 orient - 对单个文件进行快速、真实的 profile loghunter digest /var/log/messages # 一次性的、detection-driven 设置 - 查找你的日志并写入 config loghunter init ``` 入门无需配置文件——`loghunter ` 即可直接处理目录或 单个文件。`loghunter init` 的作用只是让操作变得可复现。 ## 为什么使用 loghunter? - **在日志所在的地方运行。** 无需额外服务,无需数据库,无需 daemon,也无需推送 agent。 执行 `pip install`,将其指向目录,即可获取输出。唯一存在的可选 设置步骤是:`loghunter init`,这只是为了方便起见写入一个纯文本配置文件。 - **真实的方法,清晰可见。** 信标活动通过基于连接时序的 FFT 发现; DNS 则通过基于每次查询行为的 HDBSCAN 聚类发现;罕见的 syslog 事件通过 drain3 日志模板化加上稀有度评分发现;CloudTrail 则通过透明的基于主体的 z-score 复合评分发现。每次运行都会告诉你使用了哪种技术。你可以确切了解*为什么*某些内容 会被标示出来——绝不是黑盒。 - **广泛的日志摄取能力。** 这一款工具即可读取 Zeek(支持 NDJSON *和* TSV,支持扁平目录 *或* 按日期分区的 目录)、Pi-hole/dnsmasq、扁平的 RFC 3164 syslog(支持 Debian *和* RHEL/Fedora 布局), 以及 CloudTrail。日志轮转 (Rotation) 和 `.gz`/`.bz2`/`.xz` 压缩文件均可透明处理。 - **在狩猎前先了解全貌。** `loghunter digest FILE` 会读取日志并报告相关特征—— 时间跨度、主要通信节点 (talkers)、混合数据的整体形态——且完全不做出任何判定。它只告诉你 有哪些内容,从而让你知道该将检测器指向哪里。 - **先过滤,后分析。** 默认启用了一个经过精心整理、包含已知无害基础设施的 allowlist,它会在 *任何*检测器看到数据之前就抑制掉这些噪声——你可以按名称关闭任意列表,通过 `--no-allowlist` 停用所有 列表,或者添加你自己的列表。你的底噪水平由你自己设定;检测器完全不知道它的存在,并且每次运行都会披露它隐藏了多少数据。 - **坦诚的输出。** 发现结果带有严重程度、评分背后的证据,并且(在使用 `-v`/`-vv` 时)提供分析师下一步可以追查的线索。根据任务需要选择合适的输出形式:用于阅读的**报告** (`text`、`html`、`pdf`),用于编写脚本处理的无损**数据流** (`json`),或者是用于分诊处理的**工作列表**(`csv`)。 ## 它能狩猎什么 | 检测器 | 识别目标 | 方法 | 来源 | |-----------|-----------------------------------------------------|------------------------------|--------------------------------| | `beacon` | 周期性 C2 风格的回调 | 基于连接时序的 FFT | Zeek `conn.log` | | `dns` | DGA / 隧道 / 异常查询 | HDBSCAN 聚类 | Zeek `dns.log` **或** Pi-hole | | `syslog` | 罕见事件与重启 | drain3 模板化 + 稀有度 | syslog (扁平) **或** Zeek `syslog.log` | | `scan` | 垂直 / 水平 / 网段 / 慢速端口扫描 | 模式识别 (启发式) | Zeek `conn.log` | | `duration`| 异常长寿命的连接 | 启发式方法 | Zeek `conn.log` | | `aws` | 每个主体异常的 CloudTrail 行为 | 统计方法 (z-score 复合计算) | CloudTrail `*.json` | `dns` 和 `syslog` 每一个都能针对**两**个源系回答**一个**问题——例如,DNS 对应 Zeek 和 Pi-hole,而 syslog 对应扁平的 rsyslog 和 Zeek 自身的 `syslog.log`——并且它们能够适应 所接收到的任意精度数据。 你可以运行全部检测器(`loghunter hunt`),选择性运行(`loghunter hunt --detect=beacon,dns`),或者排除 某些检测器(`loghunter hunt --detect='all,!syslog'`)。每个检测器也可以作为独立的子命令运行: `loghunter beacon ~/zeek`。 ## 运行机制 ``` discover & parse → allowlist (suppress) → detect → render ``` 各项职责之间界限分明。**加载器**负责查找文件、解压、 将每个连接源标准化为统一的规范 schema,并吸收存储方式的差异 (TSV 与 NDJSON,扁平与按日期分区的目录,以及轮转机制)。**allowlist** 在分析*之前* 抑制已知正常的流量。**检测器**只进行分析——它们绝不会打开文件、 读取配置或抑制数据。**输出处理程序**只负责渲染。CLI 是唯一一个 将错误转化为可操作消息并控制退出代码的环节。 由于检测器是纯粹的分析工具,每一个都可以像普通的 Python 函数那样被导入和调用——当你在 notebook 中需要进行实验时,这会非常实用。 ### 分析时间窗口 如果指定的是一个**目录**,一次常规的运行会回溯查看*该数据源自身*在过去 `default_window` (开箱即用默认为 `1d`)内的数据——这是针对实时日志目录的正确默认设置,因为你不必每次都完整读取。如果指定的是**单个文件**,它将读取 整个文件。你可以通过以下方式覆盖默认设置: ``` loghunter --since=7d ~/zeek # last 7 days loghunter --since=2026-05-01 --until=2026-05-08 ~/zeek loghunter --days=2-4 ~/zeek # 2 to 4 days ago loghunter --all ~/zeek # the entire archive ``` CloudTrail 是唯一一种不采用默认时间窗口的源——新颖性检测需要 完整的历史记录,因此除非你明确缩小范围,否则它将始终加载完整数据。 ## 在狩猎前了解全貌:`digest` ``` loghunter digest /var/log/messages loghunter digest conn.log dns.log # several files → several cards ``` `digest` 会对每个文件进行内容嗅探,将其路由到相应的汇总器(conn、dns、syslog、 cloudtrail),对于无法识别的内容,则回退使用一种快速的字节分析器——**blob**。一张卡片采用左对齐的纯事实展示:文件的 时间窗口、行数和大小、具有比例锚点的直方图,以及一些简明直观的见解(例如:“一个客户端占据了 71% 的查询”)。它陈述事实和极端情况,从不做出判定——没有“可疑”,也没有 “异常”。它在 allowlist 生效*之前*读取你的数据,因为文件中的所有内容(无论是否 在 allowlist 中)都是“这里有什么”的一部分。blob 分析器是有边界的:它只对大型文件进行采样,而不是完整读取,因此处理一个 1GB 的未知文件所消耗的资源与处理一个 1KB 的文件 是一样的。 ## 安装说明 loghunter 已在 PyPI 上发布为 **`loghunter-cli`**(其命令名、导入包名和 配置部分名均为 `loghunter`)。 ``` pip install loghunter-cli # core pip install 'loghunter-cli[fast]' # fast-hdbscan accelerator for DNS clustering pip install 'loghunter-cli[splunk]' # Splunk exporter pip install 'loghunter-cli[cloudtrail]' # CloudTrail (S3) exporter pip install 'loghunter-cli[all]' # fast + splunk + cloudtrail (recommended) pip install 'loghunter-cli[pdf]' # PDF reports - opt-in, see note below ``` 需要 **Python 3.11+**。直接执行 `pip install loghunter-cli` 即可正常运行——DNS 聚类 依赖于标准的 `hdbscan` 运行(作为基础依赖项);当你需要时,`[fast]` 会切换为基于 numba 加速的后端, 并且该工具会在每次运行时告诉你当前激活的是哪一种。强烈推荐使用 `[fast]`。 `[pdf]` 特意与 `[all]` 分开了,因为它需要两样东西:python 包 (`pip install 'loghunter-cli[pdf]'`)以及 WeasyPrint 用于渲染的原生文本库 (Pango, HarfBuzz, fontconfig),而这些是 `pip` 无法安装的。你需要通过操作系统的包 管理器来添加它们——在 macOS 上使用 `brew install pango`,在 Linux 上使用 `apt install libpango-1.0-0`(或者 `dnf install pango`)。其他所有格式均无需额外设置即可使用。 从源码安装: ``` git clone https://github.com/helixmap/loghunter cd loghunter pip install -e '.[all]' ``` ## 配置 配置是可选的——loghunter 无需任何配置即可针对路径运行。当你希望 操作可复现时,`loghunter init` 会检查你机器上的常规位置,分析 它找到的内容(包括哪些日志类型、大致的大小、数据的新鲜度——而且不会读取任何一行日志), 并在 `~/.loghunter/`(如果是系统级 安装,则在 `/etc/loghunter`)下写入一个带有注释的配置文件。你可以随时 重新运行它:它提供合并到现有配置的选项(每个提示都会显示你 已经设置的内容——按回车键即可保持原样)或者重置配置,在写入任何内容之前,它会显示将要更改的内容的摘要,并且永远不会 破坏你已有的设置。 配置会按以下顺序从遇到的第一个文件加载: 1. `--config=FILE` 2. `~/.loghunter/config.toml` 3. `/etc/loghunter/config.toml` loghunter 的所有数据都存放在隐藏的 `~/.loghunter/` 目录下——包括配置、allowlist、 导出文件、报告——因此它不会与项目目录发生冲突。以下是一个精简的示例: ``` [loghunter] detect = "all" # "all" | "dns,beacon" | "all,!syslog" zeek_dir = "/var/log/zeek" syslog_dir = "/var/log" # pihole_dir = "/var/log/pihole" # cloudtrail_dir = "/var/log/cloudtrail" home_net = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"] default_window = "1d" # lookback for a directory; "" or "all" = full output_format = "text" # text | json | csv | html | pdf ``` 发现结果默认会打印到你的终端中——保持其可通过管道传输的便利性。你可以设置 `report_dir`(或传入 `--out=PATH`)以便将结果写入报告文件。检测器暴露的每个可调参数都被记录在 生成配置文件底部的“引擎室 (engine room)”注释中(你极少需要用到它);此外, `loghunter --help` 会列出完整的可用参数。 ## 支持的日志源 - **Zeek** - 支持 NDJSON 或 TSV 格式的 `conn.log`、`dns.log`、`syslog.log`,可读取自扁平目录或 按日期分区的子目录。日志轮转和 gzip/bzip2/xz 压缩均可透明处理。 - **Pi-hole / dnsmasq** - DNS 事件日志,按域名聚合以进行聚类。 - **syslog** - 扁平的 RFC 3164 格式。发现机制基于内容嗅探,而非文件名匹配,因此它 既能处理 Debian 规范(`syslog`、`auth.log`、`kern.log`),也能处理 RHEL/Fedora 规范(无扩展名的 `messages`、`secure`、`maillog`)——并且不会将 `dnf.log` 或诸如 `wtmp` 之类的二进制文件误认为是日志流。 - **CloudTrail** - gzipped JSON 事件记录,支持本地读取或从 S3 提取(见下文)。 ## Allowlist loghunter 会在分析**之前**进行过滤:在任何检测器看到数据之前,已知无害的流量就会被丢弃, 从而确保信号不会被淹没在繁杂的基础流量中。Allowlist 文件分为两种: - **扁平文件 = 抑制。** 每行一条规则——可以是 IP、CIDR、`:port/proto`,或者 域名 glob/regex。匹配的流量会在任何检测器运行之前被丢弃。 - **TOML stanza = 分类。** 当检测器需要知道某项内容*是什么* (例如,一个域名服务器,一个备份客户端),而不是是否需要丢弃它时使用。 loghunter 内置了三个精选的**域名**列表,可按名称切换: | 列表 | 默认 | 涵盖范围 | |------|---------|--------| | `common` | 开启 | 广泛的互联网基础设施 - CDN、云服务、NTP、证书验证、公共 DNS、操作系统更新通道 | | `devices` | 开启 | 消费级物联网 / 智能家居的后台回传流量 | | `homelab` | 关闭 | 自托管工具 (Splunk, Proxmox, UniFi, …) - 需主动开启,因为屏蔽你正在运行的产品会形成真实的监控盲点 | 软件不包含任何与广告、跟踪或特定目的相关的列表——因为大家的看法不一,而且你可能希望 看到这些内容。loghunter 永远不会内置数字连接的抑制规则(因为这取决于你的主机情况,而且 内置这些规则可能会掩盖真实的发现)。 你可以使用 `allowlist` 相关命令来检查和管理它: ``` loghunter allowlist # what's loaded, on/off, and how much each run suppresses loghunter allowlist show common # the patterns in a list loghunter allowlist enable homelab # turn a shipped list on (writes [allowlist.lists]) loghunter allowlist disable common # …or off loghunter allowlist copy common # fork a shipped list into your allowlist.d to edit ``` 切换开关也可以直接在配置文件的 `[allowlist.lists]` 下设置;对于单次运行,可以通过 `--no-allowlist` 关闭整个 allowlist,或者通过 `enabled = false` 永久关闭。每次检测 运行都会在运行的摘要横幅中披露其覆盖情况(`allowlist: 抑制了 1,284 个连接 (12%) 和 312 个域名 (59%)`——即每个列表覆盖的已加载行数百分比,因此一旦出现出乎意料的 抑制率,你就能一目了然),所以抑制操作绝不是静默的。 你可以在 `~/.loghunter/allowlist.d/` 目录下的任意 `domains_*.txt` 文件中添加你自己的规则(内置的 `domains_user.txt` 是一个入门示例)。这些直接添加的文件始终是**增量叠加**的,并且在升级后依然保留;如果 要替换内置列表,请将其 `disable` 并添加你自己的。格式错误的 regex 行会被跳过,并给出 指出其文件和行号的通知,而不会导致程序崩溃,因此一个输入错误不会导致整个运行失败,也不会 静默禁用列表的其余部分。一个不带端口的纯主机 IP 会抑制 涉及该主机的*所有*流量——这功能强大但极其危险,因此在任何 出现它的地方都会被明确标记出来。 ## 导入日志:导出器 loghunter 可以将外部系统中的日志提取到本地文件,随后像 处理任何其他源一样对其进行分析——syslog 检测器根本无法分辨数据是来自 rsyslog 还是 Splunk 导出。 ``` loghunter export splunk # run the configured "default" query loghunter export splunk auth # run the configured named query: "auth" loghunter export cloudtrail # get logs from s3 ``` - **Splunk** - 通过 `[export.splunk.query.]` 定义的 SPL 查询。建议 使用 `LOGHUNTER_SPLUNK_USER` / `LOGHUNTER_SPLUNK_PASS` 环境变量,而不是 在配置文件中写入明文凭据,但如果你直接写明文,loghunter 也不会评判你。 - **CloudTrail** - 从 S3 前缀中提取 gzipped 的 JSON 文件。这里*不*负责处理 AWS 身份验证:你需要自行对 shell 进行身份验证,然后由 boto3 解析环境凭据链。 loghunter 绝不会读取、存储或提示输入 AWS 凭据,并且会在发生大量 数据传出前发出警告。 ## 输出格式 根据你对发现结果的处理需求进行选择——使用 `--format=NAME`(或在配置中设置 `output_format`): - **`text`**(默认)- 面向终端的分组摘要报告,包含每个检测器 背后的信号表格。 - **`html`** - 同样的报告,带有同样的每个检测器的信号表格,作为一个自包含的 带样式文件输出,你可以在浏览器中打开、打印或分享。无需额外依赖;包含深色模式和 打印样式。 - **`pdf`** - 将 html 报告渲染为 PDF(一个渲染器,两种输出)。需主动开启: `pip install 'loghunter-cli[pdf]'`,外加原生文本库 (Pango/HarfBuzz/fontconfig - 参阅上述安装说明)。宽报告会以横向方式打印,并且较宽的单元格会自动换行而不是被截断。 - **`json`** - 无损的机器可读数据流:一个包含 `run_summary` 和 `findings` 的单一对象, 具有适合 `jq` 或 SIEM 的正确数据类型,且始终是完整的数据集合。包含 `schema_version`。 - **`csv`** - 用于修复补救的工作列表:每个发现占一行,包含后续步骤、“原因”, 以及用于在解决问题时进行跟踪的空 `status`/`notes` 列。 `text`、`html` 和 `pdf` 属于阅读视图——它们显示相同的内容,并支持 `-v`(精心 整理的“为何如此评分”)和 `-vv`(原始调试信息:模板字符串、集群成员资格、完整 证据)。`json` 和 `csv` 则始终携带完整的数据集合。 **输出去向。** 每种文本格式——包括 `html`——默认都会打印到 stdout;你可以通过重定向 或使用管道来保存(`loghunter dns -f html > report.html`)。`pdf` 是二进制格式,因此它需要 一个目标:一个管道(`-f pdf > report.pdf`)或一个文件。通过设置 `--out=PATH` 或 `report_dir` 可以写入 文件;如果目标是目录,会自动命名为 `lh-report__`(如果只运行了 单个检测器,否则命名为 `-plusN`),并报告其写入的路径。即使设置了 `report_dir`,也可以使用 `-o=-` 强制输出到 stdout。 ## 从源码构建与运行测试 ``` git clone https://github.com/helixmap/loghunter cd loghunter pip install -e '.[dev]' python -m pytest ``` `main` 分支始终保持可运行状态。架构测试涵盖了关键边界——检测器 发现、运行规划、加载器元数据、allowlist 抑制、输出注册以及 CLI 错误格式化。 ## 致谢 loghunter 基于数学方法的检测——用于信标周期性的 FFT,用于 DNS 行为的 无监督聚类——其灵感来源于 David Hoelzer 的 SANS SEC595 课程。这些技术本身(FFT、 HDBSCAN、 drain3)属于公共领域的数学成果和开源库;而本 实现是独立且原创的,如有任何错误,责任均在本人。loghunter 不隶属于 SANS 或 GIAC,也 未获得其背书。 ## 许可证 loghunter 基于 [MIT License](LICENSE) 授权。
标签:IP 地址批量处理, Python, URL发现, 安全检测, 插件系统, 无后门, 逆向工具