OnyxOmega/USNJournal2EventLog

GitHub: OnyxOmega/USNJournal2EventLog

将 NTFS USN 更改日志实时转换为结构化 Windows 事件日志的取证监控服务,支持白名单过滤和长期归档。

Stars: 0 | Forks: 0

# 取证 NTFS USN 日志监控器 一个 Windows 原生后台服务,用于实时监控 **NTFS USN 更改日志**,根据用户定义的白名单过滤文件系统活动,并将取证元数据记录到专用的 Windows 事件日志 (`FileSystem`) 中。它专为终端审计、变更追踪和轻量级主机取证而设计。该服务无头运行,可在重启后保留状态,以 `LocalSystem` 身份运行,并自动管理其自身的滚动日志归档,因此可以无人值守地长时间运行,而不会塞满磁盘。 ## 完整功能列表 查看完整的 **[功能列表](FEATURES.md)** ## 工作原理 ``` USN Journal -> read record -> resolve parent directory by file-reference -> O(1) whitelist match -> classify by reason -> Windows Event ``` 1. 打开卷并查询(或创建) USN 日志。 2. 协商卷支持的最丰富读取格式(NTFS 上为 V2,ReFS 上为 V3)。 3. 对于每次更改,解析所在目录的路径(已缓存),并在常数时间内根据白名单进行检查。 4. 根据 USN reason 标志对更改进行分类,并使用特定类别的事件 ID 写入结构化事件。 ## 系统要求 - Windows(NTFS 卷;ReFS 通过 V3 记录支持) - Python 3.12+(64 位) - [`pywin32`](https://pypi.org/project/pywin32/):`pip install pywin32` - 管理员 / `LocalSystem` 权限(读取 USN 和执行 `Clear-EventLog` 需要提权) - 存在 .NET Framework 4.x(使用其 `EventLogMessages.dll` 以便事件能够渲染出可读的描述;这几乎随附于所有现代 Windows 安装中) ## 快速开始 ``` :: 1. Install dependencies pip install pywin32 :: 2. Configure which directories to monitor (launches the GUI) python usn_monitor.py :: 3. Test in the foreground (Ctrl+C to stop) python usn_monitor.py debug :: 4. Install and start as a Windows service python usn_monitor.py --startup delayed install python usn_monitor.py start ``` ## 事件 ID 参考 每次更改都根据其**主导** USN reason 标志进行分类(原因会累积到一个单独的关闭记录中,因此最显著的标志优先)。完整的原因字符串始终保留在事件正文中。 | 事件 ID | 类别 | 触发条件 | |:--------:|----------------|---------------------------------------------------------------------| | **100** | Create | `FileCreate` | | **101** | Modify | `DataOverwrite`, `DataExtend`, `DataTruncation`, `NamedDataOverwrite`, `StreamChange` | | **102** | Delete | `FileDelete` | | **103** | Rename | `RenameOld`, `RenameNew` | | **104** | SecurityChange | ACL / 所有权变更 (`SecurityChange`) | | **105** | Other | `IndexableChange`, `BasicInfoChange`, `HardLinkChange` | | **106** | RangeChange | `USN_RECORD_V4` 范围追踪(仅限 ReFS) | **分类优先级:** `Delete > Create > Rename > Security > Modify > Other`。 在其关闭记录被报告之前创建并删除的文件将被报告为 **Delete**(磁盘上的净效果)。 ### 查询事件 事件被写入 **`FileSystem`** 自定义日志中,可以在事件查看器中的 **Applications and Services Logs → FileSystem** 下找到。 ``` # 所有删除 Get-WinEvent -FilterHashtable @{LogName='FileSystem'; Id=102} # 创建和删除一起 Get-WinEvent -FilterHashtable @{LogName='FileSystem'; Id=100,102} # 过去一小时内的所有内容,最新优先 Get-WinEvent -FilterHashtable @{LogName='FileSystem'; StartTime=(Get-Date).AddHours(-1)} ``` ## EventData 字段(`{PARAM[n]}` 参考) 每个事件都包含一个完整且人类可读的字段块作为 `{PARAM[1]}`,以及六个高价值字段作为单独的插入字符串,以便在 **Event Log Explorer**(或任何使用位置 `EventData` 的工具)中提取列。使用下面的索引将字段提取为 `{PARAM[n]}` 自定义列。 | 索引 | 字段 | 备注 | |-------|-------|-------| | `{PARAM[1]}` | 完整块 | 全部 16 个字段,格式为 `Key: value` 行(可读的描述 + EvtxECmd 正则表达式源) | | `{PARAM[2]}` | Hostname | 源主机名 | | `{PARAM[3]}` | TargetFilename | 完整路径(映射 Sysmon — 关联键) | | `{PARAM[4]}` | UtcTime | `YYYY-MM-DD HH:MM:SS.fff`(映射 Sysmon — 关联键) | | `{PARAM[5]}` | MachineGuid | 稳定的机器标识符 | | `{PARAM[6]}` | SourceIP | 服务启动时的 IP 地址 | | `{PARAM[7]}` | VolumeSerial | NTFS 卷序列号 (`XXXX-XXXX`) | **其余字段**(SchemaVersion, Category, Reason, Usn, JournalId, FQDN, Domain, MachineSID, MAC, OSBuild)**不**作为单独的 `{PARAM[n]}` 字符串拆分 —— 它们存在于 `{PARAM[1]}` 块内部。可以在那里提取它们(Event Log Explorer 支持对描述使用正则表达式),或者使用 EvtxECmd 映射,这些映射会通过正则表达式将每个字段从块中提取到 Timeline Explorer 列中。 **两种工具,两种访问方法(设计使然):** - **Event Log Explorer** 读取原始插入字符串数组 → 对于六个拆分出的字段,请使用上面的 `{PARAM[n]}`。 - **EvtxECmd → Timeline Explorer** 渲染为单个 `Data` blob → 捆绑的映射 (`maps/`) 通过正则表达式将所有字段提取到 `PayloadData1–6` + `Computer` 中。 **注意:** 这些 `EventData` 元素是*按位置排列且未命名的*(这是经典事件报告的一个限制),因此 `{EventData\Usn}` 风格的**命名**查找**不**起作用。命名字段访问需要构建插桩清单(已计划),这将允许每个字段成为其自己的命名列。 ## 选择要监控的路径 运行不带参数的 `python usn_monitor.py` 以打开配置 GUI: - 树形结构会延迟加载目录(在大型驱动器上不会卡顿)。 - **双击文件夹**可递归地将其*及其所有子目录*添加(或移除)到白名单。递归遍历在 UI 线程之外运行,因此 GUI 绝不会卡死。 - **`[X]`** = 已监控,**`[ ]`** = 未监控。 - 使用搜索框按名称跳转到文件夹。 - 点击 **Save Config (JSON)** 以写入 `monitor_config.json`。 默认情况下,会监控 `C:\Windows` 及其所有子目录;其他所有内容均被排除。 ### `monitor_config.json` 格式 配置文件位于 `usn_monitor.py` 旁边。服务在**启动时读取一次** —— 每次更改后都需要重启服务。 ``` { "paths": [ "C:\\Windows", "C:\\Windows\\System32", "C:\\Windows\\Temp" ], "rotation_size_gb": 3.5, "max_storage_gb": 60.0 } ``` | 键 | 含义 | |--------------------|-------------------------------------------------------------------| | `paths` | 受监控的目录(递归选择包括每个子目录) | | `rotation_size_gb` | 当实时日志达到此大小时滚动日志 (GB) | | `max_storage_gb` | 归档目录总容量上限;最旧的归档将被先入先出 (FIFO) 删除 (GB) | ## 日志滚动和保留 - **实时日志:** `FileSystem.evtx`(自定义的 `FileSystem` Windows 事件日志)。 - **滚动触发器(以先到者为准):** - 实时日志达到 `rotation_size_gb`(默认 **3.5 GB**),或 - 日历到达**每月 1 日 01:00**。 - **归档命名:** `FileSystem___.evtx` (例如 `FileSystem_June_2026_1.evtx`);计数器每月重置。 - **归档位置:** `C:\FileSystem_Archives` - **存储上限:** 当归档目录超过 `max_storage_gb` (默认 **60 GB**)时,**最旧的** `.evtx` 文件将首先被删除 (FIFO),直到目录回到上限以下。 滚动使用 `Clear-EventLog -Backup` 执行,这会原子地归档并清除实时日志。 ## 服务管理 ``` python usn_monitor.py --startup delayed install :: install (delayed auto-start) python usn_monitor.py start :: start python usn_monitor.py stop :: stop python usn_monitor.py restart :: stop + start (reloads config) python usn_monitor.py update :: re-register after editing the .py python usn_monitor.py remove :: uninstall sc query USNMonitorService :: check status ``` - 使用 `--startup auto` 代替 `delayed`,以便在启动时尽早开始运行。 - 编辑源代码后运行 **`update`**(而不是重新安装);SCM 会缓存脚本路径。 ## 诊断 服务将其自身的操作日志(错误、启动信息、滚动活动)写入: ``` C:\FileSystem_Archives\usn_monitor.log ``` 要进行深度故障排除,请通过将 `USN_VERBOSE` 环境变量设置为 `1`、`true`、`yes` 或 `on` 来启用定期计数器摘要(看到的记录数 / 解析失败 / 白名单匹配 / 发出的事件)。 ``` :: Console (inherits your shell environment) set USN_VERBOSE=1 python usn_monitor.py debug :: Service (must be machine-wide, then restart so the SCM picks it up) setx USN_VERBOSE 1 /m python usn_monitor.py restart ``` 详细统计信息行如下所示: ``` stats: seen=48 (v2=48 v3=0 v4=0) resolve_fail=0 no_match=3 emitted=45 last_resolve_err=None ``` `no_match` 计算白名单之外的更改(预计数量会很大 —— 这是您*未*捕获的整个卷的变动)。 ## 部署到多台机器 有关组策略 / Active Directory 和打包可执行文件选项,请参阅 **[DEPLOYMENT.md](DEPLOYMENT.md)** *(如果提供)*。简而言之: 1. **在目标机器上使用 Python:** 将 `usn_monitor.py` + `monitor_config.json` 复制到 每台主机,然后运行安装/启动命令(例如,通过 GPO 启动脚本或远程管理工具)。 2. **目标机器上没有 Python(建议规模化使用):** 使用 PyInstaller 冻结为独立 可执行文件并进行部署 —— 终端上不需要 Python 运行时。 3. 将标准的 `monitor_config.json` 推送到所有主机,以便它们共享一个白名单 和保留策略。 ## 注意事项与警告 - 需要提权;在默认的 `LocalSystem` 帐户下,这是自动完成的。 - `FileSystem` 日志和事件源在首次运行时自动注册。 - 在 I/O 极高且白名单范围极广的卷上,实时日志会快速增长 — 3.5 GB / 60 GB 的滚动策略在发挥着实际作用;请根据您的保留需求进行调整。 - 路径解析按目录缓存;重命名/删除事件将绕过缓存,以避免路径过期。 ## 许可证 见 **[LICENSE](LICENSE)**
标签:NTFS文件系统, Python, Windows服务, 取证, 子域名变形, 无后门, 逆向工具