乍看之下,取证时间线比它所来自的磁盘更显权威。磁盘由数十亿个难以辨读的字节组成,时间线展示的却是一行行整齐记录:09:41 修改了一个文件,09:42 写入一条浏览器记录,09:43 出现一条日志。把这些行按时间排序,读者很容易以为一段故事已经自行成形。
然而,这三个时间可以描述三类不同的事物:一个来自文件系统的元数据字段,一个由应用程序保存,另一个则是解析器对日志记录的解释。三者的精度、时区前提以及与人的行为之间的关系都可以不同。Plaso 的事件模型设有事件时间、时间含义、来源、解析器和上下文数据等字段,以保留这些区别。[5] 因而,时间上的接近只能提供调查线索,不能证明因果关系。
开源时间线工具链的各层保持可见时,整套系统最有价值。libewf 读取或写入 .E01 一类专家证人格式(Expert Witness Format,EWF)容器;dfVFS 定位存储介质内的卷、文件系统和嵌套对象;Plaso 提取源级事件并写入 .plaso 存储文件;Timesketch 为这些事件建立索引,让调查人员可以检索、标记、比较和讲述。每一层都带来一类新的提问方式,其证明力也始终受自身处理范围限制,无法完整承接下层的权威。
核心界限由此显现:可检索时间线,是在采集数据之上、依据若干选定解释建立的派生索引。它可以帮助调查人员找到决定性的数字痕迹,却无法取代证据镜像、采集记录,或把数字痕迹与主张连接起来的推理过程。
图片背景:题图拍摄于 2013 年,画面中两名检验人员正在数字取证实验室工作。显示器占据了画面主体,裸露的硬盘、受管理的工作区和第二名操作人员同样重要。本文梳理的开放式工具链会产生可检查的转换结果;与之配套的人员和流程,则界定这些结果能够支持哪些主张。[12]
四个层次,四类不同的主张
| 层次 | 开源组件 | 可以确立什么 | 单独使用时无法确立什么 |
|---|---|---|---|
| 容器访问 | libewf | EWF 文件开放了哪些介质字节与采集元数据,以及其中存储的介质数据能否通过校验 | 是否依照有记录的程序,完整采集了正确的设备 |
| 存储定位 | dfVFS | 读取者正在访问哪个嵌套镜像、卷、文件系统和文件条目 | 每个加密、损坏或尚未支持的项目是否都已变得可读 |
| 事件提取 | Plaso | 哪个解析器从何种来源生成了事件,该事件带有什么时间含义与上下文 | 该事件是否代表调查人员所怀疑的操作 |
| 协作分析 | Timesketch | 哪些导入事件符合某项查询、视图、标签或故事 | 未出现的事件是否从未存在,或时间相邻的事件是否互为因果 |
这套工具链的价值,在于各层间的缝隙始终清晰。每一道衔接都能接受检查,也有记录可供保存。
libewf 打开容器,来源记录始于容器之外
EWF 镜像远不止一个以 .E01 结尾的文件名。它是一种容器,工具可由此访问已经捕获的存储介质数据及相关元数据。libewf 项目支持常见的 EWF 格式族,并为生命周期中的不同环节分别提供工具:ewfacquire 把介质数据写入 EWF,ewfinfo 报告容器信息,ewfexport 转换或导出数据,ewfmount 通过 FUSE 开放访问,ewfverify 则校验已存储的介质数据。[1]
这些动词的范围有意收得比“证明”更窄。ewfverify 成功运行,可以支持一项特定主张:容器内的介质数据仍与该格式预期的校验值一致。至于采集开始前活动系统是否已经发生变化、不可读扇区的处理是否恰当、规定使用写保护器时是否实际使用,以及贴有标签的设备是否就是案件记录所述设备,这项结果都无法说明。
NIST 的保存指南把容器周围的责任逐一写明:记录原始来源及镜像的创建或传输方式;采集完成后尽快计算数字镜像的哈希值;把所得哈希值单独保存于安全位置;保留备份;记录每次移交。[10] 哈希值可以有力佐证两次观察之间的字节级连续性,但它无法追溯到首个可信哈希值产生之前,替此前发生的一切作验证。
因此,EWF 容器划出了第一道技术界限;取证可信度还要从容器外的记录开始建立。一次经得起质询的取证运行,需要把来源标识、采集笔记、工具及版本、操作人员、开始与结束时间、读取错误记录、容器分段集合和密码学哈希值一并保存。随后,原始镜像继续得到妥善保存,下游工具则使用经过校验的副本,或经由受管理的只读访问通道工作。
dfVFS 在嵌套存储中保留完整地址
取证介质内的路径很少只是 C:\Users\...。抵达一个文件,往往要先打开一组 EWF 分段,读取分区表,选中某个分区,解析 NTFS,再定位文件条目或备用数据流。常规操作系统路径会隐藏这条链的大部分环节。
数字取证虚拟文件系统(Digital Forensics Virtual File System,dfVFS)为存储介质格式、卷系统和文件系统提供通用只读访问界面,各个后端负责处理具体格式。[2] 它的路径规范会明确展示嵌套关系。EWF 路径规范可以是分区路径规范的父级;分区又可以作为 Sleuth Kit 文件系统路径的父级;文件系统对象随后可以指向某个具体条目。同一模型还覆盖 raw、QCOW、VHD 与 VMDK 镜像,APFS 与 LVM 容器,采用 BitLocker 或 LUKS 加密的卷,卷影副本,乃至嵌套在 ZIP、TAR 或 SQLite 对象中的文件。[3]
这为证据审查带来直接优势:经过多层抽象之后,“这个对象来自哪里”仍然可以回答。Plaso 输出能够把序列化路径规范与解析器、事件字段一同保留,使复核人员可以从一行记录循迹返回其存储位置,避免只接受便于阅读的显示路径。[3][6]
只读访问与完整访问分属两件事。加密卷仍需正确凭据;损坏的文件系统会使路径解析器失效;某些格式尚未得到支持,或支持范围有限;选取一份快照时,也会漏掉另一份快照可见的状态。失败信息应留在运行记录中,包括来源扫描消息、所用凭据、选定分区、纳入的快照,以及无法打开的对象。来自不可读层的空结果,不能作为对象不存在的证据。
Plaso 把数字痕迹转换为源级事件
log2timeline.py 接受文件、目录、存储设备或存储介质镜像作为输入,把提取出的事件与收集元数据写入 Plaso 存储文件。文档给出的基本命令刻意保持简洁:
log2timeline.py --storage-file timeline.plaso /evidence/host.E01
在提取之前及提取过程中,Plaso 借助 dfVFS 扫描来源,预处理主机名、本地用户和时区信息等上下文,选择解析器,并存储解析器输出的事件。[4] .plaso 文件是一份从来源数据派生而来的中间分析材料:pinfo.py 可以检查它,psort.py 则可以筛选其中内容,或将其渲染成其他输出格式。[4]
这里的 事件 一词需要严格界定。Plaso 把源级事件定义为一个时间点或一段持续时长、对该时间含义的说明、获知信息的来源、来源特有数据以及上下文信息。[5] 文件的创建时间与修改时间属于两个独立事件,因为它们表达的是两项独立主张。浏览器数据库中的一行,可以呈现应用程序记录的访问时间;Windows 事件日志记录,则可以携带系统写入的时间戳。解析器能够把这些数值归一化后用于比较,同时保留 timestamp_desc、解析器链和来源路径等字段。[6]
归一化让关联分析成为现实,却无法凭空创造一套统一时钟。一台已经关机的笔记本电脑,关机前的本地时间也可以是错的;云服务可以按 UTC 写入,而应用程序按本地时间导出;有些格式保存亚秒精度,有些则没有;复制文件时,可以保留一个元数据字段并重写另一个。解析器覆盖范围也设下明确上限:不受支持的数字痕迹、损坏的记录或被排除的解析器都不会产生事件。关于数字取证工具错误的独立研究,把时钟不准与时间戳解释错误视为两条不同的故障路径;排序后的结果无法消除其中任何一条。[11]
因此,操作记录应收录 Plaso 的确切版本、完整命令行、解析器或筛选器选择、来源时区的判定方式、依赖项检查、警告,以及所得 .plaso 文件的哈希值。版本升级后重新提取完全合理,但这会生成一份新的派生数据集。应保存较早的存储文件并记录变化,避免在既有结论下面悄然替换时间线。
Timesketch 让派生事件集可供调查
.plaso 文件内容丰富,多人共同追查不断变化的问题时却不够便利。Timesketch 接受 Plaso 存储文件,也接受按要求组织的 CSV 和 JSONL。其导入程序能够套用 Plaso 事件筛选器,把大型上传拆成多个部分,并为所得事件数据建立索引以供查阅。[7] 一个 sketch 可以合并多条时间线,为调查人员提供检索、时间范围筛选、已保存视图、评论、标签、星标事件和故事;sketch 还可以分享给指定用户或群组。[8]
相较于反复导出完整时间线,这一层让分析工作开始以查询和选定事件为单位。分析人员可以保存 data_type:"windows:registry:key_value" 一类查询,缩小时间范围,给相关记录加标签,再把选中的事件写进一篇故事。[9] 第二名调查人员可以检查同一个结果集,并质疑查询方式。Timesketch 真正带来的能力,正是这种共享且可复核的分析状态。
这里还会再发生一次转换。导入筛选器可以排除某些事件类别;索引映射决定字段的检索方式;已保存视图只记录查询,分析人员未写明的前提仍留在记录之外;标签和故事属于分析人员添加的注释,磁盘本身没有这些属性。即使用户从未取得原始镜像,访问 sketch 仍会暴露高度敏感的来源内容。
如果只有一名响应人员检查一台范围明确的主机,psort.py 输出配合一份记录严谨的调查笔记,往往是一套规模更小、风险更低的系统。多名调查人员需要在大量或多条时间线上重复查询时,Timesketch 的优势才充分显现——与此同时,团队也接手了一项需要严密保护的服务,以及存储容量、案件级授权、备份、审计要求和导出方案等责任。只有协作需求本身足够明确,才值得引入这一层;网页界面带来的完成感没有证据效力。
最终截图之外,还要保存整条转换链
若只保留经过修饰的最终状态,这套工具链会迅速失去可辩护性:Timesketch 截图上显示十行记录、彩色标签和下方一段说明。截图会丢失查询、筛选器、解析器溯源信息、排除的来源,以及返回镜像的路径。
一套紧凑的审计资料包应保留五组相互关联的记录:
- 采集:来源身份、授权与范围、操作人员笔记、错误、工具版本、容器分段清单、时间戳,以及独立于镜像保存的哈希值。
- 访问:经过校验的工作副本、dfVFS 来源选择记录、所用凭据或快照,以及限制可读范围的扫描失败记录。
- 提取:Plaso 版本、完整命令、解析器集合、时区处理、警告、处理统计,以及
.plaso输出的哈希值。 - 导入:Timesketch 导入程序版本、目标 sketch 与时间线、任何
--plaso-event-filter、索引或映射变化,以及访问控制决定。 - 分析:已保存的查询和时间范围、带作者信息的标签、故事修订、导出内容,以及让每项实质主张指向底层事件与来源路径的引证。
这些记录的作用,在于定位争议所属的处理层;推断是否正确,仍要另行检验。两名分析人员看到的记录不同时,可以比较导入和查询;事件确实存在但时间含义有争议时,可以检查 Plaso 事件与解析器;来源路径无法解析时,可以检查 dfVFS 和容器;容器本身受到质疑时,则回到采集过程、哈希值与保管记录。
从故事返回事件、从事件返回对象、再从对象返回字节——这种诊断方向,是整套工具链最有力的设计属性。libewf、dfVFS、Plaso 和 Timesketch 允许团队替换或重新运行其中一层,同时清楚保留各层主张之间的差异。
取证时间线是否值得信任,要看它能否让自身的不完整接受检查;表面上的完整感没有同等分量。它应展示采集了什么、哪些内容可以打开、解析了什么、导入了什么,以及分析人员作出了什么推断。时间线让调查获得可循的路径;所有主张最终仍须回到磁盘镜像及其来源记录。
来源
- libyal,
libewf项目文档——支持的 EWF 格式族,以及ewfacquire、ewfinfo、ewfexport、ewfmount与ewfverify的用途。 - log2timeline,
dfVFS项目文档——通用只读访问界面,以及存储、卷系统和文件系统后端。 - log2timeline,dfVFS 文档“Path specifications”——EWF、分区、文件系统、加密卷、快照和嵌套容器的父子级定位方式。
- Plaso,“Using log2timeline.py”——支持的输入形式、
.plaso存储输出、来源扫描、收集元数据,以及pinfo/psort工作流程。 - Plaso,“Scribbles about events”——源级事件语义、时间含义、来源上下文、解析器来源记录和时间戳表示。
- Plaso,“Output and formatting”——序列化路径规范、解析器链、时间戳说明和面向来源的输出字段。
- Timesketch,“Uploading timelines”——Plaso、CSV 和 JSONL 的导入路径、事件筛选和大型上传处理。
- Timesketch,“Sketch overview”——多时间线组织、检索、已保存视图、故事和分享范围。
- Timesketch,“Search query guide”——事件字段、查询语法、时间筛选器和已保存检索的行为。
- 美国国家标准与技术研究院,Digital Evidence Preservation: Considerations for Evidence Handlers,NIST IR 8387(2022)——关于来源记录、哈希计算、保管、备份和受保护存储的独立指南。
- Christopher Hargreaves、Alex Nelson 与 Eoghan Casey,“An Abstract Model for Digital Forensic Analysis Tools: A Foundation for Systematic Error Mitigation Analysis”(2024)——对抽象、解释与时间线错误路径的独立分析。
- Wikimedia Commons,“Digital forensics lab”——照片来源、日期、创作者、尺寸和 CC BY-SA 4.0 许可信息。