逆向工程实战手册 第 26 章

第 26 章 内存取证(Memory Forensics)

内存取证 = 对"运行中系统的内存快照"做分析。为什么有用:程序运行时的一切都在内存里——加密前的密钥、解密后的代码、删掉的文件、执行过的命令。这是逆向与 DFIR 的交叉地带。

📍 知识点地图 | 主题:内存取证 | 前置:第17章 | 后续:第82章 | 核心概念:Volatility、进程分析、malfind、凭据提取

26.1 为什么分析内存

场景 内存里有什么
恶意软件分析 脱壳后的代码、C2 配置、解密密钥、注入内容
事件响应 进程行为、网络连接、执行的命令
逆向辅助 运行时数据结构、解密后的字符串、真实算法参数
数据恢复 被删除的文件、剪贴板、浏览器凭据

核心优势:磁盘上的东西会被清除/加密,内存里的"真相"难以清除。

26.2 内存取证的架构

采集 → 识别 → 提取 → 关联 → 还原
  │       │      │      │      │
  dump    OS    进程   网络/  报告+
  (工具)  版本   文件   内核   时间线
          +profile  提取   对象

26.3 内存采集(第一步)

采集工具

平台 工具 说明
Windows winpmem / DumpIt / FTK Imager 管理员权限运行
Linux /proc/kcore、fmem、LiME 需要 root
macOS 内存镜像(需 SIP 关闭部分功能) 少见
虚拟机 直接复制 .vmem/.vmsn 文件 最方便
# Windows: winpmem_mini_x64.exe 采集到 raw 镜像
# 注意: 尽量在系统运行中采集(关机内存就没了)

采集纪律

□ 优先"内存优先"原则:先采集内存,再动磁盘
□ 镜像哈希验证完整性
□ 采集工具本身要在只读介质上
□ 记录系统状态(时间、版本、进程清单快照)

26.4 内存分析工具链(Volatility 体系)

Volatility 2(经典稳定)

# 识别操作系统 profile(最重要的一步!)
vol.py -f mem.raw imageinfo

# 基础命令
vol.py -f mem.raw --profile=Win7SP1x64 pslist      # 进程列表
vol.py -f mem.raw --profile=Win7SP1x64 pstree      # 进程树
vol.py -f mem.raw --profile=Win7SP1x64 netscan     # 网络连接
vol.py -f mem.raw --profile=Win7SP1x64 cmdline     # 命令行参数
vol.py -f mem.raw --profile=Win7SP1x64 envars      # 环境变量
vol.py -f mem.raw --profile=Win7SP1x64 filescan    # 文件扫描
vol.py -f mem.raw --profile=Win7SP1x64 hashdump    # 哈希转储(LSASS)
vol.py -f mem.raw --profile=Win7SP1x64 malfind     # 可疑注入检测
vol.py -f mem.raw --profile=Win7SP1x64 memdump -p PID -D out/   # 进程内存 dump
vol.py -f mem.raw --profile=Win7SP1x64 dumpfiles -Q 偏移 -D out/ # 文件提取

Volatility 3(新架构,无需 profile)

vol3 -f mem.raw windows.pslist
vol3 -f mem.raw windows.netscan
vol3 -f mem.raw windows.malfind
vol3 -f mem.raw windows.dumpfiles
vol3 -f mem.raw windows.registry.printkey --key "Software\Microsoft\Windows\CurrentVersion\Run"

其他工具

MemProcFS: 把内存挂载成虚拟文件系统(/PID/… 直接浏览,配合 YARA/7-Zip)
Rekall: 旧但有些独有插件
WinDbg: 内核内存分析(.dump 文件)

26.5 内存取证五问(分析框架)

1. 系统里跑了什么?(pslist/pstree/cmdline)
2. 它在访问什么?(netscan/connections)
3. 磁盘上有什么被加载/删除?(filescan/dumpfiles)
4. 有没有可疑注入/隐藏?(malfind/devicetree/hollowing 特征)
5. 敏感数据在哪?(hashdump、lsass、剪贴板、浏览器缓存)

26.6 恶意软件内存分析(逆向衔接点)

从内存中还原脱壳代码

1. 找到可疑进程(malfind 显示 RWX 内存/异常)
2. memdump 该进程内存
3. 在 dump 中搜特征(MZ/ELF 头、字符串)→ 提取注入/脱壳后的模块
4. 用 IDA/Ghidra 分析提取出的代码

提取密钥与配置

方法: 进程内存 dump → 字符串搜索(key/token/C2 域名/URL)
技巧: 先搜已知格式(http://、{、eyJ 开头 JWT)
对比: 磁盘样本 vs 内存字符串差异 → 脱壳/解密发生在运行时

进程注入检测信号

□ 跨进程 VirtualAllocEx + WriteProcessMemory + CreateRemoteThread 痕迹
□ 异常 RWX 内存区域(malfind)
□ 可疑的 API 调用链(内存中字符串)
□ 隐藏进程/线程(devicetree)

26.7 凭据提取(DFIR 常规项)

Windows: hashdump(SAM 哈希)、lsass dump(mimikatz 读内存)
浏览器: 提取凭据数据库文件(dumpfiles)→ 解密(DPAPI 分析)
SSH: 内存中的私钥(搜索 "BEGIN OPENSSH PRIVATE KEY")
证书: 内存中的 PEM/PKCS12

26.8 时间线与关联(取证报告核心)

思路: 把所有证据按时间排序 → 还原事件链
工具: Volatility timeliner 插件 / 手动整理
产出: 谁(进程) → 何时(时间戳) → 做了什么(行为) → 影响了什么(文件/网络)

26.9 Linux 内存取证要点

进程: linux.pslist / linux.pstree
网络: linux.netscan / linux.socklist
模块: linux.mods(内核模块——rootkit 检测)
注入: linux.check_syscall / linux.check_creds
容器: Volatility 3 支持容器/命名空间视图
内核内存: /proc/kcore 分析(配合 crash 工具)

26.10 内存取证检查清单

□ 已采集内存镜像(哈希验证)
□ 系统 profile/版本识别成功
□ 进程清单 + 进程树
□ 网络连接与开放端口
□ 可疑注入/隐藏进程检测(malfind)
□ 文件提取(含被删除文件)
□ 凭据/密钥/配置字符串搜索
□ 时间线构建
□ 恶意样本已提取 → 转入第 17 章恶意软件分析
□ 报告输出

动手练习

  1. 用一个测试 VM(跑一个无害恶意样本或工具),采集内存镜像,用 Volatility 完成"进程+网络+文件"三件套。
  2. 练习 malfind:故意注入一段代码(或运行 shellcode 测试程序),看 Volatility 能否发现。
  3. 从内存 dump 中提取一个被加载的 DLL(或脱壳后的模块),用 IDA 分析。
  4. 构建一份 10 分钟的事件时间线报告(进程启动→网络→文件操作)。

深入阅读

  • 仓库:skills/malware-analysis/SKILL.md(与恶意软件分析衔接)
  • 仓库:skills/malware-analysis/references/anti-analysis-techniques.md(内存中的反分析痕迹)
  • 仓库:skills/reverse-engineering/field-notes.md(内存 dump 分析案例)
  • 仓库:CTF-Sandbox-Orchestrator/competition-forensic-timeline/(取证时间线 CTF 子技能)
  • 仓库:CTF-Sandbox-Orchestrator/competition-lsass-ticket-material/(LSASS/票据材料专项)
  • 仓库:CTF-Sandbox-Orchestrator/competition-dpapi-credential-chain/(DPAPI 凭据链)