helixmap/sigwood

GitHub: helixmap/sigwood

sigwood 是一款无需 SIEM 或 agent 的本地优先命令行威胁狩猎工具,直接对已有的 Zeek、Pi-hole、syslog 和 CloudTrail 日志运行透明检测器并给出带方法说明的发现报告。

Stars: 64 | Forks: 5

# `sigwood` [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/helixmap/sigwood/actions/workflows/ci.yml) sigwood 是一款为自托管用户设计的本地优先命令行威胁狩猎工作台。你 可以让它指向你已有的日志 - 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) **文档:** [常见问题及检测器工作原理](https://github.com/helixmap/sigwood/blob/main/docs/FAQ.md) · [路线图](https://github.com/helixmap/sigwood/blob/main/docs/ROADMAP.md) · [已知问题](https://github.com/helixmap/sigwood/blob/main/docs/KNOWN-ISSUES.md) · [数据结构](https://github.com/helixmap/sigwood/blob/main/docs/SCHEMA.md) 每次运行都会以一个汇总横幅开始 - 加载了什么内容,以及每个 检测器使用了哪种技术 - 然后按检测器对发现进行分组,以纯文本形式在你的 终端中呈现(默认),或以更丰富的格式(例如 html)呈现。下方的输出仅为 示例展示;地址属于 [RFC 5737](https://datatracker.ietf.org/doc/html/rfc5737) 文档空间:

sigwood 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

sigwood html report

