SecurityRonin/segb-forensic

GitHub: SecurityRonin/segb-forensic

Rust 实现的 Apple SEGB(Biome)取证分析器,解码 macOS/iOS 用户活动流记录并标记 CRC 不匹配、时间戳异常等分级取证发现。

Stars: 0 | Forks: 0

# segb-forensic [![segb-core](https://img.shields.io/crates/v/segb-core.svg?label=segb-core)](https://crates.io/crates/segb-core) [![segb-forensic](https://img.shields.io/crates/v/segb-forensic.svg?label=segb-forensic)](https://crates.io/crates/segb-forensic) [![Docs.rs](https://img.shields.io/docsrs/segb-core?label=docs.rs)](https://docs.rs/segb-core) [![Rust 1.81+](https://img.shields.io/badge/rust-1.81%2B-orange.svg)](https://www.rust-lang.org) [![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](LICENSE) [![Sponsor](https://img.shields.io/badge/sponsor-h4x0r-ea4aaa?logo=github-sponsors)](https://github.com/sponsors/h4x0r) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/4d1821e86f145311.svg)](https://github.com/SecurityRonin/segb-forensic/actions/workflows/ci.yml) [![Coverage](https://img.shields.io/badge/coverage-100%25%20lines-brightgreen.svg)](https://github.com/SecurityRonin/segb-forensic/actions/workflows/ci.yml) [![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/) [![Security advisories](https://img.shields.io/badge/security-cargo--deny-informational.svg)](deny.toml) **适用于 Rust 的 Apple SEGB (Biome) 取证工具 —— 一个无 panic 的读取器,用于解码 macOS/iOS 用户活动流中带有状态标签和 CRC 保护的记录;同时也是一个分级异常分析器,用于标记出常规读取容易遗漏的 CRC 不匹配、时间戳乱序或缺失等问题。** SEGB 是 **Biome** 子系统在 macOS 和 iOS 上用于记录用户活动的容器 —— 包括 Safari 历史记录事件、应用启动、微观位置访问、`App.MenuItem` 选择流等等。每个流都是一个按追加顺序记录的日志,其中包含状态标志、一两个时间戳以及原始 protobuf 负载。包含在同一个工作区下的两个 crate: - **[`segb-core`](https://crates.io/crates/segb-core)** —— 读取器:自动检测 SEGB **v1** 和 **v2** 版本,解码每一条记录(状态、Cocoa 转 Unix 时间戳、负载、存储与计算的 CRC-32 对比),并提供了一个极简的 protobuf 字段遍历器以及 `App.MenuItem` 解码器,支持任何 `Read + Seek` 源。没有 `unsafe`,也没有 C 绑定。 - **[`segb-forensic`](https://crates.io/crates/segb-forensic)** —— 分析器:将这些记录转化为严重性分级的 [`forensicnomicon::report::Finding`](https://crates.io/crates/forensicnomicon),使得 Biome 流的异常能够与其他所有工件层保持统一的聚合标准。 ## 30 秒审计 SEGB 流 ``` [dependencies] segb-forensic = "0.1" # pulls in segb-core ``` ``` use std::io::Cursor; use forensicnomicon::report::{Observation, Source}; let records = segb::read_segb(&mut Cursor::new(bytes))?; let src = Source { analyzer: "segb-forensic".into(), scope: "SEGB".into(), version: None }; for anomaly in segb_forensic::audit(&records) { // each Anomaly -> a canonical forensicnomicon Finding let finding = anomaly.to_finding(src.clone()); println!("{} ({:?}): {}", finding.code, finding.severity, finding.note); } # Ok::<(), segb::SegbError>(()) ``` ### 异常代码 SEGB 流是按追加顺序记录的状态标签化、受 CRC 保护的日志 —— 这种结构使得一小部分篡改/损坏信号变得极其精确。 | 代码 | 严重性 | 含义 | |---|---|---| | `SEGB-CRC-MISMATCH` | 高 | `Written` 记录的负载 CRC-32 ≠ 存储的 CRC —— 意味着数据损坏或写入后篡改 | | `SEGB-TIMESTAMP-OUT-OF-ORDER` | 中 | `Written` 记录的时间戳早于前一条记录 —— 追加顺序被打破(时钟更改 / 重新排序) | | `SEGB-TIMESTAMP-MISSING` | 低 | 没有有效时间戳的 `Written` 记录 | 检查发现仅适用于 **`Written`**(存活)记录。`Deleted`/`Unknown` 记录是 Biome 追加日志的正常生命周期部分 —— 它们的负载已被擦除,因此在结构上其 CRC 必然是不匹配的;参考实现 ccl-segb 仅验证 `Written` 记录的 CRC,我们也是如此(在真实的良性流中零误报)。 检查发现仅仅是**观察结果,绝非最终结论** —— 结论由分析师做出。 ## 只需要读取器? `segb-core` 可以独立使用。无需引入分析器即可解码每一条记录并遍历 `App.MenuItem` 负载: ``` [dependencies] segb-core = "0.1" ``` ``` use std::fs::File; use std::io::BufReader; use segb::{read_segb, menuitem::decode_app_menu_item}; let f = File::open("/path/to/App.MenuItem/local")?; let mut r = BufReader::new(f); for record in read_segb(&mut r)? { let item = decode_app_menu_item(record.payload(), record.timestamp_unix())?; println!("{:?} selected {:?}", item.application, item.menu_item); } # Ok::<(), segb::SegbError>(()) ``` `read_segb()` 会倒回流并自动检测版本变体: | 变体 | 魔数位置 | 文件头 | 对齐方式 | |---------|----------------|--------|-----------| | SEGB v1 | 56 字节文件头的最后 4 字节 | 56 字节 | 8 字节 | | SEGB v2 | 32 字节文件头的前 4 字节 | 32 字节 | 4 字节 | ## 双 crate 拆分设计 | Crate | 角色 | 依赖于 | 输出 | |---|---|---|---| | [`segb-core`](https://crates.io/crates/segb-core) | 读取器 / 解码器 | `thiserror` | `SegbRecord` (状态、时间戳、负载、CRC) | | [`segb-forensic`](https://crates.io/crates/segb-forensic) | 异常分析器 | `segb-core`, `forensicnomicon` | 分级的 `Finding` | 读取器保持纯粹 —— 它只负责解码字节,不作任何主观判断。所有的*取证含义*都存在于分析器中,它是一个对已解码记录进行无副作用处理的函数。这种分离设计使得 `segb-core` 可以独立发挥作用,同时也让 `segb-forensic` 能够直接无缝插入到整个集群的 `Report` 中,与其他所有分析器并列。 ## 信任但要验证 SEGB 文件属于不可信、可被攻击者控制的输入,因此这些 crate 在构建时就进行了安全加固: - 整个工作区全面启用 **`#![forbid(unsafe_code)]`** —— 在任何地方都没有 `unsafe`。 - **无 panic** —— 每个长度、偏移量、尾部条目和 protobuf varint 在使用前都经过了边界检查;精心构造的长度字段无法引发越界读取或内存分配炸弹。格式错误的输入会以具名 `SegbError` 的形式呈现,绝不会发生静默失败并使用默认值的情况。 - **经过模糊测试** —— `cargo-fuzz` 目标覆盖了 v1 和 v2 容器、protobuf 遍历器、`App.MenuItem` 解码器以及完整的 `read_segb` → `audit` 管道;其不变式原则是“绝不 panic”。 - **基于真实 Apple 数据验证** —— Josh Hickman 公开的 iOS 17.3 镜像中的每一个 SEGB 文件(139 个 v1 + 262 个 v2 = **401 个文件**)都与 [`ccl-segb`](https://github.com/cclgroupltd/ccl-segb) 参考标准实现记录级完美对齐:**401 通过 / 0 不匹配**。详见 [`docs/validation.md`](docs/validation.md)。 ## 参考文献 - **ccl-segb** (Alex Caithness / CCL Solutions) —— 字节布局参考标准: - **Unit 42 研究** (Palo Alto Networks, 2026): [隐私政策](https://securityronin.github.io/segb-forensic/privacy/) · [服务条款](https://securityronin.github.io/segb-forensic/terms/) · © 2026 Security Ronin Ltd
标签:Apple Biome, iOS, Rust, 代码示例, 可视化界面, 异常检测, 数字取证, 数据分析, 网络流量审计, 自动化脚本, 通知系统