取证实战流程

前七篇讲"macOS 上有什么、怎么看"。

最后更新 2026-10-09版本 v1.0维护 DigiForensics查看历史 0

关键词:现场处置、FileVault、APFS 整体镜像、只读挂载、易失数据、工具链、封条、启动安全 难度:综合 前置知识:本板块01–07全部内容、镜像制作与只读分析规范

一、概述

前七篇讲"macOS 上有什么、怎么看"。

这一篇讲的是另一件事:从接手一台 Mac 到出报告,按什么顺序做。

三个现场特征直接决定流程怎么排:

特征 直接后果
FileVault 2 在 Monterey 之后默认开启 大多数新设备关机后即锁,不先解决密钥就什么都拿不到
APFS 多卷共享块池 单独镜像某个卷会丢失容器级元数据,完整性无法证明
Apple Silicon 只能启动签名映像 无法用传统外接启动盘现场启动取证环境,只能物理镜像

核心原则只有一条:先在不改写证据的前提下尽可能多取易失数据,再做物理镜像。

顺序错了,要么丢数据,要么破坏证据同一性。

另有三个现实必须显式处理:

现实 处理方式
统一日志、Spotlight 索引、内存态工件随关机消失 现场用 log show / mdfind 导出
macOS 上的恶意软件常主动检测取证环境 现场处置记录必须详尽
破坏 Apple 封条在法律上有明确后果 见 2.7

在取证流程中的位置:本篇是 macOS 板块的流程编排篇,横跨采集与报告两端,既不是"只读挂载怎么做"那种单点技术,也不是"某个工件怎么解析"。它的输入是"一台处于某种状态的机器",输出是一份完整处置链路:现场状态记录 → 零密钥结构确认 → 镜像制作 → 只读挂载与验证 → 按序提取 → 工具链与报告。顺序在这里是内容的一部分,不是格式——同一个动作放错位置,性质就从"取证"变成"改写证据"。所以它是这个板块的实际起点:前几篇是它的参考手册,最后几篇是它的深水区。

本篇处理的证据形态,按易失程度分四类,处置顺序由此决定:

优先级 证据 现场手段 丢失后果
P0 进程列表、网络连接、登录会话、打开的文件 ps auxww、netstat -an、who/w/lsof -nP,每份输出前置 date -u 关机即永久消失
P1 统一日志、Spotlight 索引与 kMDItemWhereFroms /usr/bin/log show --last 30d --info --style json、mdfind、mdutil -s 关机后只剩部分持久化部分
P2 硬件与系统标识、加密状态 system_profiler SPHardwareDataType(型号、Chip、序列号、Hardware UUID)、sw_vers、uptime、fdesetup status uptime 直接决定值不值得保持通电
P3 镜像与卷结构 整个 APFS 容器(不是单个卷)、diskutil apfs list、容器超级块 缺失则完整性声明站不住

每份现场输出都必须带采集时刻,且必须录像——屏幕内容、登录用户、连接状态都要入镜。零密钥阶段还有一层:FileVault 没解开时不碰数据,也能靠 diskutil apfs list 的容器与卷清单、ntfs/apfs 结构的可见部分确认这台机器上"应该有什么",这个结论本身就是有价值的产出。

本篇能回答什么:这台设备的型号、芯片、序列号与硬件 UUID、加密状态、卷与快照布局、通电时长、处置顺序为什么这么排,以及每个环节拿到了什么、每份输出的采集时刻。

本篇不能回答什么:顺序对了不等于数据全——关机状态下 Spotlight 索引与内存态工件已经没了,log show 导出的也只是持久化部分,报告里要写明"哪些易失项因设备关机未能获取"。FileVault 密钥不在这台机器上时,镜像做得再规范也只能做零密钥结构分析,此时能出的结论限于结构性判断(例如存在多少个用户卷、有没有加密的交换卷),内容层面一概不能碰,所以阴性表述的门槛在零密钥现场要高得多。uptime 短不代表没发生过什么,它只说明现场状态与事发状态可能已经隔开了,时间线断层必须写明。另外本篇给不出结论,结论要靠证据链与交叉验证得出(见 取证流程与原则);它也无法判断机器上运行的恶意软件具体做了什么——那要回到 plist、统一日志、LaunchAgents 与 Quarantine 的具体分析。

读者前提:需要先读完本板块前两篇,知道工件在哪些路径下;需要理解 FileVault 2 的加密范围与 APFS 容器/卷/共享块池的关系,这两件事直接决定"能不能取"和"怎么证明没被破坏";需要知道 Apple Silicon 的启动安全性机制意味着无法现场外接启动盘,这不是工具缺失而是平台限制,所以必须接受物理镜像这条唯一路径;还要接受一条纪律:封条、录像、采集记录本身就是交付物的一部分,现场处置记录越详细,复核时能还原的空间越大;最后需要具备现场判断能力——uptime 与封条状态这种信息只出现一次,判断错了没有第二次机会。


