bwhitn/sspry

GitHub: bwhitn/sspry

基于多层布隆过滤器的可扩展 YARA 规则预过滤系统,用于在大规模文件集合中快速缩小待扫描候选集,降低全量 YARA 扫描的开销。

Stars: 0 | Forks: 0

# YARA 的可扩展筛查与规则预过滤 (SSPRY) `sspry` 是命令行二进制文件和 crate 的名称。 一个支持快速候选检索和可选 YARA 验证的可变文件搜索数据库。 ## 概述 SSPRY 是一种可扩展的解决方案,旨在根据您打算使用的 YARA 规则来减少需要扫描的文件集。公共搜索路径支持单规则查找以及通过常规 `include "..."` 指令从单个顶级 YARA 文件加载的小型捆绑规则集。它旨在避免漏报并控制误报数量。其他项目也做过类似的事情,但本项目的目标是以一种可扩展的方式来实现,通过牺牲前期处理来换取更低的内存占用和搜索处理开销,同时保持整体数据库 (Forest) 的大小小于文件总和;然而,它在搜索期间会产生大量的磁盘 I/O。除此之外,数据库还需要支持项目的插入和删除操作。 ## 术语 候选 - 作为可能匹配项返回的单个文档,由其 Source ID 标识。
文档 - 一个包含 Tier 1 布隆过滤器、Tier 2 布隆过滤器和元数据附属文件的单个文件。
文档 ID - 插入时分配的数字 ID。该值仅限于存储它的 Tree/shard 本地有效。
Forest - 由一个 SSPRY 实例或本地 forest 根目录管理的一组 Trees 集合。
元数据附属文件 - 元数据包含可以在搜索期间检查的 YARA 相关值的子集。
Shard - Tree 内部的一个分区,用于分散摄入/写入工作并限制分片本地文件的大小。
Source ID - 配置的文件身份哈希,用于插入去重、删除、搜索身份匹配和全局 Forest 范围去重。支持的模式有 MD5、SHA1、SHA256 和 SHA512。
Tier 1 布隆过滤器 - 首先使用的较宽泛的过滤器,用于拦截部分 Tier 2 读取并帮助提高准确性。
Tier 2 布隆过滤器 - 使用更精确的过滤器进一步缩小候选集范围。
Tree - 包含多个 Shards 的单个逻辑存储单元。 ## 通用方法论 通用方法论涉及一个操作方式类似于日志结构合并树 (LSM Tree) 的 Forest。基本思想是通过发布例程追加新项目,并通过压缩例程延迟执行删除操作。整体格式实际上并不是一个树 (Tree),而是一组在物理上拆分的长数据流(一个森林 forest)。每个文件由一个 Tier 1 (T1) 和一个 Tier 2 (T2) 布隆过滤器组成,默认情况下,它们分别是 3-gram 和 4-gram 布隆过滤器,以及一个包含 YARA 特定信息的可选元数据附属文件(例如 pe.is_pe、用于 math.entropy(0, filesize) 的文件熵等)。T1 是一个较轻量的布隆过滤器,它将拦截部分必需的 T2 布隆过滤器读取,并略微减少误报。T2 是一个更精确的布隆过滤器,具有低得多的误报率。支持的 gram 大小对包括 `3,4`、`4,5`、`5,6` 和 `7,8`。布隆过滤器的大小基于误报 值 p 和近似的 ngram 数量进行计算,该数量是通过对所有 gram 应用 HyperLogLog 函数得出的,其结果通常在 1% 的准确度范围内。 这些 forest 被划分为多个 Tree,每个 Tree 具有固定的最大文档数量,并且每个 Tree 进一步被划分为多个 Shard。每个 shard 包含搜索所需的数据,包括 T1 和 T2 布隆过滤器,以及元数据附属文件。进行这些拆分是为了防止文件过大。当文件被移除时,它会立即被标记,但直到压缩完成后才会被物理移除。压缩操作会重建一个 shard,然后将其替换掉前一个 shard。另一方面,索引是通过发布完成的,这会追加到活动的 shard 集中。 在基于 Source ID 的插入操作中,同一 Tree 内可以防止重复检测。在不同的 Tree 之间仍然可能存在重复。在空闲维护期间,服务器会构建按 Tree 排序的 Source ID 引用文件,并在插入了足够数量的新文档后运行一次全局 Forest 范围的去重遍历。该遍历会保留最旧的 Tree 条目,并从较新的 Tree 中删除重复项。客户端在搜索期间也会对匹配项进行去重。 大多数基于布隆过滤器的搜索会读取正在被搜索的 Tree 中的 T1 布隆过滤器。可能的 T1 匹配项随后可能需要 T2 读取和元数据检查。如果规则没有可搜索的字符串锚点,则可能会根据规则结构回退到元数据检查、直接身份查找或后续验证。这方面的一个例子可能是类似“filesize < 4kb and pe.is_pe and pe.timestamp > time.now”的条件,该条件可以找到小于 4kb 且时间戳大于搜索开始时间的 PE 文件。 ## 程序架构 程序架构主要是客户端-服务器模式。在摄入期间,客户端扫描文件并将每个文档的布隆过滤器和元数据行发送到服务器。在搜索期间,客户端发送经验证的 YARA 源,服务器负责处理搜索规划、磁盘 I/O 和候选检索。唯一的例外是直接本地路径,在这种情况下,`local search` 会在进程内打开一个 forest。一点快速提示:由于这些是客户端和服务器,并且没有任何内置的安全性,因此建议将它们部署在封闭的网络中。 此外,如果您在创建 Forest 时选择存储路径信息,您可以使用它自动验证搜索结果。 客户端还可以通过将逗号分隔的地址传递给 `--addr` 来在多个服务器之间分配工作。多服务器索引会在命令启动时检查一次服务器信息,验证兼容的数据库策略,并将每个完成的上传批发送到当前文档计数最低的服务器。多服务器搜索会扇出到所有可达的服务器,并在应用最终上限之前对返回的 Source ID 进行去重。多服务器删除会扇出到所有可达的服务器,因为文档可能仅存在于一个服务器上。因此,除非执行验证的系统仍然可以访问原始文件,否则内置验证会变得更加困难。 ## 通用操作复杂度 * 搜索的复杂度通常与服务器必须检查的数据量呈线性关系。 * 服务器端索引以追加为导向,并且大部分是顺序的。对于典型的批量大小,每个文档的服务器工作量大致有界,但它仍随着写入数据量的增加而线性增长。客户端索引的规模随文件大小、唯一 n-gram 数量以及元数据提取工作量而变化。 * 移除操作在前期通常开销很低,而较重的清理工作会延迟到压缩期间进行。 * 所有这些都取决于配置的布隆过滤器大小,以及发布和压缩带来的一般偶尔开销。 ## 一般说明 * 这种预 YARA 搜索筛查方法存在许多权衡。对于 T1,如果 p(误报)率设置得过低,布隆过滤器会变大,因此搜索所需的最低磁盘 IO 量将会增加。T2 也是如此,但程度更深:ngram 大小越大,唯一 ngram 就越多。虽然一些 YARA 模块和常见条件评估存储在元数据中,但存储所有元数据将大幅增加 Forest 的大小。 * 这仍处于早期开发阶段,需要进行许多改进。这些改进可能会破坏某些内容,导致当前的 Forest 无法使用并需要将其删除和重建。 * 尝试将其与类似项目进行比较并不容易。制作一个功能对比表可能会更容易些。 * 在 YARA 规则中使用“time.now”时,有可能出现漏报,因为搜索在它开始时对其进行了评估,而验证发生在稍后,在此期间会再次对其进行评估。 ## 当前问题 * 多服务器模式在索引、删除、搜索和信息查询方面已经具备功能,但它仍然是一个操作简单的客户端扇出模型,而不是一个协调的集群。 * 全局 Forest 范围的去重运行在空闲维护期间,因此在达到维护阈值并完成去重遍历之前,重复的 Source ID 可能会暂时存在。 * 该项目仍处于早期开发阶段;数据库格式的更改可能需要重建现有的 Forest。 ## 快速链接 - [快速入门](docs/quickstart.md) - [使用说明](docs/usage.md) - [具体实现](docs/implementation.md) ## 构建 ``` cargo build cargo build --release ``` ## 测试 ``` ./scripts/naming_audit.sh cargo test --workspace --all-targets ``` ## 覆盖率 如果已安装 `cargo-llvm-cov`: ``` ./scripts/coverage.sh ``` ## 性能基准测试 对于带有 CPU 和匿名内存采样的服务器端搜索基准测试: ``` ./scripts/server_search_bench.sh \ --root ./candidate_db \ --addr 127.0.0.1:18663 \ --out ./results/bench_runtime_workers6 \ --mode-label runtime \ --search-workers 6 \ --rule-list /path/to/rules.list \ --bundle-rule /path/to/bundle_10rules.yar ``` 基准测试辅助工具会记录: - 每阶段的客户端耗时、用户 CPU、系统 CPU、CPU 平均使用率和最大 RSS - 每阶段的服务器 CPU 时间和 CPU 平均使用率 - 峰值 `VmRSS`、`RssAnon`、`VmSwap`、`Pss_Anon`、`Private_Clean` 和 `Private_Dirty` - 位于 `server_samples.tsv` 中的原始带时间戳的 `/proc` 采样 `--bundle-rule` 应指向一个顶级 YARA 文件,通常是一个展开为您希望捆绑到一个远程 `search` 请求中的规则集的包含文件。在需要时使用 `--server-extra-arg` 和 `--search-extra-arg` 转发额外的服务/搜索标志。
标签:HTTP工具, PE 加载器, Rust, YARA, 云资产可视化, 信息检索, 候选检索, 分层过滤, 可扩展性, 可视化界面, 后端开发, 哈希校验, 安全扫描, 布隆过滤器, 性能优化, 搜索引擎, 数据去重, 数据库, 数据泄露, 文件搜索, 无线安全, 时序注入, 检测绕过, 网络安全审计, 网络流量审计, 规则预过滤