内存证据的可采性与报告

内存证据在法律程序上面临一个结构性的不对称:它和磁盘证据的所有保障机制都是为磁盘设计的。

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

关键词:证据保全、可复现性、Sysmon 事件 9、Sysmon 事件 11、采集痕迹、隐私最小化、证据链、交叉验证 难度:进阶 前置知识:Windows 事件日志与 Sysmon、证据链基本要求、报告写作规范

一、概述

内存证据在法律程序上面临一个结构性的不对称:它和磁盘证据的所有保障机制都是为磁盘设计的。

特征 磁盘证据 内存证据
可重复采集 ✅ 今天不采明天还能采 ❌ 只有一次机会
事后可验证 ✅ 可对同一设备重采并比对 ❌ 原始状态已消失
时间点 文件时间戳是固定的 内存是一个采集区间的混合体
完整性锚点 哈希 + 多次采集比对 哈希是唯一锚点(只有一个样本可比)
采集过程的证明 通常不必要(设备可复现状态) 必须证明"谁、何时、如何采的"
敏感度 取决于访问权限 可能含全部用户的明文数据

问题也随之而来。

你怎么证明这份镜像不是被人伪造的、不是上次采集的、不是从别的设备来的?答案有三层:

  1. 镜像哈希——锚定"这份文件自采集后未变"
  2. 采集记录——锚定"什么时候、谁、用什么工具采的"
  3. 目标机自身的日志——锚定"确实有人在目标机上做过内存采集"

第三层是很多办案人员不知道的:Windows 事件日志里能证明"有人从这台机器做了内存采集"。

这就是本篇的精华,也是内存证据链最容易被忽略的一环。

在取证流程中的位置:本篇不属于"从镜像里挖信息"的环节,它同时横跨采集的收尾与报告的成文两端——采集时它决定要留下哪些记录(Sysmon 必须事先部署,时间记录必须精确到秒),分析后它决定结论怎么写、哪些结论必须降级表述。所以它必须在采集前就被读完,采完再补是补不上的:Sysmon 没部署就没有事件,采集起止时间没记就永远说不清。这与本板块的 Volatility3 框架与插件选择(采集工具的取舍)和 进程与注入检测(分析结论怎么写)配套:采集方法决定镜像里有什么,可采性决定镜像能不能用,判读决定结论能写到什么程度。

本篇处理的证据形态,是三组证据加两组时间:

证据 具体位置与字段 作用
镜像哈希 采集后、分析前、分析后各算一次,三条必须完全一致 锚定"文件自采集后未变";这是唯一可信性锚点,因为只有一个样本可比
采集记录 采集开始/结束时间(精确到秒、含时区)、目标机系统时间(从 windows.info 的 SystemTime 读)、操作人与见证人 锚定"何时、谁、用什么工具采的"
Sysmon 采集痕迹 事件 9 RawAccessRead(Device 字段出现 \\.\PhysicalDrive0,这是全量物理内存采集的直接特征)、事件 11(TargetFilename 只能是普通文件路径,如 E:\evidence\DigiForensics-mem.raw)、事件 10(进程内存访问,更常出现在单进程转储场景)、事件 1、事件 6 与 System.evtx 7045 独立证明"有人在这台机器上做过内存采集",这是镜像哈希做不到的
时钟基准 目标机 SystemTime 必须落在采集起止区间内 目标机时钟不准时,所有时间线分析都带偏差,必须在报告里记录这个偏差
可复现性记录 每条命令、参数、工具版本、执行人、时间 让复核人能重走一遍;报告里"我们找到了 X"需要的是这个过程,不是结论本身

Sysmon 事件 9 单独不足以定性:读 \\.\PhysicalDrive0 也可能是磁盘取证工具或恶意软件在读磁盘。判据必须是组合证据——读到物理设备 + 产生了与目标机物理内存大小相当的文件。反过来,事件 10 也不是全量采集的主证据,把它当成主要证据是最常见的误判。

本篇能回答什么:这份内存镜像在什么时间区间采集、由谁操作、采集后是否被改动过、目标机上是否真的发生过一次物理内存读取、每条分析结论能否被别人按记录复现、哪些结论有交叉验证支撑。