二、核心原理

2.1 现场处置决策树

收到一台 Mac
    │
    ├─ 已关机?──→ FileVault 状态?
    │              ├─ 已解锁 → 直接镜像
    │              └─ 已锁定 → ★ 必须先取得密钥
    │
    └─ 通电 ──→ ★ 关键决策点
          ├─ 近期有使用且易失数据有价值 → 先导出易失数据 → 关机 → 镜像
          ├─ 长期闲置、易失数据无价值     → 直接关机 → 镜像
          └─ 疑似作案进行中              → ★ 保持现状,立即记录全部现场状态

"是否关机"没有标准答案,只有权衡记录。

复核人看的不是结论对不对,而是当时的信息支撑下这个决策是否合理。

决策理由、决策人、时间必须写进现场记录。

2.2 FileVault 密钥的四条合法路径

路径 适用 说明
委托人当面解锁 最常见 在委托方或司法人员在场时输入口令,当场镜像
个人恢复密钥 委托人记得 Apple ID 账户可查
组织统一管理的恢复密钥 企业环境 IT 部门集中保管,需书面授权
依法向 Apple 调取 常规路径均不可行 需司法程序,周期长

fdesetup status

FileVault is Off. ← 未启用

FileVault is On. ← 已启用且已解锁(通电状态)

FileVault is Enabled, but not unlocked. ← ★ 已启用且已锁定(关机状态,最常见)

三条红线:报告只写"已使用合法取得的密钥解密",绝不记录密钥字符串;不得尝试暴力破解或绕过密钥派生;"已锁定"绝不等于"数据已销毁"——这个措辞是事实性错误。

2.3 APFS 容器整体镜像的必要性

这是 macOS 取证最贵的坑。

APFS 容器(disk0s2,494.4 GB)
├── 容器超级块(NXSB)        ← 块大小、总块数、块池分配表
├── 各卷的 B-tree 元数据      ← 文件名与 inode 映射
└── 共享块池
    ├── Macintosh HD(系统卷,只读签名)    ├── Macintosh HD - Data(用户数据)
    ├── Preboot(预启动)                   ├── Recovery(恢复)
    └── VM(交换)

单独 dd 某个卷会丢掉什么:

丢失的元数据 后果
容器超级块 无 NXSB 头,APFS 解析器可能直接拒绝打开
块池分配表 无法确定哪些块属于哪个卷,卷边界不可信
其他卷的元数据 缺 Preboot 会影响系统卷引导校验;缺 VM 丢失交换数据
快照索引 本地快照全部不可见,丢失"删除前内容"
sudo dd if=/dev/rdisk0   of=/Volumes/Evidence/DigiForensics.dd bs=4m status=progress  # ✓ 整盘
sudo dd if=/dev/rdisk0s2 of=/Volumes/Evidence/DigiForensics.dd bs=4m status=progress  # ✓ 整容器
sudo dd if=/dev/rdisk3s5 of=/Volumes/Evidence/DigiForensics.dd bs=4m                  # ✗ 只镜像数据卷

"容量够就行"是错误的。

数据卷显示的 447.8 GB 既不是该卷实际占用块数(共享块池中属于它的块是离散的),也不是完整证据范围。

正确做法是镜像整个容器或整盘。

2.4 只读挂载的三种路径

方式 命令 限制
Linux apfs-fuse(主力) apfs-fuse -r <key> -o vol=2,ro /dev/loop0 /mnt/mac-data ★ 默认只暴露一个卷;FileVault 需 -r
macOS mount_apfs sudo mount_apfs -o rdonly,nobrowse … 原生兼容性最好
镜像挂载 diskutil image attach -readonly DigiForensics.dd 快速查看卷布局

hdiutil attach 在现代 macOS 已弃用,实测会输出 'hdiutil attach ...' is deprecated. Please use 'diskutil image attach ...' instead.。报告里写命令要用 diskutil image attach。

只读挂载后必须做的事:记录挂载前的镜像 SHA-256,分析完成后卸载并重新校验哈希。这是"全程未改写证据"的可复核证明。只写"只读挂载"而没有哈希对比,等于没有证明。

2.5 易失数据的优先级

优先级 内容 采集命令 丢失后果
P0 进程与网络连接 ps auxww、netstat -an 完全丢失
P0 已登录用户与登录会话 who、w 完全丢失
P1 剪贴板 pbpaste 完全丢失
P1 统一日志(近 30 天) /usr/bin/log show --last 30d 部分丢失(.tracev3 解析难)
P1 Spotlight 索引查询结果 mdfind / mdls 完全丢失(二进制库无离线解析)
P2 打开的文件与网络挂载 lsof、mount 丢失
P3 FileVault 状态等 fdesetup status 关机后仍可从镜像取得

P0–P2 全部"关机即永久丢失",这就是"能不能关机"这个决策的核心依据。

2.6 Apple Silicon 与启动安全性

