cray44/detection-validator

GitHub: cray44/detection-validator

一个用于对 Sigma 检测规则进行离线单元测试的验证工具,通过配对的 JSON 样本确保检测逻辑的准确无误并减少误报。

Stars: 0 | Forks: 0

# detection-validator 针对配对的 JSON 测试样本验证 Sigma 检测规则 —— 无需 Splunk。 给定一个 Sigma 规则和两个 JSON 文件(恶意事件,良性事件),它会断言: - **至少一个恶意事件匹配** 检测逻辑 - **零个良性事件匹配** 检测逻辑 每次规则检查时也会通过 [sigma-to-spl](https://github.com/cray44/sigma-to-spl) 进行转换:如果规则转换失败或产生 `MANUAL:` 警告,这些信息会显示在输出中。 ## 安装 ``` pip install -e . # 转换检查也必须安装 sigma-to-spl pip install -e ../sigma-to-spl ``` ## 用法 ``` # 测试所有规则,自动发现 validator.yml 和 test-data 路径 detection-validator test rules/ # 测试单个规则 detection-validator test rules/network/dns-tunneling-high-entropy-subdomains.yml # 显式 sigma-to-spl 配置 (Corelight/Zeek 字段映射) detection-validator test rules/ --config config/corelight.yml # 显式 test-data 目录(仅限单个规则) detection-validator test rules/network/dns-tunneling.yml --test-data ../detection-notes/detections/network/dns/test-data/ # 显式 validator.yml(覆盖自动发现) detection-validator test rules/ --mappings config/validator.yml ``` ## 输出 ``` PASS network/dns-tunneling-high-entropy-subdomains conversion: clean malicious: 3/4 matched benign: 0/5 matched WARN network/statistical-beaconing-zeek-conn-log conversion: clean manual: MANUAL: rule has SPL-only additions not expressible in Sigma — see detection writeup malicious: 10/10 matched benign: 6/12 matched benign FPs: 6/12 — SPL additions handle these SKIP identity/oauth-device-code-phishing-sigmahq no test-data directory FAIL windows/some-rule malicious: 0/3 matched <- detection gap 10/11 passed 1 skipped 0 failed ``` 退出码:`0` = 全部通过/警告/跳过,`1` = 任何失败或错误,`2` = 配置错误。 ## 状态码 | 状态 | 含义 | |--------|---------| | `PASS` | 转换无误,恶意事件匹配,无良性事件匹配 | | `WARN` | 断言通过,但规则带有 `MANUAL:` 警告(SPL 添加了超出 Sigma 表达范围的过滤) —— 预期会产生良性误报 | | `SKIP` | 未配置测试数据,或需要时间窗口的聚合条件 | | `FAIL` | 检测遗漏(未匹配到恶意事件),纯净规则上出现误报,或转换错误 | | `ERROR` | YAML 解析失败或样本加载失败 | `WARN` 不是 CI 失败。检测遗漏总会导致失败,与 `MANUAL:` 状态无关。 ## 工作原理 ### Sigma 原生评估 评估器直接作用于 Sigma 的检测 YAML —— 而不是 SPL 输出。这使其无需依赖特定基础设施,并且测试的是数据源真实面貌,而非派生产物。 检测块被解析为条件 AST(抽象语法树)(递归下降解析器处理 `and`、`or`、`not`、`1 of`、`all of`)。每个命名选择块使用规则中的字段修饰符对事件进行评估: | 修饰符 | 行为 | |----------|----------| | *(无)* | 不区分大小写的相等匹配;`*` 作为值时 = 字段存在且具有任意值 | | `|contains` | 子字符串匹配 | | `|startswith` | 前缀匹配 | | `|endswith` | 后缀匹配 | | `|contains|all` | 所有值必须出现在字段中 (AND) | | `|cidr` | 通过 Python `ipaddress` 进行 IP/子网成员关系匹配 | | `|fieldref` | 将字段值与同一事件中另一个字段的值进行比较 | | `|re` | 正则表达式匹配 | **字段解析** 首先使用字面键查找(如 `id.orig_h` 这类的 Zeek 扁平字段),然后回退到嵌套字典遍历(如 `DeviceDetail.isCompliant` 这类的 Azure 结构化字段)。这能正确处理这两种日志格式,而无需特殊用例处理。 ### 转换检查 在评估之前,每条规则都会通过 sigma-to-spl 的 `Converter` 运行。有两种结果会标记一条规则: - **转换错误** → 状态为 `FAIL` 并附带异常消息 - **输出中包含 `MANUAL:`** → 规则被标记为宽松评估(误报将变为 `WARN` 而不是 `FAIL`) `MANUAL:` 警告由 sigma-to-spl 的 `PostProcessor` 在以下两种情况下发出: 1. 规则的 logsource category 为 `dns`(需要熵评分) 2. 原始规则 YAML 包含 `# NOTE:` 注释(内联记录了仅限 SPL 的逻辑) 使用 `# NOTE:` 记录仅限 SPL 新增内容的规则在 Sigma 层级上被视为有意放宽 —— 它们的误报是预期之中的,并由 SPL 进行处理。 ### 无法测试的内容 - **聚合条件** —— 使用 `count by`、`stats`、`streamstats` 的规则需要时间窗口,会被自动跳过 - **仅限 SPL 的过滤** —— 风险评分、基于查找的抑制、`eval`/`rex` 转换;这些由 `MANUAL:` / `WARN` 路径覆盖 - **字段提取** —— 由 PostProcessor 应用的转换(索引路由、宏替换)不会反映在 Sigma 条件中 ## 测试数据格式 每项检测需要在文章旁边有两个 JSON 文件: ``` test-data/ malicious-sample.json # events the rule MUST match (≥1 required) benign-sample.json # events the rule MUST NOT match (0 allowed, unless MANUAL:) ``` 文件可以包含单个 JSON 对象或 JSON 数组。请随意使用 `_comment` 键 —— 评估器会忽略未知字段。Sigma 规则合法触发但被 SPL 抑制的事件(已知误报)仅当规则带有 `# NOTE:` / `MANUAL:` 标记时才属于 `benign-sample.json`。 ## 规则 → 测试数据映射 该工具从规则目录向上遍历以自动发现 `config/validator.yml`。该配置将规则标识符映射到测试数据路径: ``` rules: network/dns-tunneling-high-entropy-subdomains: test_data: ../../detection-notes/detections/network/dns/test-data # Intentionally excluded (upstream mirror — no local test data) identity/oauth-device-code-phishing-sigmahq: test_data: ``` 路径相对于 `validator.yml` 进行解析。具有 `test_data: null` 的规则被视为明确排除(不会被覆盖率检查标记为缺失)。 ## CI 集成 在 `sigma-to-spl` 的 GitHub Actions 工作流中,`validate` 作业将检出所有三个代码库作为同级目录,以便 `validator.yml` 中的相对路径解析与本地开发保持一致: ``` $GITHUB_WORKSPACE/ sigma-to-spl/ ← main checkout (rules, config) detection-notes/ ← test-data source detection-validator/← tool ``` `validate` 作业在 `convert` 作业之后运行,并作为 PR 的门禁。检测断言失败将阻止合并。 ## 设计决策 **为什么选择 Sigma 原生评估而不是 SPL 评估?** pySigma 是一个编译器,而不是运行时 —— 它没有内置的“此事件是否匹配此规则?”函数。编写一个 SPL 子集评估器将测试派生产物(转换输出),而不是数据源真实面貌。Sigma 条件是工程师编写的逻辑;这才是应该被测试的内容。 **为什么对 MANUAL: 规则使用 WARN 而不是跳过?** 跳过会掩盖检测遗漏。带有 SPL 新增内容的规则仍然需要在 Sigma 层级触发恶意事件 —— SPL 只是 *增加* 了对误报的过滤。WARN 确认了基础检测在运行,同时承认由 SPL 处理精度问题。 **为什么使用 `# NOTE:` 约定?** pySigma 在解析期间会剥离 YAML 注释,因此没有其他方法可以从规则元数据中传达“此规则有意不完整”。检测块中的 `# NOTE:` 是一种可见且轻量级的信号,为检测作者和工具都提供了上下文。
标签:AMSI绕过, Homebrew安装, JSON测试, Maven, Python, Rootkit, Sigma-to-SPL, Sigma规则, URL发现, Zeek, 威胁检测, 安全检测, 无后门, 漏洞验证, 目标导入, 网络安全, 自动化payload嵌入, 规则验证, 误报测试, 逆向工具, 隐私保护