本篇不能回答什么:镜像里有 X 只能证明"采集期间 X 存在于内存中"——它不能证明用户当时在屏幕上看到 X(内容可能在一个后台进程的缓冲区里,或者早已被换出到 swap);它不能证明采集那几分钟里系统状态没有变;它不能证明 X 不是在采集开始前几秒才被创建、或在采集后被覆盖。内存里找不到某个进程或某个密钥,只能表述为"在该镜像覆盖范围内未发现",未覆盖范围包括已被换出并释放的页、被覆盖的缓冲区、以及采集工具本身的局限——阴性结论在这里几乎没有证明力。Sysmon 的组合证据只证明"发生过采集",证明不了采到的内容有没有被替换;采集起止时间缺失时,任何指向具体行为的结论都无法归属到具体时刻。隐私上也要注意边界:内存里可能含全部用户的明文数据,这既是它的价值也是它的处置风险,报告只写与案件相关的那部分。

读者前提:需要先掌握 Sysmon 与日志聚合(部署必须发生在事发前,本篇的所有日志证据都建立在那篇的配置上,没部署就是没有);需要理解 .evtx 的解析与 EventData 字段的准确位置——事件 9 的 Device 与事件 11 的 TargetFilename 字段集不同,混用会导致检索为空;需要接受"可复现性记录"这个交付要求,并知道它要求你在动手前把命令和参数写下来而不是事后回忆;还需要理解隐私最小化原则在取证报告里的适用方式——写出哈希存在于哪个文件的哪个偏移、属于哪个 RID 账户,而不是把口令或密钥原文直接写进正文。


二、核心原理

2.1 内存证据的四个特有问题

问题一:易失性 → 采集时间必须精确到秒

内存证据的价值几乎全部来自"它记录的是某个特定时刻的状态"。三类时间缺一不可:

时间 说明 为什么必要
采集开始时间 精确到秒,含时区 内存证据代表的区间起点
采集结束时间 精确到秒,含时区 区间终点;两者之差即采集耗时
目标机系统时间 从 windows.info 的 SystemTime 读出 验证目标机时钟与采集机时钟是否一致

目标机时钟偏差是真实的坑。目标机时钟不准(手动改过、未同步、时区设错)时,"采集时间"与"内存中记录的时间"就无法对齐。必须交叉比对:SystemTime 落在采集起止区间内 → 时钟基本可信;偏离很大 → 必须在报告中记录这个偏差,因为它影响所有时间线分析。

问题二:无法重复采集

磁盘取证可以「再采一遍看看是否一样」来验证,内存做不到。

所以:采集过程必须一次做对(中途失败只能重来,而重来的那次已经不是「原始状态」);不能「先试试能不能采到」;必须双人确认(一人操作、一人见证)。

问题三:哈希是唯一可信性锚点

既然只有一份样本,「完整性」只能靠哈希保证,且采集后、分析前、分析后三条哈希必须完全一致。任何一条不一致,镜像的可用性就要打问号。命令见 3.5。

问题四:「当时内存里有什么」无法事后重建

你可以确定的:镜像里有 X(因为镜像里有 X)
你不能确定的:采集那一刻用户是否"看得到" X
                采集那 5 分钟里系统是否一直在变
                X 是否在采集前几秒才被创建
                X 是否在采集后被覆盖(而你在镜像里看到的是"更早"的副本)

一个具体例子:你在内存里找到一个敏感文件的内容。这证明"该文件的内容在采集期间存在于内存中"。但不能证明"用户当时在屏幕上看到它"——内容可能在一个后台进程里,或者在采集开始前就已经被换出到 swap 了。

2.2 采集痕迹:目标机日志能独立证明「有人采过内存」

这是内存证据链最关键、也最容易被忽略的一环。

为什么需要它:如果某方对内存镜像提出质疑(「你怎么证明这不是编的?」),镜像自身的哈希只能证明「文件没被改」,不能证明「它确实来自那台设备」。

目标机自身的日志能提供这个证明——而且它独立于分析过程,不可由分析人员构造。

