[](https://crates.io/crates/forensicnomicon)
[](https://docs.rs/forensicnomicon)
[](https://github.com/SecurityRonin/forensicnomicon/actions/workflows/ci.yml)
[](LICENSE)
[](https://www.rust-lang.org)
[](https://github.com/sponsors/h4x0r)
## DFIR 知识即代码
MITRE ATT&CK、LOLBAS 和 LOLDrivers 是供你*浏览*的参考资料。**Forensicnomicon 是编译为代码的 DFIR 知识** —— 每一个 LOLBin、BYOVD 易受攻击驱动程序、取证工件和攻击指标,都作为零依赖的 Rust 库和离线二进制文件,无需浏览器和网络即可在几毫秒内查询。
**6,554 个取证工件。每一个都经过了丰富化。**
你正处于一次活跃的 IR(事件响应)中。你现在就需要知道某个二进制文件是否可被滥用,而且是离线、不开浏览器的状态。
```
brew install SecurityRonin/tap/4n6query
# 或:cargo install forensicnomicon-cli
4n6query certutil.exe # LOLBin lookup, ATT&CK techniques, use cases
4n6query userassist # 5 artifact variants, decoded field schemas, triage priority
4n6query T1547.001 # all artifacts mapped to this technique
4n6query --triage # Critical artifacts to collect first, RFC 3227 order
```
正在用 Rust 构建 DFIR 工具?同样的数据就是一个零依赖的库:
```
[dependencies]
forensicnomicon = "1" # facade: stable engine + the full catalog, one import
```
正在构建检测 pipeline 或 `*-forensic` 分析器?请依赖于**稳定的引擎** —— [`forensicnomicon-core`](https://crates.io/crates/forensicnomicon-core)(`report` 模型、目录类型和查找引擎)保持不变,而 [`forensicnomicon-data`](https://crates.io/crates/forensicnomicon-data) 中的知识(6,554 个描述符 + IOC/MITRE 表)在它底层更新 —— 因此目录变更永远不会迫使你的 crate 重新发布。
## 它有何不同
MITRE ATT&CK 和 lolbas-project.github.io 是浏览器参考资料。而这是**知识即代码** —— 一个二进制文件。
- **离线。** 所有 6,554 个工件都编译进二进制文件中。运行时零 I/O,零网络调用。
- **丰富化。** 不仅仅是工件存在于何处 —— 还包括如何解码它、证据有多强、需要同时收集什么,以及哪些 KAPE 目标和 Velociraptor 工件可以收集它。
- **统一了所有六个 LOL/LOFL 数据集。** LOLBAS、GTFOBins、LOOBins、LOFL cmdlet、LOFL MMC 管理单元、LOFL WMI 类。一次查找,一个 API。
## LOL + LOFL —— 六个数据集,一次查找
LOL(Living Off the Land)是对操作系统自带二进制文件的滥用。LOFL(Living Off Foreign Land)是对企业端点上常见的第三方管理工具的滥用:云 CLI、容器 runtime、Sysinternals、语言 runtime。两者在进程遥测和 EDR 警报中的表现完全相同。将它们统一在一个查找中可以减少遗漏的检测。
| 常量 | 条目数 | 来源 |
|----------|---------|--------|
| `LOLBAS_WINDOWS` | 187 | [LOLBAS Project](https://lolbas-project.github.io/) + [LOFL Project](https://lofl-project.github.io/) |
| `LOLBAS_MACOS` | 139 | [LOOBins](https://loobins.io/)(约 61 个原生)+ [macOS LOFL 目录](https://github.com/SecurityRonin/forensicnomicon/blob/main/research/macos-lofl-catalog.yaml)(约 78 个,同类首个目录) |
| `LOLBAS_LINUX` | 479 | [GTFOBins](https://gtfobins.github.io/) |
| `LOLBAS_WINDOWS_CMDLETS` | 289 | [LOFL Project](https://lofl-project.github.io/) + 原生 PS 攻击 cmdlet + PS 别名(Event 4104/PSReadLine) |
| `LOLBAS_WINDOWS_MMC` | 63 | [LOFL Project](https://lofl-project.github.io/) MMC 管理单元(.msc, LNK/UserAssist) |
| `LOLBAS_WINDOWS_WMI` | 30 | [LOFL Project](https://lofl-project.github.io/) WMI 类(Event 5861) |
每个常量都是一个 `&[LolbasEntry]`。每个条目都包含名称、MITRE 技术 ID、一个 `use_cases` 位掩码和一个描述。
LOLBin 查找 API
| 常量 | 检测来源 |
|----------|----------------|
| `LOLBAS_WINDOWS` / `LOLBAS_LINUX` / `LOLBAS_MACOS` | 进程遥测、Prefetch、AmCache、EDR |
| `LOLBAS_WINDOWS_CMDLETS` | PowerShell ScriptBlock 日志(Event 4104)、PSReadLine 历史记录、AMSI |
| `LOLBAS_WINDOWS_MMC` | LNK 文件、UserAssist MRU、Jump Lists |
| `LOLBAS_WINDOWS_WMI` | WMI 活动日志(Event 5861)、`Get-CimInstance` 调用 |
```
use forensicnomicon::lolbins::{
is_lolbas, lolbas_entry,
LOLBAS_WINDOWS, LOLBAS_LINUX, LOLBAS_MACOS,
LOLBAS_WINDOWS_CMDLETS, LOLBAS_WINDOWS_MMC, LOLBAS_WINDOWS_WMI,
UC_EXECUTE, UC_DOWNLOAD, UC_BYPASS,
};
// Cross-platform check
assert!(is_lolbas("certutil.exe"));
assert!(is_lolbas("bash"));
assert!(is_lolbas("osascript"));
// Rich struct lookup
let entry = lolbas_entry(LOLBAS_WINDOWS, "certutil.exe").unwrap();
assert!(entry.use_cases & UC_DOWNLOAD != 0);
println!("{}", entry.description);
// Non-binary LOFL types
assert!(is_lolbas_windows_cmdlet("Invoke-Command"));
assert!(is_lolbas_windows_mmc("compmgmt.msc"));
assert!(is_lolbas_windows_wmi("Win32_Process"));
```
## 工件目录
该目录涵盖了跨 Windows、Linux、macOS 和云环境的 6,554 个工件。数百个条目是完全手工整理的,包含解码后的字段 schema、分析师编写的含义、分诊优先级、证据强度评级和检测支点。其余部分则是从七个权威的 DFIR 源语料库中生成的。
以 UserAssist 为例。每一个工件注册表都会为你提供键路径。而这个目录为你提供:
| 字段 | 值 |
|---|---|
| 解码 | 值名称为 ROT13 编码。Payload 是一个 72 字节的结构体:运行次数在偏移量 4 处,最后执行的 FILETIME 在偏移量 60 处 |
| 含义 | 证明特定用户账户交互式启动了一个程序 |
| 可靠性 | `Strong`,但该键可以被清除。缺失并不证明未执行。 |
| 分诊优先级 | `Critical` |
| 易失性 | `Persistent`(磁盘上的注册表)。根据 RFC 3227,首先获取 RAM。 |
| 检测支点 | T1204.002,3 条 Sigma 规则,YARA 模板 |
目录中包含什么
**执行证据:** UserAssist、Prefetch、Shimcache/AppCompatcache、Amcache、BAM/DAM、MUICache、SRUM、AppShim、Windows Timeline、Background Activity Moderator
**持久化:** Run/RunOnce 键(HKLM + HKCU)、计划任务、Startup 文件夹、Active Setup、IFEO 调试器劫持、AppInit DLL、WMI 订阅、服务 ImagePath、Boot Execute、打印监视器、LSA 包、COM 劫持、Winlogon、屏幕保护程序可执行文件、Netsh 助手、密码过滤器 DLL
**注册表 MRU 和 Shell 历史记录:** ShellBags、Jump Lists、LNK 文件、OpenSave MRU、LastVisited MRU、Run MRU、TypedURLs、TypedPaths、WordWheelQuery、最近文档
**文件系统:** $MFT、USN Journal、回收站、Thumbcache、Windows Search 数据库
**Windows 事件日志:** Security、System、PowerShell/ScriptBlock (4104)、Sysmon,以及包括 RDP、WinRM、WMI、Defender、BITS、AppLocker、Firewall、NTLM、SMB、Task Scheduler 在内的 22 个附加命名通道
**凭据工件:** SAM 配置单元、LSA 机密、DPAPI 主密钥、Windows 凭据管理器、Windows Hello/NGC 密钥、证书存储、DCC2/MSCachev2
**网络和远程访问:** RDP 位图缓存、RDP 客户端服务器历史记录、VPN/RAS 电话簿、WinSCP、PuTTY、WiFi 配置文件、NetworkList、MountPoints2、便携设备
**云、浏览器和第三方:** Chrome、Edge、Firefox 凭据存储;TeamViewer、AnyDesk、ScreenConnect、RustDesk;OneDrive、Dropbox、Google Drive FS、MEGAsync;Teams、Slack、Discord、Signal;WinRAR 历史记录
**Active Directory:** NTDS.dit、SYSTEM 启动密钥、DPAPI SYSTEM 主密钥
**macOS:** LaunchAgents、LaunchDaemons、emond、Unified Log、CoreAnalytics、KnowledgeC、Keychain、TCC 数据库、隔离事件、Safari、Gatekeeper、bash/zsh 会话
**Linux:** bash/zsh 历史记录、cron、systemd units、XDG 自启动、SSH 密钥、sudoers、/etc/passwd、auth.log、systemd journal、wtmp/btmp/utmp、ld.so.preload、PAM、udev 规则、云凭据(AWS、Azure、GCP、Kubernetes)、Docker 配置、git 凭据
**按来源生成的条目:**
| 来源 | 条目数 |
|--------|---------|
| KAPE 目标 (EricZimmerman/KapeFiles) | 2,422 |
| ForensicArtifacts YAML | 2,545 |
| EVTX/ETW 通道 | 995 |
| Velociraptor 工件 | 122 |
| RECmd 批处理文件 | 44 |
| 浏览器工件(20 种浏览器) | 37 |
| NirSoft 工具 | 28 |
目录 API:查询、解码、证据、易失性
```
use forensicnomicon::catalog::{CATALOG, TriagePriority};
use forensicnomicon::volatility::acquisition_order;
// RFC 3227 acquisition order: RAM first
let order = acquisition_order();
// Triage-ordered list, Critical first
let critical: Vec<_> = CATALOG
.for_triage()
.into_iter()
.filter(|d| d.triage_priority == TriagePriority::Critical)
.collect();
// Keyword search
let hits = CATALOG.filter_by_keyword("prefetch");
// MITRE technique lookup
let hits = CATALOG.by_mitre("T1547.001");
// Decode a raw artifact
let d = CATALOG.by_id("userassist_exe").unwrap();
let record = CATALOG.decode(d, value_name, raw_bytes)?;
// record.fields — Vec<(&str, ArtifactValue)>: typed field pairs
// record.timestamp — Option: ISO 8601 UTC when present
```
内置解码器:`Rot13Name` (UserAssist)、`FiletimeAt` (FILETIME 转 ISO 8601)、`BinaryRecord`、`MruListEx`、`MultiSz`、`Utf16Le`。
```
use forensicnomicon::evidence::{evidence_for, EvidenceStrength};
use forensicnomicon::volatility::{volatility_for, acquisition_order};
let e = evidence_for("prefetch_dir").unwrap();
// e.evidence_strength — EvidenceStrength::Strong
// e.evidence_caveats — &["Disabled by default on Server SKUs", ...]
let order = acquisition_order();
// order[0] → mem_running_processes (Volatile)
// order[n] → mft_file (Persistent)
```
## 可滥用网站
`abusable_sites` 模块映射了攻击者用于 C2、网络钓鱼、payload 传递和数据渗出的域名。这些都是企业无法封锁的受信任域名。
`BlockingRisk` 编码了关键的权衡。GitHub 和 AWS 带有 `BlockingRisk::Critical`,因为封锁它们会破坏你自己的 CI/CD 和云工作负载。使用此字段在封锁(低风险)和检测并警报(高风险或严重风险)之间进行选择。
数据来自 [LOTS Project](https://lots-project.com/) 和 [URLhaus](https://urlhaus.abuse.ch/)。
可滥用网站 API
```
use forensicnomicon::abusable_sites::{
is_abusable_site, abusable_site_info, sites_with_tag, sites_above_risk,
BlockingRisk, TAG_C2,
};
assert!(is_abusable_site("raw.githubusercontent.com"));
let site = abusable_site_info("api.telegram.org").unwrap();
// site.blocking_risk → BlockingRisk::Medium
// site.abuse_tags & TAG_C2 → true
// C2-capable domains you cannot block
let critical_c2: Vec<_> = sites_with_tag(TAG_C2)
.filter(|s| s.blocking_risk >= BlockingRisk::Critical)
.collect();
```
## `4n6query` CLI
从终端查找任何二进制文件、域名或工件。所有查询均为离线进行。
```
$ 4n6query certutil.exe # LOLBin lookup, all platforms
$ 4n6query certutil.exe --platform windows # restrict to one platform
$ 4n6query curl --platform linux
$ 4n6query raw.githubusercontent.com # abusable domain lookup
$ 4n6query userassist # artifact search, all variants
$ 4n6query T1547.001 # technique lookup
$ 4n6query --triage # Critical artifacts first (RFC 3227 order)
$ 4n6query --triage --scenario ransomware # filter by incident type
$ 4n6query --triage --type lateral-movement
$ 4n6query dump --format json # full dataset for SIEM/SOAR integration
$ 4n6query dump --format yaml --dataset lolbas
$ 4n6query dump --format json --dataset catalog
$ 4n6query certutil.exe --format json # JSON output for any query
```
`--scenario` 选项:`ransomware`、`data-breach`、`bec`、`insider`、`supply-chain`
`--type` 选项:`execution`、`persistence`、`lateral-movement`、`credential-access`、`defense-evasion`、`discovery`、`collection`、`exfiltration`、`command-and-control`、`privilege-escalation`
指标表模块
| 模块 | 涵盖范围 | 关键 API |
|---|---|---|
| `ports` | C2、Cobalt Strike、Tor、WinRM、RAT 默认端口 | `is_suspicious_port(u16)` |
| `lolbins` | 所有六个 LOL/LOFL 数据集 | `is_lolbas(&str)`、`lolbas_entry(catalog, name)` |
| `abusable_sites` | LOTS Project + URLhaus | `is_abusable_site(&str)`、`sites_above_risk(BlockingRisk)` |
| `processes` | 恶意软件和伪装进程名称 | `is_masquerade_target(&str)` |
| `commands` | 反弹 shell、下载 cradles、WMI 滥用 | `is_reverse_shell_pattern(&str)` |
| `paths` | 可疑的暂存和劫持路径 | 路径切片 |
| `persistence` | Run 键、cron、LaunchAgents、IFEO、AppInit | `WINDOWS_RUN_KEYS`、`LINUX_PERSISTENCE_PATHS` |
| `antiforensics` | 日志擦除、timestomping、rootkit 指标 | 指标切片 |
| `remote_access` | LOLRMM/RMM 工具指标 | `is_lolrmm_path(&str)` |
| `third_party` | PuTTY、WinSCP、OneDrive、Chrome、Dropbox | `identify_application(&str)` |
丰富化模块
| 模块 | 关键 API |
|---|---|
| `attack_flow` | `flow_by_id(&str)`、`flows_for_artifact(&str)` |
| `chainsaw` | `hunt_rules_for(&str)` |
| `dependencies` | `dependencies_of(&str)`、`full_collection_set(&[&str])` |
| `eventids` | `event_entry(u32)`、`events_for_artifact(&str)`| `navigator` | `generate_navigator_layer(&str)`、`covered_techniques()` |
| `playbooks` | `playbook_by_id(&str)`、`playbooks_for_artifact(&str)` |
| `sigma` | `sigma_refs_for(&str)` |
| `stix` | `stix_mapping_for(&str)` |
| `temporal` | `temporal_hints_for(&str)` |
| `toolchain` | `kape_mapping_for(&str)`、`kape_target_set(&[&str])`、`velociraptor_artifact_set(&[&str])` |
| `volatility` | `acquisition_order()`、`volatility_for(&str)` |
| `yara` | `yara_rule_template(&str)` |
ArtifactDescriptor 字段参考
| 字段 | 类型 | 描述 |
|---|---|---|
| `id` | `&'static str` | 机器可读的标识符,例如 `"userassist_exe"` |
| `name` | `&'static str` | 人类可读的显示名称 |
| `artifact_type` | `ArtifactType` | `RegistryKey`、`RegistryValue`、`File`、`Directory`、`EventLog`、`MemoryRegion` |
| `hive` | `Option` | 注册表配置单元,对于文件/内存工件则为 `None` |
| `key_path` | `&'static str` | 相对于配置单元根目录的路径 |
| `file_path` | `Option<&'static str>` | 适用时的绝对文件路径 |
| `scope` | `DataScope` | `User`、`System`、`Network`、`Mixed` |
| `os_scope` | `OsScope` | `Win10Plus`、`Linux`、`LinuxSystemd`、`MacOS`、`MacOS12Plus` |
| `meaning` | `&'static str` | 取证意义 |
| `mitre_techniques` | `&'static [&'static str]` | ATT&CK 技术 ID |
| `fields` | `&'static [FieldSchema]` | 解码后的输出字段 schema |
| `triage_priority` | `TriagePriority` | `Critical` / `High` / `Medium` / `Low` |
| `related_artifacts` | `&'static [&'static str]` | 交叉关联的工件 ID |
| `sources` | `&'static [&'static str]` | 权威来源 URL |
## 规范化报告 (`report`)
静态目录是末端的一半。另一半是 `forensicnomicon::report` —— **每个 SecurityRonin 分析器都标准化至其上的共享发现词汇表**,因此 VMDK、VHDX、EWF、MBR/GPT/APM、ISO 9660、EVTX、SRUM、内存和 PE 发现将聚合成一个统一的 `Report`,而不是 N 个定制的结果类型。它是**分析器数据的联合,而不是扁平化** —— 并且一个 `Finding` 是*带有证据的观察*,绝不是一个判决。
```
use forensicnomicon::report::{Finding, Severity, Category, Source};
// Each analyzer keeps its own typed AnomalyKind and converts to a canonical Finding.
let finding = Finding::observation(Severity::High, Category::Integrity, "VMDK-RGD-MISMATCH")
.note("redundant grain directory diverges from the primary")
.source(Source { analyzer: "vmdk-forensic".into(), scope: "VMDK".into(), version: None })
.mitre("T1565.001") // "consistent with", never an assertion
.evidence("primary_gte", "0x1234")
.build();
assert_eq!(finding.severity, Some(Severity::High));
```
- **5 级 `Severity`** (`Info < Low < Medium < High < Critical`),作为 `Option` 携带,因此*未评级*(分析器未对其评分)与*已评分且为良性*是有所区别的。
- **`Observation` 生产者 trait** —— 在你定义类型的异常上实现 `severity`/`category`/`code`/`note`,并免费获得 `to_finding()`。`Finding` 仅支持构建器模式且为 `#[non_exhaustive]`,因此模型可以在不破坏已发布集群的情况下增加字段。
- **`FindingContext`** 携带行为的超集:置信度、出现次数、时间戳、MITRE `ExternalRef` 以及非磁盘的 `SubjectRef`(进程 / 模块 / 注册表项)。
- **稳定的、带 scheme 前缀的代码**(`VMDK-RGD-MISMATCH`、`MEM-PROCESS-HOLLOWING`、`WINEVT-PROVIDER-GUID-SPOOFING`)是跨 scheme 的连接键;`Category::from_code` 对它们进行分类,并且 `disk4n6` / `issen` 统一渲染 `Report { findings, provenance, timeline }`。
`forensicnomicon` 保持着零依赖的**末端**地位:每个分析器都向下依赖于它;而它不依赖于任何人。
## 状态历史 (`history`)
第三个知识词汇表(与目录和 `report` 并列)是 `forensicnomicon::history` —— **`[H]` 状态历史层**:一个横切面的 functor,将每个导航原语提升为时间索引变体(磁盘 → VSS/APFS 快照,内存 → hiberfil 链,日志 → 轮换/密封的 journals,查询 → 时间点导出;`[C]` git 是不动点)。它是纯粹的声明式词汇表 —— 没有解析,没有 I/O。
```
use forensicnomicon::history::{epoch::LsnKind, profiles::SourceTemporalProfile};
// The canonical temporal profile of one source family — the fleet's single source
// of truth, so consumers (sqlite-forensic, Issen, …) never re-assert and drift on it.
let wal = SourceTemporalProfile::sqlite_wal();
assert!(wal.clock.ordering_only); // a WAL frame carries no wall clock
// A WAL ordering key is salt-qualified: a checkpoint reset rolls the salts AND
// renumbers frames, so "frame 7 of epoch A" is not "frame 7 of epoch B".
let _lsn = LsnKind::SqliteWalFrame { salt1: 0xDEAD_BEEF, salt2: 0x0BAD_F00D, frame_seq: 7, commit_seq: 3 };
```
- **`TemporalCohort
` / `TemporalState`** —— 一个工件的状态,按 `wall_time`(否则按排序键)排序,归组在一个 `IdentityDiscipline` 下;对源定义的句柄进行了泛型抽象,因此没有 trait 对象开销。
- **`ClockProvenance`** —— 四个正交的信任轴(`source` / `trust_grade` / `tamper_resistance` / `ordering_only`),因此“本地但已签名”(iOS APFS)与“外部 + 已证明”(Sigstore)有所区别,而不是一个扁平的信任级别。
- **`SourceTemporalProfile`** *(0.4 中的新功能)* — 每个源家族(SQLite WAL、EVTX、USN、ESE、journald、VSS、git)对应一个规范的 `{ clock, safety, topology, ordering }`。消费者读取该配置文件,而不是重新推导分类,因此集群不会在例如“WAL 时间戳是否可伪造”这样的问题上产生分歧。
## 文档
| | |
|---|---|
| [API 参考](https://docs.rs/forensicnomicon) | 所有模块的完整 rustdoc,包括 `report` 和 `history` |
| [架构](ARCHITECTURE.md) | 数据流:从原始字节到 ArtifactRecord |
## 使用方
- [`issen`](https://github.com/SecurityRonin/issen) — 实时事件响应分诊工具;渲染规范化的 `Report`
- [`disk-forensic`](https://github.com/SecurityRonin/disk-forensic) — `disk4n6` 分区 scheme 编排器;聚合分析器发现
- SecurityRonin **取证分析器集群** — `vmdk-forensic`、`vhdx-forensic`、`ewf-forensic`、`mbr-/gpt-/apm-/iso9660-forensic`、`winevt-forensic`、`srum-forensic`、`memory-forensic`、`exec-pe-forensic`、`usnjrnl-forensic` — 全部发出 `forensicnomicon::report::Finding`
- [`blazehash`](https://github.com/SecurityRonin/blazehash) — 高速取证哈希验证
[隐私政策](https://securityronin.github.io/forensicnomicon/privacy/) · [服务条款](https://securityronin.github.io/forensicnomicon/terms/) · © 2026 Security Ronin Ltd