norwytch/weeping-angel

GitHub: norwytch/weeping-angel

一个针对 Windows 时间戳篡改(timestomping)恶意软件的检测框架,通过多见证者分歧和防篡改账本实现带外取证。

Stars: 1 | Forks: 0

# 哭泣天使 [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/1179e52319180728.svg)](https://github.com/norwytch/weeping-angel/actions/workflows/ci.yml) [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) [![MITRE ATT&CK](https://img.shields.io/badge/ATT%26CK-T1070.006-red.svg)](https://attack.mitre.org/techniques/T1070/006/) 检测仅在认为自己未被观察时才运作的 timestomping 恶意软件。 在经典的英国科幻剧集《神秘博士》中,哭泣天使是一种只有在未被观察时才能移动的实体。在直接观察下,它必须保持墓地雕像的形态,一动不动。脱离观察后,哭泣天使可以超越光速在空间中移动,以触及受害者并吸食他们的“时间能量”,包括通过数字信号网络进行移动。这意味着哭泣天使也有可能被用于恶意软件。 在这个 repo 中,我们设想了一款具有与剧中相似能力(仅在未被观察时进行横向移动)和目标(破坏目标的时间线)的恶意软件。当然,我们最终受限于天使被设想为“量子”实体这一事实,而我们受到经典计算系统的制约。尽管如此,我们将这款恶意软件设想为以下映射关系: | 《神秘博士》 | 本系统 | |---|---| | 天使 | 进行 timestomp 的反取证恶意软件 | | 移动 | 写入伪造的 `$STANDARD_INFORMATION` 时间戳 | | 被观察 | 恶意软件的自查:带内检查 Procmon、EDR、打开的句柄、调试器 | | 量子锁定 / 变成石头 | 每当其自查显示“被观察”时便进入休眠 | | 两个天使互相锁定 | 必须达成共识的独立见证者;它们之间的分歧即为指纹 | | 时间悖论 | 一条仅可追加、防篡改的记录,你无法在不产生矛盾的情况下重写它 | | 从时间之外观察 | 带外观察(内核 minifilter、hypervisor/VMI),它无法感知 | ## 核心设计原则 1. 带外观察。恶意软件会检查带内观察者(用户态 进程、句柄、调试器)。从它之下或外部进行观察(内核 minifilter,或监视 guest 的 hypervisor),这样它行动的前提条件 在现实中永远为假,而它却无法察觉。 2. 多见证者分歧。保留多个独立的时间戳源, 如果没有人伪造任何东西,它们必须一致。没有单一的见证者能抓住天使; 它们的分歧可以。 3. 防篡改账本。一条前向哈希链、仅可追加的日志,其中每条 记录都与其前驱绑定。篡改过去会打破这条链。 有关更多详细信息,请参阅[威胁模型](docs/THREAT_MODEL.md)。 ``` flowchart LR subgraph guest["What the Angel can see (in-band)"] A[Angel / malware] -->|checks| O[procmon? handle? debugger?] A -->|stomp $SI| SI["DisplayWitness ($SI)"] end subgraph oob["Out-of-band, invisible to the Angel"] REC[Recorder
minifilter / VMI] --> LED[(Hash-chained ledger)] FN["MFTWitness ($FN)"] LED --> JW["JournalWitness (USN)"] end REC -. observes every op .-> A SI --> DET{DivergenceDetector} FN --> DET JW --> DET DET --> F[Findings: the move, recorded] ``` ## 快速入门 ``` git clone && cd weeping_angel python examples/demo.py # narrated walkthrough of the scenarios python -m weeping_angel.adapters.mft examples/data/sample.mft # parse a raw $MFT and scan it python -m weeping_angel.efficacy # precision/recall over a labeled corpus python examples/arena_demo.py # adversarial arena: Angels vs the recorder pip install -e . && weeping-angel scan examples/data/sample.mft # the unified CLI pip install -e ".[test]" && pytest -q # 115 tests ``` 有关完整的论证和设计说明,请参阅 [`docs/WRITEUP.md`](docs/WRITEUP.md)。 要在来自 Windows VM 的真实 timestomp 上运行检测器,请参阅 [`docs/LAB.md`](docs/LAB.md) 中的实验指南。 ## 面对天使 天使是 Whoniverse 中最令人恐惧的实体之一。了解如何在你的系统中检测并击败它们非常重要!`python examples/demo.py` 会在模拟的天使上运行完整流程。 1. 移动。在没有带内观察者存在的情况下,`Angel.tick` (`weeping_angel/simulator.py`) 写入伪造的 `$SI` 时间戳并返回 `MOVING`。同样的操作 会在天使无法看到的账本中进行带外记录。 2. 检测。由于带外见证者保留了真实值, `DivergenceDetector.scan` (`weeping_angel/detector.py`) 发现它们存在分歧,并 在场景 1 中触发 R1、R2、R4 和 R6。没有使用天使能够观察到的任何信息 来抓住它。 3. 击败。有两种方式。如果它认为自己被观察,它会变成 `STONE` 并且绝不行动 (场景 2)。当 `AdvancedAngel` 试图抹除记录时(场景 3), 哈希链账本在任何内部编辑时都会断裂,并且机外锚点 会捕获到被丢弃的尾部。最终证明 (`weeping_angel/paradox.py`) 表明, 只要带外观察持续存在,“移动但未被记录”的状态是无法达到的。 示例输出(已精简): ``` Scenario 1 -- the Angel moves while it believes no one is watching Angel.tick -> MOVING (it sees no in-band observer) Three independent witnesses disagree: [HIGH] R1_si_fn_birth_divergence display($SI) vs mft($FN) [HIGH] R2_si_journal_rollback display($SI) vs journal(USN) [HIGH] R4_setinfo_captured journal(USN) the forgery caught in the act Scenario 2 -- the Angel freezes because it believes it is watched Angel.tick -> STONE no divergence, quantum-locked (harmless) Scenario 3 -- the Angel also tries to rewrite history ledger.verify().ok = False broken chain link, cannot rewrite the past ``` 场景 1 中的伪造在内部逻辑上是一致的(创建时间早于修改时间,看起来 像是一个旧文件),因此单源启发式方法会漏掉它。它依然无法逃脱 它无法触及的见证者。 ![Timestomp 时间线:显示的 $SI 时间早于记录的真实时间](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/c677e9a9b4180733.svg) 显示的 `$SI` 时间停留在 2019 年,而带外记录显示了真实的 2023 年活动;阴影间隙就是伪造的倒填日期。你可以使用 `weeping_angel.timeline.divergence_svg` 为任何文件生成它。 ## 检测规则 | 规则 | 见证者 | 捕获内容 | |---|---|---| | `R1_si_fn_birth_divergence` | `$SI` vs `$FN` | 显示的创建时间早于内核设置的 MFT 创建时间 | | `R2_si_journal_rollback` | `$SI` vs USN | 显示的修改时间早于日志中真实的最后写入时间 | | `R3_internal_ordering` | `$SI` | 修改时间早于其自身的创建时间(不可能) | | `R4_setinfo_captured` | USN | 写入与基准事实相矛盾的元数据设置操作:早于 `$FN` 创建时间、回滚到早于真实的最后写入时间,或处于未来 | | `R5_future_timestamp` | `$SI` | 处于未来的时间戳 | | `R6_subsecond_truncation` | `$SI` vs `$FN`/USN | `$SI` 被清零至整秒,而见证者保留了 100 纳秒的精度,这是基于 `SetFileTime` 的 stompers 将纳秒清零的特征 | | `R7_si_fn_modified_divergence` | `$SI` vs `$FN` | 显示的修改时间早于内核设置的 `$FN` 修改时间,而经典的 stompers 不会触及后者 | 每个 `Finding` 都标记有 MITRE ATT&CK [T1070.006](https://attack.mitre.org/techniques/T1070/006/)(Indicator Removal: Timestomp)。Sigma 规则和基于 Sysmon Event ID 2 (FileCreateTime,该技术的实时遥测)键控的 Sysmon 配置位于 [`detections/`](detections/)。 ## 已实现 vs 仅限设计 以下所有内容都是可运行、经过测试的代码(Python,以及用于记录器的 Go); [布局](#layout) 是按文件映射的目录。亮点如下: - **检测:** 在真实的 `$MFT` 和 USN-journal 二进制解析器(以及 MFTECmd-CSV 适配器)上应用了七条带有 ATT&CK 标签的规则,并配备了精度/召回率测试套件。 - **防篡改记录:** 一个带有 off-box HMAC 锚点的哈希链 JSONL 账本,由 Python 检测器和 Go `recorder/` 完全一致地写入: 字节一致的 SHA-256 链,经过跨语言验证。 - **响应与集成:** 一套试运行的交战规则响应层, 用于 SIEM 摄取的 ECS/OCSF 导出器,以及 Sigma/Sysmon 检测。 - **对手建模:** 悖论证明、确定性模拟器,以及配备了启发式、贝叶斯和进化策略训练的智能体的对抗性竞技场(也作为下方的 Kaggle 竞赛打包)。 - **靶场:** Terraform (Docker) 用于配置记录器机群并端到端地运行 timestomp 场景。 仅限设计(已记录文档,但在此处不可执行):内核 minifilter、 hypervisor/VMI 视角,以及实时 USN 收集。每个见证者 的真实数据源都在 [`weeping_angel/adapters/windows.py`](weeping_angel/adapters/windows.py) 和 [`docs/DESIGN.md`](docs/DESIGN.md) 中有详细说明。 ## 备注/对现实情况的让步 - 复杂的样本不一定使用纯粹的“被观察/未被观察”二元状态。它可能会 按概率或定时器进行 timestomp,不会留下任何可供利用的瞬间破绽。 防御方假设它会行动,并依赖于不可磨灭的记录,而不是冻结它。 - 用虚假的观察者(诱饵 Procmon 进程、被保持的句柄)来 冻结它符合主题但很脆弱,因为这取决于能否准确枚举其检查项。应将其 视为绊线,而不是核心机制。 - 防篡改保护了已记录的过去。它无法恢复记录器 从未见过的值,因此记录器的覆盖范围才是真正的安全边界。 - 除非其头部被锚定在 off-box,否则最新的账本记录仍可能被丢弃。 `weeping_angel/anchor.py` 实现了该锚点,因此被丢弃的尾部 会表现为“锚定的头部领先于磁盘上的内容”。参见 [`docs/DESIGN.md`](docs/DESIGN.md)。 - 设置旧的时间戳本身并不具有恶意;归档程序、 restore/backup、`cp -p` 和 `rsync -t` 都会这样做。因此,`R4` 仅在 捕获到的 `setinfo` 与带外基准事实相矛盾时触发,并 豁免已知合法设置者(`trusted_setinfo_actors`)的白名单,其匹配 基于记录器提供的映像路径或签名者,而不是可伪造的名称。 ## Kaggle 该竞技场还被封装为 [`kaggle/`](kaggle/) 中的 [kaggle-environments](https://github.com/Kaggle/kaggle-environments) 模拟,包含一个自包含的 notebook ([`kaggle/weeping_angel_arena.ipynb`](kaggle/weeping_angel_arena.ipynb)),该 notebook 内联定义了 env(无需附加数据集),运行一个 episode,并对 内置的智能体进行相互评分。竞赛环境是一场深度博弈:包含 staging-cost 机制(天使必须先发出活动才能进行 timestomp),因此 不存在统治性策略,外加贝叶斯(Thompson-sampling)和混合策略 基线智能体。 - 在 Kaggle 上运行:https://www.kaggle.com/code/jaq2347/weeping-angel-notebook - 在本地运行:`pip install -e ".[arena]" && python examples/kaggle_arena.py` - 对于官方举办的竞赛,[`kaggle/contrib/`](kaggle/contrib/) 包含了 可合并的 `kaggle-environments` 环境包,以及贡献 + 推介指南。 ## 布局 ``` weeping_angel/ # the package: detection logic and the simulation that exercises it ledger.py # hash-chained, append-only, tamper-evident log anchor.py # HMAC-authenticated off-box head anchor (closes tail-truncation) witnesses.py # $SI / $FN / USN witnesses over a common interface detector.py # seven divergence rules -> ATT&CK-tagged findings paradox.py # observed/unobserved state machine + unreachability proof simulator.py # filesystem sim, observation oracle, Angel agents response.py # rules-of-engagement response layer (dry-run, ledger-audited) export.py # render findings as ECS / OCSF for SIEM ingestion timeline.py # forged-vs-true timeline as a standalone SVG cli.py # unified `weeping-angel` command-line entry point efficacy.py # precision/recall harness over a labeled corpus arena.py # adversarial Angels-vs-recorder game (coverage budget) learn.py # learned arena agent (Evolution Strategies, no deps) adapters/windows.py # design-only real-artifact adapters adapters/mft.py # executable: parse a raw NTFS $MFT and run the rules adapters/mft_csv.py # executable: run the rules over an MFTECmd CSV export adapters/usn.py # executable: parse the USN journal ($J) for the true timeline recorder/ # out-of-band collector in Go (shared JSONL ledger, hash chain) range/ # Terraform range: recorder fleet + timestomp scenario (Docker) kaggle/ # the arena as a kaggle-environments sim (bot-vs-bot, optional dep) detections/ # ATT&CK map, Sigma rules, Sysmon config (Event ID 2) examples/ # demo, arena, and kaggle runners; data/ ($MFT + USN samples) docs/ # DESIGN, THREAT_MODEL, WRITEUP, LAB, timeline.svg tests/ # 115 tests, incl. Hypothesis property tests ``` ## 许可证 MIT,请参阅 [LICENSE](LICENSE)。
标签:Python, 反取证, 安全评估, 强化学习, 数字取证, 无后门, 日志审计, 自动化脚本, 请求拦截, 逆向工具