# Time Machine 恢复如何分裂审计轨迹

Time Machine 恢复可能会让审计历史分成两条，即使所有保留下来的记录都通过了加密验证。这个结果常常让团队感到意外，因为他们以为哈希链应该只产生一条权威记录。哈希链能证明记录从此前某条记录连续延伸，但无法证明 Mac 从未回到那条记录，再沿另一条路径继续运行。

调查人员发现两条延续后，马上把其中一条称为伪造，这是一个错误。普通恢复就可能产生这种结构，并不需要欺骗。证据工作的重点是保留两条线，说明它们在哪些地方共享历史，并明确每条线能够和不能够证明什么。如果把它们压平成一条整齐的时间线，案件中第一个不可信的记录就会由你制造出来。

## 恢复可能产生两条真实的延续

当恢复内容包含较早版本的审计存储，而应用随后从这个恢复状态写入新事件时，恢复后的 Mac 就会形成分叉。假设有一个日志，其中每条记录按顺序链接前一条记录的哈希。在第 500 条记录处，存储的头部哈希是 H500。Time Machine 捕获了这一状态。之后 Mac 继续运行，并写入第 501 条到第 580 条记录，每条记录都链接到前一条记录。

后来，有人把 Mac 恢复到截至第 500 条记录的备份。恢复后的应用将 H500 视为当前头部，并写入一条新的第 501 条记录。这条新记录正确连接到 H500，只是内容、哈希，以及可能还有时间戳，都与原 Mac 在恢复前写入的第 501 条记录不同。

结果是一个共享前缀和两个后继：

```text
records 1 through 500
             |
             +-- lineage-original: 501 through 580
             |
             +-- lineage-restored: 501 through 544
```

每个后继都可能通过普通链检查。验证器会检查每条记录是否连接到该序列中提供的前一条记录，但它并不知道所有可能从 H500 开始的后续路径。这不是哈希的缺陷。系统恢复可变状态时，出现这种结果本来就是预期行为。

分叉可能发生在正常关机时、崩溃后，或紧急恢复期间。技术人员不需要操纵审计数据库。恢复整个系统、恢复应用数据文件夹，或用备份替换整个卷，都可能让较早的日志头重新出现在机器上。具体细节取决于备份捕获了什么，以及恢复过程放回了什么。

不要把副本和分叉混为一谈。如果恢复后的 Mac 再也没有记录新事件，你得到的只是同一段历史的较早副本。只有当两个不同的后继都声称自己连接到同一个前置记录时，才算出现分叉。这个区别会影响之后的每一个结论。

## 分支内部有效，不等于存在一条全局时间线

哈希链检查回答的是一个范围很窄的问题：在提供的这条序列中，这条记录是否紧接着前一条记录出现？它无法回答在其他地方是否也有另一条有效记录紧接着同一条前置记录出现。调查人员常常把前一个答案说得过于绝对，仿佛它已经解决了后一个问题。

可以把以下四个概念明确区分开：

- 完整性，是指一条采集到的序列中的记录仍按预期相互连接。
- 连续性，是指在你掌握的材料范围内，序列没有无法解释的缺口。
- 完备性，是指相关范围内发生的每个事件都在你手中。
- 排他性，是指从同一个位置不存在其他延续。

恢复之后，本地审计轨迹可能拥有很强的完整性，却既不具备完备性，也不具备排他性。误解这一点，会导致报告中出现具有破坏性的句子：日志证明没有发生审批。日志可能只能证明恢复后的延续中没有出现审批记录。

时间会进一步加剧混淆。墙上时钟的时间可能重叠。原始 Mac 可能在 14:03 记录了一次操作，恢复后的 Mac 随后从网络校准时钟，却在 14:02 记录了另一个操作，同时仍从较早的序列头继续运行。按时间戳排序，可能会把不同分支的事件交错成一个看似合理、实际却错误的顺序。

序列号也需要上下文。两个后继都可能包含第 501 条记录。不要在原始证据中把其中一条改名为 501A，也不要认定序列号更大的那条才正确。保留原始字段不变，在工作记录中补充链路信息。

NIST Special Publication 800-92《Guide to Computer Security Log Management》将时间同步和受保护的日志处理视为运营要求。这一指导仍然可靠，但同步时钟无法解决恢复状态的问题。时钟规范有助于比较不同来源，却无法告诉验证器，在较早记录之后出现的两条记录中，哪一条是唯一后继。

