一、概述
本篇要处理的是 iOS 取证里最危险的一块:设备已锁定、备份做不了,但委托方仍希望知道设备上发生过什么。
这个局面下有两个前提必须先说清。它们决定了本篇的写作重点不是"怎么进系统",而是"哪些事绝对不能做,以及在不能做的情况下还能拿到什么"。
第一,备份与 DFU 是两件完全不同的事。
| 误解 |
事实 |
| "进 DFU 就能做备份" |
DFU 模式本身不产生备份 |
| "DFU 可以解锁设备" |
DFU 恢复会清空设备数据 |
| "把设备放 DFU 就锁住证据了" |
恰恰相反——从这两种模式启动回正常系统时,若启动被判定为异常,iOS 可能触发「抹掉所有内容和设置」 |
第二,iOS 版本之间的路径与可用工件差异很大。
iOS 17 起系统对部分路径与容器做了调整。用 iOS 15 时代的路径去查 iOS 17 的设备,会得出"数据不存在"的错误结论——而实际上是路径变了。
这类错误的杀伤力在于:它不是漏检,是把"没找到"写成了"不存在"。
本篇的核心问题是在"设备已锁定、备份不可用"的前提下,回答两个问题:系统上还残留着哪些高价值痕迹,以及 DFU 究竟在什么情况下、经过什么程序才可以考虑。
在取证流程中的位置:采集环节的边界判定层。
输入是 iOS 备份与沙盒提取 没能覆盖的部分——备份层通常拿不到 knowledgeC.db、通话记录、完整照片,这些只在设备层可见。
输出是一份明确的能力边界声明:哪些结论来自备份层、哪些来自设备层、哪些因状态受限不可获取。
这份声明本身是交付物的一部分,不是过程记录。
涉及的证据形态(保留真实产品的强制路径与文件名):
| 形态 |
具体位置 |
说明 |
| 设备识别 |
ideviceinfo 的 UniqueDeviceID、ProductType、ProductVersion |
UDID 串联全部检材;ProductType 决定 DFU 按键流程 |
| 开机时间锚点 |
ideviceinfo 的 TimeIntervalSince1970 |
反映最近一次系统启动,锁屏状态下可能读不到,读不到本身也是一条记录 |
| 短信 |
/private/var/mobile/Library/SMS/sms.db |
已加密,需 passcode |
| 通话记录 |
.../CallHistoryDB/CallHistory.storedata |
时间、时长、方向 |
| 行为预测痕迹 |
.../CoreDuet/Knowledge/knowledgeC.db |
被严重低估的一类痕迹,见 2.3 |
| 系统偏好 |
.../Preferences/com.apple.*.plist |
网络、定位、Safari 设置 |
| 照片元数据 |
/private/var/mobile/Media/PhotoData/ |
EXIF、编辑历史、人脸与场景识别结果 |
| 系统日志 |
/private/var/logs/、system_logs.logarchive |
崩溃、网络、诊断 |
设备最后活跃时间点、曾访问过哪些应用与网站类型、通话对象与时间、照片的拍摄与编辑史、以及哪些数据因为设备状态拿不到。
锁屏且未解锁时的数据内容(sms.db 加密需 passcode);备份时点之后的行为;激活锁状态下的任何用户数据;绕过激活锁不是本领域的技术问题,而是法律程序问题。
内容边界(这一节请务必读完):
- 不做越狱、不提供 DFU 绕过、不提供激活锁绕过。 遇到激活锁,正确做法是如实记录设备状态并启动相应法律程序,而不是寻找规避手段。任何声称"可以自行绕过激活锁"的第三方服务,其合法性与真实性都应高度怀疑——这也是涉诈案件常见的敲诈话术。
- DFU 与刷写是本领域最不可逆的操作之一。 本篇给出进入与退出的完整记录要求,目的是让你能判断它该不该被做、做了之后如何留痕,而不是鼓励在未备份未授权的情况下尝试。
- 未完成备份、未获得明确授权之前,绝不能把扣押设备置于 DFU 或恢复模式,更不能执行任何刷写或恢复动作。 这不是技术建议,是证据保护的基本要求。很多案件的证据就是这样永久灭失的。
读者前提:需要 iOS 备份与沙盒提取 的备份层认知作为前提(必须先确认备份确实做不到或覆盖不足,本篇才是起点)。
还需要 Apple plist 与 SQLite 的基础,以及 取证流程与原则 里不可逆操作的处理纪律。
另外强烈建议先读 4.3——那是本篇最重要的一组陷阱。
二、核心原理
2.1 设备识别与开机时间
ideviceinfo 返回的字段中,有几个对取证意义特殊:
| 字段 |
含义 |
取证价值 |
UniqueDeviceID |
UDID,设备唯一标识 |
★★★★★ 串联该设备的所有检材 |
ProductType |
硬件标识(如 iPhone14,2) |
★★★★ 决定 DFU 的进入方式 |
ProductVersion |
iOS 版本 |
★★★★★ 决定可用工件与路径 |
DeviceName |
用户自命名 |
★★★ 常含姓名 |
TimeIntervalSince1970 |
自 1970 年以来的秒数 |
★★★★ 推算最近一次开机时间 |
TimeZone |
时区 |
★★★ 时间线对齐必需 |
TotalDiskCapacity / TotalSystemCapacity |
容量 |
★★ 校验备份完整性 |
InternationalMobileEquipmentIdentity |
IMEI |
★★★★ 设备标识(部分版本受权限限制) |
TimeIntervalSince1970 的价值:它反映的是最近一次系统启动的时间点。
开机时间是一条重要的时间线锚点——能界定"设备最后活跃于何时",也能帮助判断设备是否在扣押前被重启过。
ideviceinfo | grep -E 'TimeIntervalSince1970|TimeZone|ProductType|UniqueDeviceID'
# TimeIntervalSince1970: 1725039652
# TimeZone: Asia/Shanghai
重要限制:ideviceinfo 的可用字段受设备状态与 iOS 版本影响。未解锁或 iOS 较新时,部分字段返回不了。拿不到的字段就是拿不到,不要臆造——报告中应写"该字段在当前连接状态下不可读"。
2.2 高价值系统痕迹
以下是 iOS 上被广泛验证有取证价值的痕迹(路径随版本变化,务必实测):
| 痕迹 |
典型路径 |
内容 |
价值 |
| 短信 |
/private/var/mobile/Library/SMS/sms.db |
短信与 iMessage |
★★★★★ 已加密,需 passcode |
| 通话记录 |
/private/var/mobile/Library/CallHistoryDB/CallHistory.storedata |
通话时间、时长、方向 |
★★★★★ |
| 通讯录 |
/private/var/mobile/Library/AddressBook/AddressBook.sqlitedb |
联系人,含最近联系人 |
★★★★★ |
| 日历 |
/private/var/mobile/Library/Calendar/Calendar.sqlitedb |
日程、提醒 |
★★★★ |
knowledgeC.db |
/private/var/mobile/Library/CoreDuet/Knowledge/knowledgeC.db |
见 2.3 |
★★★★★ |
| 系统偏好 |
/private/var/mobile/Library/Preferences/com.apple.*.plist |
网络、定位、Safari 设置 |
★★★★ |
| 照片元数据 |
/private/var/mobile/Media/PhotoData/ |
EXIF、编辑历史、人脸与场景识别 |
★★★★ |
| DCIM |
/private/var/mobile/Media/DCIM/ |
原始照片与视频 |
★★★★ |
| 系统日志 |
/private/var/logs/、system_logs.logarchive |
崩溃、网络、诊断 |
★★★ |
| Safari |
/private/var/mobile/Library/Safari/ |
历史、书签、缓存 |
★★★ |
| 键盘缓存 |
/private/var/mobile/Library/Keyboard/ |
输入统计、常用短语 |
★★★ |
| Notes |
/private/var/mobile/Library/Notes/(旧版) |
备忘录 |
★★★★ |
# 备份中可直接查到的痕迹(不需越狱)
sqlite3 Manifest.db "
SELECT domain, relativePath FROM Files
WHERE relativePath LIKE '%knowledgeC%' OR relativePath LIKE '%CallHistory%'
OR relativePath LIKE '%AddressBook%' OR relativePath LIKE '%sms.db%'
OR relativePath LIKE '%Calendar%';"
一个必须知道的现实:上表中的路径是设备上的原始路径,只有在已越狱设备或物理镜像上才能直接读取。通过备份(06)能拿到的是参与备份的那部分——knowledgeC.db、通话记录、完整照片等通常不在普通备份范围内。报告中必须写清每个结论来自哪一层获取。
2.3 knowledgeC.db:被严重低估的痕迹
knowledgeC.db 是 iOS 的行为预测与知识库(CoreDuet / Knowledge 框架),它缓存了系统学习到的关于用户的大量信息:
| 内容 |
说明 |
取证意义 |
| 应用使用记录 |
打开过哪些 App、频次、时段 |
建立使用习惯画像 |
| 搜索关键词 |
系统 Spotlight 中搜索过的词 |
★ 常含用户主动搜索的敏感词 |
| 位置与时间的关联 |
常去地点、到达/离开时间 |
★ 建立行踪模式 |
| 联系人交互频次 |
与谁联系最频繁 |
★ 关系亲疏排序 |
| 邮件/消息实体 |
主题、行踪摘要 |
辅助印证 |
为什么它特别有价值:它是系统自动记录的,不是用户主动创建的。用户不会想到去清理它——因此它常常比聊天记录保存得更久、更完整。
一个反直觉的推论:当某个 App 的聊天数据库已经被清理或加密无法读取时,knowledgeC.db 里往往还残留着该 App 的使用记录、搜索关键词、以及从该 App 提取的实体摘要。这构成了"交叉印证"而非"直接证明",报告中必须严格区分这两者。
2.4 iOS 版本差异(必须实测,不能套用)
| 版本 |
变化 |
对取证的影响 |
| iOS 13+ |
部分 App 数据迁到 App Group 共享容器 |
备份中 relativePath 含 Containers/Shared/AppGroup/ |
| iOS 15+ |
更多 App 转向沙盒化存储 |
部分历史路径失效 |
| iOS 17+ |
系统部分路径与容器结构调整 |
旧路径假设可能完全失效 |
| iOS 17+ |
Safari 相关数据更多走容器化路径 |
需按 BundleID 定位容器 |
实战原则:
# ★ 不要硬编码路径。先列出实际有什么
# 备份中:把所有与目标相关的路径列出来,再逐个确认
sqlite3 Manifest.db "SELECT domain, relativePath FROM Files
WHERE relativePath LIKE '%Safari%' OR domain LIKE 'AppDomain-com.apple.mobilesafari%';"
本篇无法给出"iOS 17+ 的确切新路径",因为具体调整在不同机型与版本上并不完全一致。正确做法是实测 + 记录,而不是引用任何"版本对照表"。这是本篇刻意保留的不确定性,报告中也应如此表述。
2.5 DFU 与恢复模式:必须先讲清后果
DFU 会改写设备上的系统分区状态,属于对检材的写入操作。接入方式、只读优先原则与移动取证箱的要求见取证装备与写保护器。
这两种模式完全不是一回事,按键流程也完全不同,绝不可混记。
| 对比项 |
DFU(Device Firmware Update) |
恢复模式(Recovery Mode) |
| 层级 |
固件/引导加载层,不启动 iOS 本体 |
系统层,已启动最小 iOS 组件,能与电脑交互 |
| 是否加载 iOS |
否 |
是(精简环境) |
| 主机端可用的工具 |
刷写/固件类工具 |
ideviceinfo 可用;AFC 通道与 idevicebackup2 是否可用取决于设备实际状态,见下 |
| 能否做加密备份 |
不能 |
不能(无用户数据,无密钥材料可用) |
| 主要用途 |
刷固件、恢复固件、诊断 |
恢复系统、重装、诊断 |
| 对数据的影响 |
刷写即清空 |
恢复/重装即清空 |
恢复模式的能力边界必须按实际状态收窄,不能笼统说"工具都能用":
恢复模式下的可用性取决于三件事——① 设备是否已通过安全验证(未解锁则 lockdownd 不接受会话,表现为 Could not connect to lockdownd);② AFC 通道是否已建立(依赖设备与主机配对状态);③ 具体 iOS 版本与工具版本。
实操上:先用 ideviceinfo 探测,能返回机型即基本可用;返回 Could not connect to lockdownd 就说明会话建不起来,AFC 与备份类工具都不要再尝试。 任何"恢复模式下可以取出沙盒数据"的说法都应视为错误。
⚠️⚠️ 最重要的一条警告:
进入 DFU 或恢复模式本身不会立刻清除数据,真正不可逆的是后续的刷写、恢复、重装动作——这些操作会重写系统分区并抹除用户数据。此外,从这两种模式启动回正常系统时,若启动被判定为异常,iOS 可能触发「抹掉所有内容和设置」(Erase All Content and Settings),这是设备的保护性重置行为。
因此在未完成备份、未获得明确授权之前,绝不能把扣押设备置于这两种模式,更不能执行任何刷写或恢复动作。 这不是技术建议,而是证据保护的基本要求——很多案件的证据就是这样永久灭失的。
iPhone 8 及以后与 iPhone 7 及以前,进入 DFU 的按键流程完全不同:
| 机型 |
进入 DFU |
退出 DFU |
| iPhone 8 / X 及以后(Face ID 机型,无物理 Home 键) |
1) 电脑已识别设备后用工具触发;2) 快速按住侧边键 2 秒 → 不松手追加按住音量下约 4 秒 → 松开侧边键,继续只按住音量下约 10 秒(屏幕保持全黑,这是判据) |
按住侧边键 + 音量上,直到出现 Apple 标志 |
| iPhone 7 / 7 Plus 及更早(有 Home 键) |
1) 同时按住电源键(或侧边键)+ 音量下;2) 保持约 8–10 秒,看到 Apple 标志后松开电源/侧边键,继续只按住音量下约 8 秒(屏幕变黑是判据) |
按住电源键 + Home 键,直到出现 Apple 标志 |
两者的关键差异(务必记牢):iPhone 8+ 是先侧边键、再追加音量下(串行),全程无 Apple 标志直接黑屏;iPhone 7 及更早是电源键与音量下同时按(并行),先出现 Apple 标志随后黑屏。
iPhone 8 及以后没有物理 Home 键,因此「按住 Home 键」这套流程完全不适用。 用 iPhone 7 的方法操作 iPhone 8+ 会直接进入恢复模式或正常启动,而这两种情况都不是 DFU。
另外:上述为通行的参考时序,具体秒数在不同 iOS 版本与工具链下存在差异。 iPhone 15 及以后的机型在部分地区已进一步调整按键组合。实机操作前应查阅对应机型与当前 iOS 版本的官方指引,并在检查笔录中记录每一步按键与屏幕状态。
2.6 设备锁与激活锁
| 机制 |
说明 |
取证影响 |
| 锁屏密码(passcode) |
解锁设备、启用部分数据类 |
备份需要它;部分数据需要它 |
| 激活锁(Activation Lock) |
绑定 Apple ID 的设备锁 |
需 Apple ID 与密码才能解除 |
| MDM 远程管理 |
企业设备可远程锁定/抹除 |
扣押后企业可能远程执行,影响证据 |
⚠️ 激活锁的法律现实:绕过激活锁在多数司法辖区都需要走官方的司法协助/法律程序,由 Apple 或执法机关依申请处理。任何声称"可以自行绕过激活锁"的第三方服务,其合法性与真实性都应高度怀疑——这也是涉诈案件中常见的敲诈话术。
取证中的正确做法:遇到激活锁,如实记录设备状态并启动相应法律程序,而不是寻找规避手段。这既是法律要求,也是保护检材不被第三方工具破坏的考虑。
三、操作步骤
第 1 步:设备识别与状态固定
sudo apt install libimobiledevice-utils usbmuxd
sudo usbmuxd &
idevice_id -l
ideviceinfo > device-info.txt
grep -E 'UniqueDeviceID|ProductType|ProductVersion|DeviceName|TimeIntervalSince1970|TimeZone' \
device-info.txt
sha256sum device-info.txt | tee device-info.sha256
# 换算最近一次开机时间(Python 避免时区歧义)
python3 - <<'PY'
import datetime, subprocess, re
out = subprocess.run(["ideviceinfo"], capture_output=True, text=True).stdout
m = re.search(r"TimeIntervalSince1970:\s*(\d+)", out)
t = re.search(r"TimeZone:\s*(\S+)", out)
if m:
ts = int(m.group(1))
tz = t.group(1) if t else "UTC"
print("TimeZone:", tz)
print("UTC :", datetime.datetime.utcfromtimestamp(ts))
print("Local :", datetime.datetime.fromtimestamp(ts))
PY
第 2 步:判断设备可用层级
# 能否备份(最基本的能力探测)
ideviceinfo >/dev/null 2>&1 && echo "可通信" || echo "不可通信"
# 备份是否需要口令
idevicebackup2 -i backup /tmp/probe-backup/ 2>&1 | head -5
# 提示 "Please enter backup password" → 加密备份
# 提示 "backup is encrypted" → 同样
# 激活锁状态(若已启用,部分字段会显示 ActivationState)
ideviceinfo | grep -iE 'Activation|ProductType|ProductVersion'
| 结果 |
结论 |
| 能通信 + 提示输入备份口令 |
设备已解锁且信任,备份为加密 |
| 能通信 + 备份直接完成 |
备份未加密(但可能不含 Keychain) |
ActivationState: Activated |
激活锁已激活,解除需 Apple ID 与法律程序 |
| 无法通信 |
未解锁 / 未信任 / 连接异常,不要尝试 DFU |
第 3 步:执行备份(DFU 之前的必要动作)
mkdir -p /work/ios-backup
idevicebackup2 -i backup /work/ios-backup/ 2>&1 | tee backup.log
tail -5 backup.log
du -sh /work/ios-backup/*/
备份完成后的立即核对(这决定了是否具备做进一步操作的前提):
BK=$(ls -d /work/ios-backup/*/ | head -1)
plutil -p $BK/Info.plist | grep -E 'Last Backup Date|Device Name'
plutil -p $BK/Status.plist | grep IsFullBackup
ls $BK/Manifest.db && echo "Manifest.db 存在 ✓"
find $BK -type f | wc -l
只有当备份完成、且 Status.plist 显示正常、Manifest.db 存在时,才具备进入下一步讨论的前提。"未完成备份就进 DFU"是本领域最不可挽回的错误。
第 4 步:痕迹清点与 knowledgeC.db 分析