Windows 上做内存采集必然产生痕迹:读取物理设备(Sysmon 事件 9)、创建大文件(事件 11)、访问进程内存(事件 10)、采集工具进程创建(事件 1)、驱动加载(事件 6 / System.evtx 7045)。

Sysmon 需要提前部署。没有 Sysmon 的机器上不会有这些事件——日志侧证据的存在与否,取决于采集之前有没有做日志部署准备。详见 2.4。

2.3 四个关键事件(以及为什么不能只看 10)

事件 含义 与内存采集的对应
ID 9 RawAccessRead 通过 \\.\ 句柄直接读卷 全量物理内存采集的直接特征(绕过文件系统)
ID 10 ProcessAccess 打开另一个进程,带 GrantedAccess 掩码 单进程转储(如只转储 LSASS)的特征
ID 11 FileCreate 创建/覆盖文件 镜像落盘路径的直接证据
ID 1 ProcessCreate 进程创建 采集工具自身被启动,含完整命令行
ID 6 DriverLoad 驱动加载 采集用的驱动

⚠️ 最常见的误判:拿事件 10 当内存采集的主要证据。事件 10 反映的是进程内存访问,而全量物理内存读取走的是磁盘设备路径(事件 9)。事件 10 更常出现在单进程转储场景。两者都要查,且事件 9 才是全量采集的主证据。

事件 9 本身也不足以定性:读 \\.\PhysicalDrive0 也可能是磁盘取证工具或恶意软件在读磁盘。判定要靠组合证据:读到物理设备 + 产生了与内存大小相当的文件 = 内存采集。

字段位置不能混:\\.\PhysicalDrive0 出现在事件 9 的 Device 字段;事件 11 的 TargetFilename 只能是普通文件路径(如 E:\evidence\DigiForensics-mem.raw),不可能是物理设备路径。** GrantedAccess 常见掩码(事件 10)**:0x1010 = PROCESS_VM_READ + PROCESS_QUERY_LIMITED_INFORMATION(凭据转储的典型)。

0x1410 含 PROCESS_VM_OPERATION(改内存)。

0x1f0fff 含 PROCESS_VM_WRITE(注入)。

0x1fffff 全部权限。

这一串掩码值要背下来。事件 10 一旦筛出来,第一眼就该看 GrantedAccess——它直接告诉你对方想读还是要写。

2.4 部署 Sysmon(必须在事发前完成)

这是本篇最重要的实务建议:如果目标环境没有部署 Sysmon,事后无法补做。

一个极端情况值得先想清楚:如果目标机从装机起就没开过 Sysmon,你手上一份采集完的镜像,日志侧那一层证据永远是空的。方案设计阶段决定的事,报告阶段补不回来。

<!-- 最小化配置:只启用内存采集相关事件,降低噪声 -->
<Sysmon version="4">
  <EventFiltering>
    <ProcessAccess onmatch="include">
      <GrantedAccess>0x1010</GrantedAccess>   <!-- VM_READ -->
      <TargetImage>C:\Windows\System32\lsass.exe</TargetImage>
    </ProcessAccess>
    <RawAccessRead onmatch="include" />
  </EventFiltering>
</Sysmon>
# 安装(需管理员) / 卸载
Sysmon64.exe -accepteula -i config.xml
Sysmon64.exe -u

部署 Sysmon 本身会改变系统状态,应在取证方案中提前设计。若因合规要求不能安装 Sysmon,应在报告中明确写出"该机未部署 Sysmon,采集痕迹无法从日志侧验证"作为证据链局限。

2.5 隐私与最小化原则

内存镜像可能包含所有登录用户的明文口令、Token、会话票据、聊天记录、邮件正文、未保存文档,以及与案件无关的第三方个人信息——敏感度远高于磁盘镜像。

四个层次的最小化做法:

层次 做法
采集时 只在授权范围内采集;能不采全量就不采全量(单进程转储 > 全量镜像)
分析时 只提取与案件相关的工件;不"顺便"翻看无关内容
报告时 敏感内容脱敏或不展示;凭据只说"存在"不贴明文(见第 07 篇)
归档时 镜像按最高密级保管;分析副本用完销毁;记录销毁动作