## 准确称呼分叉点

在讨论动机之前，先使用精确的标签。我把两条延续共同拥有的最后一条记录称为分叉点，把从这个点开始的一条连续链称为链路，把不同链路之间的关系称为分支，而不会把它随意当作文件副本的同义词。

为每条链路分配稳定的案件标识。名称应该描述来源，而不是可信度。例如，可以把从设备镜像或恢复前导出文件中提取的序列称为 lineage-original，把恢复后的 Mac 继续写入的序列称为 lineage-restored。如果来源仍不确定，可以先使用 lineage-A 和 lineage-B，等有更多证据后再改成更具体的名称。

一份简短的保留记录就能避免数周的混乱：

```yaml
case: IR-2026-041
fork_record: 000500
shared_head_hash: H500-value-recorded-verbatim
lineage-original:
  source: external-export-collected-from-operator
  first-divergent-record: 000501
  collection-copy-sha256: recorded-separately
lineage-restored:
  source: restored-mac-audit-store
  first-divergent-record: 000501
  collection-copy-sha256: recorded-separately
```

不要在这些标签中加入 legitimate、compromised 或 trusted 之类的结论。这些词会诱使团队在检查周边证据之前就做出判断。标签应该让另一名调查人员在六个月后接手材料时，准确知道某个陈述指的是哪条序列。

如果证据只能支持一个范围，也要把恢复边界记录成范围。Time Machine 快照日期告诉你备份何时捕获了数据，但不会自动告诉你实际恢复何时执行、Mac 之后何时首次启动，或应用何时恢复写入。这些问题可能需要结合备份元数据、系统记录、管理员笔记和其他服务日志来确认。

## 在恢复后的分支继续延长之前保留机器

恢复后的机器一旦启动拥有审计存储的应用，就可能立刻改变证据。它可能写入启动事件、轮换文件、更新索引，或联系时间服务。因此，第一次处理决定比之后使用多么聪明的解析器更重要。

首先，停止日常使用并记录 Mac 的可见状态。如果它已经在运行，拍下屏幕，记下显示的时间和网络状态，并记录谁拥有物理控制权。然后按照事件处理流程，以合适的方式将它与网络隔离。不要仅仅因为偏好干净的采集就重启机器。重启可能替换易失性上下文，并触发更多写入。

接下来，分别保留不同来源。这包括恢复后的卷、相关的 Time Machine 备份集、恢复前的任何导出文件，以及接收过审计操作副本的服务。为每个采集文件或镜像计算加密哈希，并在工具允许时让原始材料保持只读。使用副本开展工作。

「保留两条时间线」有实际含义。它不是把渲染后的活动界面复制到报告里，而是保留原生审计数据、验证器程序及其版本、能够说明较早状态为何出现在 Mac 上的备份元数据，以及记录每项材料如何到达你手中的采集笔记。

如果你只找到了恢复后的延续，就如实说明。不要凭想象补出原始延续。如果备份快照包含共享头部，而其他来源显示恢复后的历史无法解释的活动，你仍然可以识别出可能存在的分叉。但你不能通过外推哈希来重建缺失记录。哈希链能检测提供给它的关系，不能恢复缺失内容。

时间紧迫的事件可能迫使团队尽快恢复服务。把运营恢复与证据保留分开。能先制作保留副本时就先制作；无法做到时，记录从哪一点开始无法保留，并记录所有可能向实时系统写入数据的操作。坦诚说明限制，远比事后拼出一条精致的时间线更可靠。

## 在排列事件之前建立证据地图

调查人员在制作时间线前需要先建立证据地图。从来源开始，而不是从事件开始。每个来源都应记录采集日期、所有者、相关日期范围、原生格式、加密摘要，以及它属于哪条链路或同时属于两条链路。

证据地图经常会发现，所谓分叉其实只是一次不完整的导出。例如，操作人员可能从一台机器导出第 1 条到第 580 条记录，而恢复后的 Mac 只保存第 1 条到第 544 条记录。如果两条序列直到第 500 条都完全相同，并在第 501 条分开，这支持存在真正的分叉。如果导出文件只是缺少第 545 条到第 580 条记录，却在其他方面与恢复后的序列一致，那你得到的是一条被截短的链路副本。