能力 Intel Mac Apple Silicon
外接启动盘启动系统 可(Option 键) ★ 不可(只能启动签名映像)
降低启动安全性策略 可(需管理员密码) 需另一台 Mac + 恢复固件更新(法律上通常不允许)
扣押后被引导攻击的风险 较高 ★ 较低

对取证的影响:Apple Silicon 上无法制作可启动的取证副本,只能逐块物理镜像后在分析机上分析。这不是技术缺陷,是安全设计的副作用。

2.7 封条与证据完整性

情形 风险
要求"保持原样"却破坏封条 证据同一性受质疑,委托方可能主张排除
拆机换盘导致来源链断裂 需额外说明拆机过程与新盘来源
涂抹机器标识 可能被认定为破坏证据

正确做法:开箱与拆机全程录像(覆盖封条原状、序列号、型号);记录封条编号与状态;拆机前取得书面授权并写明授权人、时间、范围;拆下部件单独封存编号,并记录它与主机的对应关系。


三、操作步骤

3.1 第 1 步:现场状态记录(通电状态下立即执行)

system_profiler SPHardwareDataType # 型号、Chip、序列号、Hardware UUID sw_vers; uptime # ★ uptime 判断是否值得保持通电 fdesetup status # ★ FileVault 状态

易失数据 P0(关机即永久丢失)

{ date -u '+%FT%TZ'; ps auxww; } > /evidence/live-ps.txt { date -u '+%FT%TZ'; netstat -an; } > /evidence/live-netstat.txt 2>&1 { date -u '+%FT%TZ'; who; w; lsof -nP; } > /evidence/live-users.txt 2>&1

易失数据 P1:统一日志与 Spotlight

/usr/bin/log show --last 30d --info --style json > /evidence/live-log-30d.json 2>/dev/null /usr/bin/log show --last 1h --info --style compact
--predicate 'subsystem == "com.apple.securityd" OR subsystem == "com.apple.network"' \

/evidence/live-log-security.txt 2>/dev/null mdfind -onlyin /Users/liwei "kMDItemWhereFroms == '*'" > /evidence/live-wherefroms.txt 2>/dev/null mdutil -s / > /evidence/live-mdutil.txt mount > /evidence/live-mount.txt; df -h > /evidence/live-df.txt

每份输出都要带采集时刻(上面已前置 date -u)。同时录像:屏幕内容、登录用户、连接状态都要入镜。

3.2 第 2 步:零密钥结构确认

取得密钥之前也有活可干,而且这些结论必须最先写进报告:

mmls /work/DigiForensics.dd # 找 APFS 分区起始扇区 APFS_PART=775920 xxd -s $((APFS_PART*512 + 32)) -l 16 /work/DigiForensics.dd

→ 4e585342 ... ← NXSB 魔数:确认是 APFS 容器、块大小

apfsutil -o $((APFS_PART*512)) /work/DigiForensics.dd # 卷列表、oid、快照

零密钥可得的结论:文件系统类型、块大小、卷数量与名称、各卷 oid、快照存在与否与创建时间。

这些不依赖任何密钥,成本最低,也最经得起复核。

3.3 第 3 步:镜像制作

diskutil list                             # 区分 (internal, physical) 与 (synthesized)
diskutil apfs list | grep -E 'APFS Container Reference|Volume Name|Capacity'
df -h /Volumes/Evidence                   # 目标 ≥ 容器标称容量 × 1.03
diskutil unmountDisk /dev/disk3           # 减少写入风险

sudo dd if=/dev/rdisk0   of=/Volumes/Evidence/DigiForensics.dd bs=4m status=progress
sudo dd if=/dev/rdisk0s2 of=/Volumes/Evidence/DigiForensics.dd bs=4m status=progress
shasum -a 256 /Volumes/Evidence/DigiForensics.dd | tee /evidence/DigiForensics.dd.sha256
纪律 原因
必须用 r 前缀设备 非 r 走缓冲 I/O,慢一个数量级
bs=4m 或更大 默认 512 字节块做 500 GB 镜像需数小时
完成后立即算 SHA-256 唯一能证明"之后没人改过"的方法
记录 dd 起止时间 与案件时间线对照
目标 ≥ 容器标称容量 × 1.03 APFS 独立卷与元数据开销不在主卷显示容量里

3.4 第 4 步:只读挂载与验证

shasum -a 256 /work/DigiForensics.dd > /evidence/baseline.sha256 # ★ 挂载前算基线 apfs-fuse -r "<恢复密钥>" -o vol=2,ro /dev/loop0 /mnt/mac-data

或:diskutil image attach -readonly /work/DigiForensics.dd

mount | grep apfs # 确认含 ro

EV=/mnt/mac-data ls -1 $EV/Users/ ls -1 $EV/Library/LaunchDaemons/ | wc -l ls -1 $EV/Users//Library/LaunchAgents/ | wc -l ls -1 $EV/var/db/diagnostics/Persist/ | wc -l ls -1 $EV/Users//Library/Containers/ | w