一个实用的判断标准:如果一个证据细节与案件无关,它就不该出现在报告里。 可以分析,但不必记录。

举例:分析中看到某员工与案件无关的私人聊天记录——它不构成证据,不应写入报告。

2.6 结论必须交叉验证

内存发现 交叉验证来源
外部 IP 连接 防火墙日志、代理日志、NetFlow、威胁情报
域名 浏览器历史、DNS 缓存日志、Sysmon 事件 22(DNS Query)
文件路径 $MFT、$UsnJrnl、$LogFile、Prefetch、ShimCache
程序执行 Prefetch、ShimCache、UserAssist、Amcache、事件日志 4688
时间点 事件日志时间戳(比内存精度高得多)
进程父子关系 事件日志 4688、Sysmon 事件 1
凭据 认证日志 4624/4625、域控日志

内存的时序精度低于磁盘。这一点反直觉,但很重要。

磁盘上的 FILETIME 精确到 100 纳秒且是固定值;内存里的时间受采集耗时影响,可能偏差数分钟。

所以"谁先执行、谁后执行"这类因果排序,应该以事件日志为准,内存用于确认"确实发生过"。

这条结论的上游是易失性顺序与采集时机窗口,采集前就该据此判断值不值得冒险采,回看见第 01 篇。


三、操作步骤

3.1 第 1 步:采集记录模板(现场填写)

【内存采集记录】
1. 目标机识别:设备序列号/资产编号、主机名、OS 与 Build、
   物理内存大小、磁盘序列号、MAC 地址
2. 采集信息
   采集人:  见证人:  采集地点:
   采集开始(含时区):  采集结束(含时区):  采集耗时:
   采集方式(现场/远程/网络推送):
   采集期间保持开机:是/否    采集期间有用户活动:是/否
3. 工具信息
   工具名称与版本:  工具文件 SHA-256:  工具来源:
   是否为目标机原装:是/否
4. 状态变更记录
   是否加载驱动:(驱动名与路径)  是否加载内核模块:
   是否修改 SELinux:(变更前后状态)  其他状态变更:
5. 产物
   镜像文件名:DigiForensics-mem.raw
   镜像大小(字节):  镜像 SHA-256:  哈希计算时间:  存储介质编号:

这份记录本身就是证据。它比事后任何描述都可靠,因为它是在现场、即时填写的。空白项也要保留并注明"不适用",不能事后补写。

3.2 第 2 步:Sysmon 事件查询

# 前提:已从目标机提取 Sysmon 日志
# 路径:C:\Windows\System32\winevt\Logs\Microsoft-Windows-Sysmon\Operational.evtx
evtx_dump.py /evidence/logs/Sysmon.evtx | grep -A 20 'EventID.*9' \
  | grep -iE 'UtcTime|Image|Device'                # 事件 9:Device = \\.\PhysicalDrive0
evtx_dump.py /evidence/logs/Sysmon.evtx | grep -A 20 'EventID.*11' \
  | grep -iE 'UtcTime|Image|TargetFilename'        # 事件 11:TargetFilename = 普通文件路径
evtx_dump.py /evidence/logs/Sysmon.evtx | grep -A 25 'EventID.*1' \
  | grep -iE 'UtcTime|Image|CommandLine'          # 事件 1:采集工具进程与命令行
evtx_dump.py /evidence/logs/Sysmon.evtx | grep -A 25 'EventID.*10' \
  | grep -iE 'UtcTime|SourceImage|TargetImage|GrantedAccess'   # 事件 10:单进程内存访问

# 把事件时间与镜像文件创建时间对齐(BSD 与 GNU stat 均可)
stat -c '%w' DigiForensics-mem.raw 2>/dev/null \
  || stat -f '%SB' -t '%Y-%m-%d %H:%M:%S' DigiForensics-mem.raw
# → 2026-03-14 10:23:45 +0800,与事件 11 的 02:23:45 UTC 一致 → 互相印证

3.3 第 3 步:无 Sysmon 时的替代路径