在疑似边界附近寻找独立见证来源。有用的来源包括备份快照元数据、操作系统安装和启动记录、远程 API 日志、SSH 目标端日志、通知记录，以及当时写下的工单笔记。每个来源都有局限。远程服务可以佐证某个操作确实到达，但未必能指出是哪一个本地审计文件记录了它。备份记录可以显示较早状态曾经存在，但未必能说明是谁发起了恢复。

从一开始就在工作表中加入链路列。它可以简单到这样：

| 事件引用 | 链路 | 记录时间 | 支持来源 | 可信度说明 |
| --- | --- | --- | --- | --- |
| 000500 | shared | 13:42 | 两个原生存储 | 共同分叉点 |
| 000501-O | original | 13:45 | 恢复前导出文件 | 原始链路的第一个后继 |
| 000501-R | restored | 13:38 | 恢复后的卷 | 恢复链路的第一个后继 |

表格中的后缀只是分析人员使用的引用。请在单独字段中保留原生记录标识。这样可以防止电子表格为了让重复编号看起来整齐，就悄悄重写证据。

不要按便利程度给来源排序。屏幕截图容易阅读，但缺少字段和采集上下文。原始导出文件看起来可能不太方便，却允许其他人重新运行验证。证据地图应该告诉审阅者某个来源为什么支持一项陈述，而不是只告诉他们分析人员在哪里找到它。

## 分别验证每条链路，不要假装它们重新连接

把每条采集到的链路作为独立序列进行链验证。记录确切的输入集、采集副本摘要、工具版本、命令、执行主机和结果。没有输入材料的验证结果只是一个主张，不是可重复的发现。

对于支持 Sallyport 验证器的审计数据，相关命令是：

```text
sp audit verify
```

Sallyport 可以在离线状态下对加密的哈希链式审计日志执行验证，无需保险库密钥。这在采集期间很有用，因为保险库被锁定时，调查人员不必为测试采集序列是否正确连接而解锁凭据。

不要在随意混合两个后继分支记录的文件夹上运行验证器。混合输入可能在分歧处失败，也可能被工具按你没有预期的顺序读取。为 lineage-original 和 lineage-restored 分别创建有文档记录的工作副本。保持原生材料不变。

通过验证的结果只能支持所选链路内部的完整性。笔记和报告应这样表述。验证失败则需要受控调查。检查采集是否遗漏了一段，导出工具是否重新排列了记录，解析器是否转换了换行符或字段，以及来源本身是否被改动。在测试修正之前，先保留每个失败的输入。

共享的分叉记录需要单独检查。确认它的序列化内容和哈希在两个来源中一致。如果在疑似分歧之前它们就已不同，那么你面对的就不是这里描述的简单恢复模型。可能存在不同的导出文件、数据损坏、独立的审计存储，或更复杂的序列。不要因为 V 形图很熟悉，就强行把证据塞进一个整齐的 V 形结构。

## 分支重叠时，时间戳需要见证来源

分开链路后，时间戳才能恢复正确用途。它们可以帮助你把事件放在外部来源之间进行比较，却不能决定哪条本地延续具有权威性。

先建立两条时间线。在每条时间线中保留记录时间、序列顺序、事件身份和来源引用。然后在旁边加入外部事件，例如服务收到的远程 API 请求、SSH 目标端记录、备份快照完成时间，或有文档记录的恢复操作。标明每个外部事件是支持某条特定链路、同时支持两条链路，还是只能缩小时间范围。

假设原始延续在 15:10 记录了一次 HTTP 调用，而恢复后的延续在 14:58 记录了另一次不同的调用，尽管从现实时间看恢复发生得更晚。差异可能来自恢复后的时钟、包含较早时钟值的快照，或启动后校正的时间。正确的报告不会把 14:58 或 15:10 选作全局顺序，而会说明每个时间由哪台设备记录，以及哪些独立记录把恢复操作定位在两者之间。

单次启动期间，单调计数器可能很有帮助，但恢复可能带回旧的计数器状态，或启动新的启动上下文。除非文档能够证明它们跨链路仍具备一致含义，否则应把它们视为链路内部的值。进程标识符、临时文件名和本地会话标识符也一样需要谨慎。恢复的快照可能重现一些看起来只会出现一次的值。