## 快速开始 ``` pipx install sigwood # or pip install sigwood in a venv - see Installation # 跨越配置中启用的所有内容进行搜寻 sigwood hunt # 或直接指向某个目录 / 文件(该路径即为意图) sigwood ~/zeek-logs sigwood syslog /var/log # 在搜寻之前进行定位 - 针对单个文件的快速、真实的概况 sigwood digest /var/log/messages # 一次性的、基于检测的设置 - 查找您的日志并写入 config sigwood init ``` 开始使用时无需配置文件 - `sigwood ` 即可针对一个目录或 单个文件进行工作。`sigwood init` 只是为了让操作可重复执行。 ## 为什么使用 sigwood? - **在日志所在的地方运行。** 无需服务,无需数据库,无需 daemon,无需推送 agent。 `pipx install sigwood`,将其指向一个目录,即可获取输出。唯一存在的设置步骤 是可选的:`sigwood init`,并且它只是为了方便而在 `~/.sigwood/` 下写入纯文本文件。 - **真实的方法,完全透明。** Beaconing 是通过对连接时序进行 FFT 发现的; DNS 是通过对每次查询的行为进行 HDBSCAN 聚类发现的;罕见的 syslog 事件是通过 drain3 日志模板化加上稀有度评分发现的;CloudTrail 是通过透明的按主体(per-principal) z-score 复合评分发现的。每次运行都会告诉你运行了哪种技术。你可以确切地读懂*为什么*某些内容 会被揪出来 - 没有黑盒。 - **广泛的接入能力。** 一个工具即可读取 Zeek(NDJSON *和* TSV,扁平目录 *或* 按日期分区的 目录)、Pi-hole/dnsmasq、扁平的 RFC 3164 syslog(Debian *和* RHEL/Fedora 布局) 以及 CloudTrail。日志轮转和 `.gz`/`.bz2`/`.xz` 压缩都会被透明地处理。 - **在狩猎前先熟悉环境。** `sigwood digest FILE` 会读取日志并报告关于 它的事实信息 - 时间跨度、主要通信者、混合流量的形态 - 且不给出任何结论。它告诉你里面有 什么,从而让你知道该将检测器指向哪里。 - **分析前先过滤。** 默认开启了一份精选的已知无害基础设施白名单,它会在 任何检测器看到数据*之前*抑制掉这些噪音 - 你可以按名称关闭任意列表,使用 `--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*`(包含 `.gz`) | `dns` 和 `syslog` 各自跨越**两**个来源家族回答**一个**问题 - DNS 对应 Zeek 和 Pi-hole,syslog 对应扁平的 rsyslog 和 Zeek 自带的 `syslog.log` - 并且会适应 它们所接收到的任何保真度。 运行所有检测器(`sigwood hunt`),选择部分检测器(`sigwood hunt --detect=beacon,dns`),或者排除 (`sigwood hunt --detect='all,!syslog'`)。每个检测器也可以作为它自己的子命令运行: `sigwood beacon ~/zeek`。 ## sigwood 与 RITA / AC-Hunter 如果你了解 [RITA](https://github.com/activecm/rita)(或者其商业版本 AC-Hunter),就会对这种 beacon 狩猎的目标感到熟悉 - 两者都在 Zeek 日志中狩猎 C2, 并且 RITA 在这方面非常出色。sigwood 在理念而非野心方面有所不同:它没有 数据库,也没有导入步骤(它直接在原地读取 Zeek - 以及 Pi-hole、syslog 和 CloudTrail),它跨越多个 日志家族,而不仅仅是 conn/dns,它为还没见过的日志提供了一个用于熟悉环境 的命令(`digest`),并且它在报告本身上指出了每个发现背后的技术。如果你已经在专用的 Zeek 传感器上运行了 RITA,请保留它 - sigwood 适用于那些日志已经存在的主机,以及 希望用一个轻量级工具处理所有日志的分析师。 ## 运行机制 ``` discover & parse → allowlist (suppress) → detect → render ``` 职责不会跨越这条界限。**加载器**(loader)负责查找文件、解压、 将每个连接源标准化为统一的 schema,并吸收存储方式上的差异 (TSV 与 NDJSON,扁平目录与按日期分区的目录,轮转)。**白名单**(allowlist)在 分析*之前*抑制已知的正常流量。**检测器**(Detectors)只负责分析 - 它们从不打开文件、 读取配置或进行抑制。**输出处理程序**(Output handlers)只负责渲染。CLI 是唯一一个 将错误转化为可操作信息并管理退出码的地方。 因为检测器是纯分析工具,所以每一个都可以像普通的 Python 函数一样被导入和调用 - 当你想在 notebook 中进行实验时非常有用。 ### 分析时间窗口 当指向一个**目录**时,未加限定符的运行会回顾过去 `default_window` (默认为 `7d`)的*该源自身的*数据 - 这对于你不希望每次都完整读取的实时日志目录来说是 正确的默认设置。当指向一个**单个文件**时,它会读取整个 文件。可以通过以下方式覆盖任何一种设置: ``` sigwood --since=7d ~/zeek # last 7 days sigwood --since=2026-05-01 --until=2026-05-08 ~/zeek sigwood --days=2-4 ~/zeek # 2 to 4 days ago sigwood --all ~/zeek # the entire archive ``` CloudTrail 是唯一选择退出默认时间窗口的来源 - 新颖性检测需要 完整的历史记录,因此除非你明确缩小范围,否则它总是全量加载。 时间以你的本地时区进行渲染并会照此标明。传入 `--utc`(或在 配置中设置 `use_utc = true`)以改为使用 UTC 渲染 - 该设置还会将无时区偏移的 `--since`/`--until` 日期和 `--days` 日界线视为 UTC,导出功能的无时间范围 默认窗口也会受其影响。带有明确偏移量的日期(`--since=2026-05-01T09:00+02:00`) 始终按输入原样执行。无论哪种情况,`json` 输出始终是 ISO-8601 UTC 格式。 ## 在狩猎前先熟悉环境:`digest` ``` sigwood digest /var/log/messages sigwood digest /var/log/pihole/pihole.log # a great first move on a Pi-hole box sigwood digest conn.log dns.log # several files → several cards ``` `digest` 会对每个文件进行内容嗅探,将其路由到合适的汇总器(conn、dns、syslog、 cloudtrail),对于任何无法识别的内容,则回退到快速的字节分析器 - **blob**。卡片采用左对齐且基于事实:文件的 时间窗口、行数和大小,带有刻度锚定的直方图,以及一些通俗易懂的 见解(“一个客户端占据了 71% 的查询”)。它陈述事实和极端情况,从不给出结论 - 没有“可疑”,没有 “异常”。它在白名单*之前*读取你的数据,因为文件中的所有内容, 无论是否在白名单中,都是“这里有什么”的一部分。Blob 分析器是有边界的:它对大型 文件进行采样而不是完整读取,因此一个 1GB 的未知文件消耗的时间与 1KB 的文件 相同。 ## 安装 在所有地方都是同一个名字:PyPI 发行版、命令、导入包和 配置部分都叫 `sigwood`。需要 **Python 3.11+**。 推荐的安装方式是 [pipx](https://pipx.pypa.io),它为 sigwood 提供了自己的 隔离环境,并将命令放在你的 PATH 中 - 并且避开了直接使用 `pip install` 在 Debian 12+、Raspberry Pi OS、Ubuntu 23.04+ 和 Fedora 上遇到的 `externally-managed-environment` 拒绝(PEP 668): **Debian / Raspberry Pi OS / Ubuntu** ``` sudo apt install pipx pipx ensurepath # once - then reopen your shell pipx install sigwood sigwood --help ``` **Fedora** ``` sudo dnf install pipx pipx ensurepath pipx install sigwood sigwood --help ``` **macOS (Homebrew)** ``` brew install pipx pipx ensurepath pipx install sigwood sigwood --help ``` 更喜欢 [uv](https://docs.astral.sh/uv/)?`uv tool install sigwood` 在 uv 支持的任何平台上都能完成相同的工作。普通的 virtualenv 也可以工作 (`python3 -m venv venv && venv/bin/pip install sigwood`;最小化的 Debian 可能需要 先运行 `sudo apt install python3-venv`)。应该避免的做法是:`sudo pip install` - 它不能 绕过 PEP 668,并且无论如何都会污染系统 Python。使用 `pipx upgrade sigwood`(或在你的 venv 中运行 `pip install -U sigwood`)进行升级。 可选的附加组件(在 pipx 或 pip 下拼写相同): ``` pipx install 'sigwood[all]' # fast + splunk + cloudtrail (recommended) pipx install 'sigwood[splunk]' # Splunk exporter pipx install 'sigwood[cloudtrail]' # CloudTrail (S3) exporter pipx install 'sigwood[fast]' # force fast-hdbscan for DNS clustering pipx install 'sigwood[hdbscan]' # stock hdbscan for DNS clustering pipx install 'sigwood[pdf]' # PDF reports - opt-in, see note below ``` 在人们通常运行此工具的平台上,无需 C 编译器即可进行裸安装。在 64 位机器上(x86-64 和 aarch64/arm64,包括 64 位 Raspberry Pi OS),sigwood 会从纯 wheel 包安装 `fast-hdbscan`; 在 32 位 ARM(armv7l/armv6l)上,它会从 piwheels 保留标准的 `hdbscan`。该 工具在每次包含 dns 检测器的运行中都会指明当前启用的聚类后端。预计在小型机器上的*第一*次 运行会很慢:科学计算栈的冷导入加上一次性的 numba JIT 预热在 Raspberry Pi 上可能需要几分钟的时间,这两者都会缓存在磁盘上 - 之后的每次 运行都会很快。`[fast]` 依然是强制使用 `fast-hdbscan` 的稳定方式,而 `[hdbscan]` 会安装标准的 `hdbscan`(用于 32 位 ARM,并可在 64 位上进行校准/测试)。 如果同时存在这两个后端,sigwood 会优先选择 `fast-hdbscan`。 `[pdf]` 特意与 `[all]` 分开,因为它需要两样东西:python 包 (`pip install 'sigwood[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/sigwood cd sigwood python3 -m venv .venv # Python 3.11+ .venv/bin/pip install -e '.[all]' ``` ## 配置配置是可选的 - sigwood 无需任何配置即可针对路径运行。当你想让操作 可重复时,`sigwood init` 会查看你机器上的常规位置,分析它 找到的内容(哪些日志家族、大致大小、新鲜度 - 仅读取文件的足够部分以识别其格式,绝不读取其内容), 并在 `~/.sigwood/`(如果是系统级安装,则为 `/etc/sigwood`)下写入一个带有注释的 配置。你可以随时重新运行它:它会提议合并到现有配置中(每个提示都会显示 你已经设置了什么 - 按 Enter 键保留;合并操作永远不会破坏你已经 拥有的设置)或重置它,并且无论哪种方式,它都会在写入之前 显示将要更改的内容摘要。 配置会从以下位置中的第一个加载: 1. `--config=FILE` 2. `~/.sigwood/config.toml` 3. `/etc/sigwood/config.toml` sigwood 拥有的一切都位于隐藏的 `~/.sigwood/` 目录下 - 配置、白名单、 导出、报告 - 因此它不会与项目目录发生冲突。一个精简的示例: ``` [sigwood] 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 = "7d" # lookback for a directory; "" or "all" = full output_format = "text" # text | json | csv | html | pdf ``` 默认情况下,发现结果会打印到你的终端 - 保持其可通过管道传输。设置 `report_dir`(或传入 `--out=PATH`)以写入报告文件。检测器暴露的每个可调参数都作为注释掉的“机房”记录在 生成配置的底部(你极少需要用到它),并且 `sigwood --help` 会列出该命令的标志。 ## 支持的日志来源 - **Zeek** - `conn.log`、`dns.log`、`syslog.log`,NDJSON 或 TSV 格式,来自扁平目录或 按日期分区的子目录。轮转和 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** - gzip 压缩的 JSON 事件记录,在本地读取或从 S3 拉取(见下文)。 ## 白名单 sigwood 在分析**之前**进行过滤:已知的无害流量会在任何 检测器看到它之前被丢弃,因此信号不会被日常基础流量淹没。白名单文件有两种类型: - **扁平文件 = 抑制。** 每行一个规则 - IP、CIDR、`:port/proto` 或 域名 glob/正则表达式。匹配的流量会在任何检测器运行之前被丢弃。 - **TOML 配置段 = 分类。** 当检测器需要知道某个东西*是什么* (DNS 服务器、备份客户端)而不是是否要丢弃它时使用。 sigwood 附带三个精选的**域名**列表,可通过名称切换: | 列表 | 默认 | 覆盖范围 | |------|---------|--------| | `common` | 开启 | 广泛的互联网基础设施 - CDN、云、NTP、证书验证、公共 DNS、操作系统更新通道 | | `devices` | 开启 | 消费级 IoT / 智能家居主机的对外通信 | | `homelab` | 关闭 | 自托管工具(Splunk、Proxmox、UniFi 等) - 需主动开启,因为屏蔽你正在运行的产品会造成真正的盲点 | 不包含任何广告、跟踪或特定于目的地的内容 - 因为各人看法不同,你可能希望看到 这些内容。sigwood 绝不附带数字连接抑制规则(这些取决于你的主机, 附带它们可能会隐藏真实的发现)。 使用 `allowlist` 命令检查和管理它: ``` sigwood allowlist # what's loaded, each list's on/off state and size sigwood allowlist show common # the patterns in a list sigwood allowlist enable homelab # turn a shipped list on (writes [allowlist.lists]) sigwood allowlist disable common # …or off sigwood allowlist copy common # fork a shipped list into your allowlist.d to edit ``` 开关也可以直接在配置的 `[allowlist.lists]` 下设置;对于单次运行,可以使用 `--no-allowlist` 关闭整个白名单,或者通过 `enabled = false` 永久关闭。每次检测 运行都会在运行摘要横幅中披露其覆盖情况(`allowlist: suppressed 1,284 connections (12%) and 312 domains (59%)` - 被抑制的已加载行(按类型)占比,因此 惊人的抑制率可以一目了然),所以抑制操作永远不是静默的。 在 `~/.sigwood/allowlist.d/` 下的任何 `domains_*` 文件中添加你自己的列表(附带的 `domains_user` 是一个入门文件)。插入文件始终是**附加的**,并在升级后保留;要 替换附带的列表,请将其 `disable` 并添加你自己的。插入文件不带有扩展名,因此像 `domains_user.bak` 这样带有点的副本将不会被加载(读取输出会提示你重命名它);要安静地 搁置废弃的列表,请添加尾部 `~` 或去掉 `domains_`/`connections_` 前缀。格式错误的正则表达式行会被跳过,并 提示指明其文件和行号,而不会导致崩溃,因此一个拼写错误不能 使一次运行崩溃或静默地禁用列表的其余部分。没有端点的纯主机 IP 会抑制 涉及该主机的*所有*流量 - 功能强大但很危险,无论在 哪里出现都会被明确指出。 ## 导入日志:导出器 sigwood 可以从外部系统获取日志到本地文件,然后它会像 分析任何其他源一样对其进行分析 - syslog 检测器无法分辨数据是来自 rsyslog 还是 Splunk 导出。 ``` sigwood export splunk # run the configured "default" query sigwood export splunk auth # run the configured named query: "auth" sigwood export cloudtrail # pull logs from S3 ``` - **Splunk** - `[export.splunk.query.]` 下命名的 SPL 查询。首选 使用 `SIGWOOD_SPLUNK_USER` / `SIGWOOD_SPLUNK_PASS` 环境变量,而不是 在配置中使用明文凭据,但 sigwood 不会评判你。 - **CloudTrail** - 从 S3 前缀拉取 gzip 压缩的 JSON。AWS 身份验证在此处*不*进行 处理:你需要验证你的 shell 身份,然后由 boto3 解析环境凭据链。 sigwood 绝不会读取、存储或提示输入 AWS 凭据,并会在大量 数据传出前发出警告。 ## 输出格式 根据你对发现结果的处理方式来选择 - `--format=NAME`(或在配置中设置 `output_format`): - **`text`**(默认) - 针对终端的分组、汇总报告,带有每个检测器 的表格,显示每个发现背后的信号。 - **`html`** - 相同的报告,带有相同的每个检测器的信号表格,作为一个自包含的 带样式文件,你可以将其在浏览器中打开、打印或分享。无需额外依赖;包含深色模式和 打印样式。 - **`pdf`** - 将 html 报告渲染成 PDF(一个渲染器,两种输出)。可选开启: `pip install 'sigwood[pdf]'`,加上本地文本库(Pango/HarfBuzz/fontconfig - 参见上方的安装说明)。宽报告会横向打印,宽单元格会换行而不是被裁剪。 - **`json`** - 无损的机器数据流:带有 `run_summary` 和 `findings` 的单个对象, 类型正确,适合 `jq` 或 SIEM,始终包含完整集合。包含 `schema_version`。 - **`csv`** - 补救工作清单:每个发现占一行,包含后续步骤、“原因”, 以及空的 `status`/`notes` 列,方便你在处理项目时进行追踪。 `text`、`html` 和 `pdf` 是阅读视图 - 它们显示相同的内容,并遵循 `-v`(精选的 “为什么这样评分”)和 `-vv`(原始调试:模板字符串、聚类成员资格、完整 证据)。`json` 和 `csv` 始终携带完整集合。 **输出去向。** 每种文本格式 - 包括 `html` - 默认情况下都会打印到标准输出;重定向 或使用管道进行保存(`sigwood dns -f=html > report.html`)。`pdf` 是二进制格式,因此它需要 一个目的地:管道(`-f=pdf > report.pdf`)或文件。设置 `--out=PATH` 或 `report_dir` 来写入 文件;目录目标会自动命名为 `sigwood-report__`(单个检测器,否则 为 `-plusN`)并报告其写入的路径。即使设置了 `report_dir`,`-o=-` 也会 强制输出到标准输出。 ## 从源码构建并运行测试 ``` git clone https://github.com/helixmap/sigwood cd sigwood python3 -m venv .venv # Python 3.11+ .venv/bin/pip install -e '.[dev]' .venv/bin/python -m pytest ``` `main` 分支保持可运行状态。架构测试涵盖了重要的边界 - 检测器 发现、运行计划、加载器元数据、白名单抑制、输出注册和 CLI 错误格式化。 ## 致谢 sigwood 基于数学的检测 - 用于 beacon 周期性的 FFT,用于 DNS 行为的无监督聚类 - 灵感来自 David Hoelzer 的 SANS SEC595。这些技术本身(FFT、 HDBSCAN、drain3)属于公共领域的数学和开源库;此实现 是独立且原创的,任何错误均由本人承担。sigwood 不隶属于 SANS 或 GIAC,也未得到它们的认可。 ## 许可证 sigwood 采用 [MIT 许可证](https://github.com/helixmap/sigwood/blob/main/LICENSE) 授权。
标签:Blue Team, IP 地址批量处理, Python, 安全, 插件系统, 无后门, 聊天机器人, 超时处理, 逆向工具