SQLite 几乎无处不在。iOS 和 Android 的原生应用、第三方聊天工具、甚至 Windows 10 的时间线Timeline都在用这个数据库格式。对取证调查人员来说这意味着一个案子里的关键证据——聊天记录、浏览历史、应用行为——很可能就藏在一个或多个 SQLite 文件里。用户删除一条微信消息或者一个应用自动清理了旧记录数据并不会立刻从数据库里消失。它可能还留在某个角落只是普通工具看不见。这就是 SQLite 取证的价值所在。一、SQLite里值得关注的三个“隐藏区域”要找到那些已经“被删掉”或者“还没正式保存”的数据得先弄清楚 SQLite 是怎么处理数据的。1. Freelists已删除记录的去处当一条记录被删除SQLite 并不会马上把它从文件里抹掉。而是把存放这条记录的那个页面page标记为“空闲”扔到一个叫 freelist 的地方。这些页面会被留着等以后有新的数据要写入时再拿出来用。在真正被覆盖之前里面的数据一直存在。不过这里有几个变量。比如 auto_vacuum 设置成 “full” 的话freelist 会被清空页面会挪到文件末尾然后截掉——但数据本身不一定被擦除理论上还能通过雕琢carving找回来。另一个是secure_delete如果应用开发者把它打开了删除的内容会被直接写零覆盖那就基本没救了。所以能不能恢复很大程度上取决于你调查的那个应用是怎么设计的。2. Journal 文件和 WAL还没提交的交易记录早期版本的 SQLite 用回滚日志Rollback Journal来保证事务安全。写入数据前先把页面原来的内容备份到 journal 文件里。写入成功就把 journal 删掉如果写入失败或者程序崩溃journal 就会留在磁盘上下次启动时用它来回滚。从3.7.0版本开始SQLite 改用预写式日志Write-Ahead Log简称 WAL。它的逻辑反过来新写入或修改的数据不直接改主数据库而是先存到 WAL 文件里。主数据库保持不变读取的时候同时看 WAL。当 WAL 积攒到一定大小或者手动触发检查点时才会把 WAL 里的数据正式合并到主数据库。这意味着什么如果一个聊天会话总共不到1000条消息那它在 WAL 里待上几天甚至几周都是有可能的。在这段时间里那些尚未被“提交”的消息、被编辑过的旧版本、甚至被删除但记录还留在 WAL 里的内容都有机会被提取出来。3. 未分配空间Unallocated Space这里的未分配空间不是指硬盘上的而是 SQLite 数据库页面内部的碎片区域。当页面里的某个单元格被释放后那部分空间就成了未分配区域里面可能残留着之前的数据片段。这些碎片没有被任何系统表引用找起来很麻烦但仍然可以尝试从里面雕刻出有意义的记录。二、用普通工具看 SQLite可能会漏掉什么很多免费或通用的 SQLite 浏览器比如 DB Browser for SQLite走的是标准 SQLite API。这套 API 根本看不到 freelist 里的东西也处理不了 WAL 和 journal——或者说处理的方式可能会毁掉证据。举个例子。一个 Skype 数据库文件有300多KB用 DB Browser 打开 Messages 表结果是空的。但如果你对文件大小有点敏感就会觉得不对劲300多KB不可能什么都不存。换到专业的取证工具中打开同一个文件直接显示53条聊天记录——全是 freelist 里挖出来的。再比如 WAL。普通工具打开一个带 WAL 的数据库时可能会自动执行 checkpoint把 WAL 数据合并到主数据库。如果你的证据介质是可写的主数据库的哈希值就变了WAL 文件本身也可能被删除这在法庭上是大忌。如果介质是只读的checkpoint 执行不了那工具到底给你看的是主数据库的数据还是 WAL 的数据很难说清楚。三、怎么做 SQLite 取证该文介绍一种取证解决方案它绕过了标准 SQLite API自己做低层解析。这意味着能直接读 freelist那些被删除但尚未被覆盖的记录会被提取出来和正常的记录一起合并到工件Artifacts视图里。比如一条被删掉的 Telegram 消息在界面上会多一个“Is deleted”属性标记而不是直接消失。能安全地处理 journal 和 WAL不会执行任何 checkpoint不修改原始文件同时把 journal 和 WAL 里的记录用不同颜色的标签标出来方便区分。能扫描未分配空间可以看到所有未分配空间的碎片。如果这些碎片里包含该取证解决方案能识别的工件比如聊天记录或浏览器链接会单独放在“Carved data”里。另外内置的 SQLite 检视工具还有一些对调查很实用的功能显示数据库属性页面大小、页面数量、journal 类型、哈希值查看表结构字段类型、主键、非空约束手动设置列的数据类型——比如 Unix 时间戳可以一键转成可读的时间直接预览 BLOB字段里的图片缩略图WhatsApp 的数据库里经常有针对任何表格生成报告XLSX、PDF、HTML、CSV 等而且列类型的设置会保留在报告里四、案例从内存里挖出 SQLite 数据库用该取证解决方案提取一台运行中的 Windows 7 的内存镜像让工具自动雕琢内存里的 SQLite 签名。从其中一个 Chrome 进程的内存里找到了13个 SQLite 数据库。打开其中一个只看到两个表和少量记录但仔细一看——里面6条记录全部来自 freelist都是已经被删除的。如果没有低层解析的能力这些数据根本看不到。五、总结SQLite 取证的难点不在于“会不会打开数据库文件”而在于“能不能看到那些标准API看不到的东西”。freelist、WAL、journal、未分配空间这四个地方往往藏着最关键的证据。用错了工具轻则漏掉线索重则破坏证据的完整性。该取证解决方案的做法是从底层自己解析不依赖 SQLite 官方驱动配合内置的 SQLite 检视工具和自动化雕琢能力把那些“理论上存在但普通工具看不见”的数据挖出来。对于 Windows 10 Timeline 这类数据库能找回的比例可能高达40-50%。而对于从内存里恢复的、已经部分被覆盖的数据库它可能是唯一还能读出东西的工具。