需要单一事件叙述时，使用偏序。明确写出证据能够确定顺序的事件，例如在采集前创建的原始导出文件。对于顺序仍然未知的部分，写明时间区间。调查人员有时不喜欢这样的答案，因为管理层希望看到一条时间线。明确的不确定性比虚假的全序更好，尤其是在纪律处分或法律决定取决于它时。

## 恢复后的历史不能证明存在隐瞒

团队经常把恢复后的缺口视为有人有意擦除活动的证据。这个结论很受欢迎，因为它符合一个简单故事：备份等于回滚，回滚等于掩盖。单靠技术证据，很少能支持如此强烈的动机判断。

恢复可能由磁盘故障、升级失败、恶意软件清理、误操作清理，或让开发机重新运行起来的常规尝试引起。无论动机如何，同一个操作都可能产生审计分叉。意图需要来自分支结构以外的证据，例如消息、命令、访问记录，或某人陈述中的矛盾。

反过来，把每个缺口都解释成无害恢复也同样错误。寻找矛盾之处。相关人员是否报告过恢复？备份元数据是否支持所声称的来源和时间？原始延续是否仍存在于导出文件或其他服务中？远程系统是否收到过恢复链路中没有记录的操作？同一时期是否有人改动了备份保留策略、审计存储或系统时间？

实用的审查顺序可以让推理保持严谨：

1. 确定共享前缀和第一条分歧记录。
2. 保留原生材料并计算采集摘要。
3. 分别验证每条链路。
4. 使用备份和外部记录佐证恢复边界。
5. 将技术发现与关于意图的结论分开。

这种方法也能保护无辜的操作人员。有人可能是在服务中断期间恢复 Mac，却因为调查人员把有效的恢复延续当成伪造日志而背上指控。反过来，如果另一条保留下来的延续显示同一分叉点之后发生了更多事件，仅仅指出某条链本身完整，也无法解决问题。

## 设计恢复流程，让分叉留下可见证据

你无法让 Time Machine 失去恢复应用状态的能力，但可以决定恢复后是否留下足够的独立证据，解释之后发生了什么。实用的控制措施包括：在重大变更前导出已签名或以其他方式独立保留的审计材料，保留备份元数据，在工单中记录恢复决定，并在适合的地方采集远程操作记录。

不要把本地链作为历史记录的唯一证明。本地链能为该设备上现存的记录提供有力证据。备份让回滚成为可能，这正是它的职责。这两个事实可以同时成立。如果团队需要区分连续运行和恢复旧状态后继续运行，就需要另行保留的参考来源。

在非生产环境中测试这个容易被忽略的场景。创建几条审计事件，进行备份，再创建更多事件，恢复较早状态，然后再创建一条事件。让第二个人收集两条延续，并在不依赖操作人员记忆的情况下解释分叉。如果团队在这个演练中都无法标记来源、验证每条序列并保留边界，那么真正发生事件时会更难处理。

在恢复流程中写入一句话：包含审计状态的恢复，在审查另有结论之前，会启动一条新的证据链路。这句话会在关键时刻改变操作人员的行为。它要求在恢复正常工作前先保留证据，也阻止团队继续相信恢复后的日志会自动取代此前的记录。

## 报告两段历史，不要掩平难以解释的部分

一项经得起审查的结论，应指出共享记录，标明每条延续的来源，分别陈述验证结果，并说明外部证据能够或不能够确定什么顺序。同时，还应区分已经证实的恢复和疑似恢复。语言可以保持简单：采集材料包含第 500 条记录之后的两条加密上一致的延续；备份元数据显示一份较早的审计状态曾出现在 Mac 上；在没有更多来源的情况下，证据无法确定两个后继之间唯一的顺序。

不要把分支称为 alternate reality、shadow log 或 duplicate timeline。这些说法会让技术状态显得过于戏剧化，也会让审阅者猜不出你究竟发现了什么。分叉的审计历史本身已经足够严重。这意味着在一个已知点之后，本地记录不再提供一份不间断的单一叙述。

发现分叉后的第一步很简单：如果原始延续仍然存在，就在恢复后的 Mac 再写入一条记录之前保留它。之后关于验证、时间戳和动机的所有讨论，都取决于第二条线是否留存。
