计算机内存取证技术
原文作者:徐志强 日期:2018年6月10日
一、 计算机物理内存简介
计算机的物理内存一般我们指的就是随机存取存储器(Random Access Memory,简称RAM)。内存是一种易失性存储载体,它保存处理器主动访问和存储的代码和数据,是一个临时的数据交换空间。大多数的PC的内存属于一种动态RAM(DRAM)。 它是动态变化的,因其利用了电容器在充电和放电状态间的差异来存储数据的比特位。 为了维持电容器的状态,动态内存必须周期性刷新- 这也是内存控制器最典型的任务。
由于计算机的内存(DRAM)需要持续供电才能保持数据可持续访问,因此也称为易失性存储。美国普林斯顿大学曾做过关于计算机冷启动攻击的研究,计算机在断电后,在很短的时间内内存的数据就会消失,然而通过液态氮冷却,可以将内存中的数据进行冻结,再通过一些技术方法来解冻并获取原来的内存数据。以下我们先了解一下与内存相关的基本概念。
地址空间(Address Space)
CPU处理器要在执行指令并访问存储与内中的数据,它必须为要访问的数制定一个唯一性地址。地址空间指的就是一组大量的有效地址,可用于去识别存储与有限的内存分配空间中的数据。一个正在运行的程序可以访问的单个连续的地址空间一般称为线性地址空间。基于内存模型及采用的分页模式,我们有时将其称为线性地址,有时称为虚拟地址。通常我们使用物理地址空间来特指处理器请求访问物理内存的地址。这些地址是通过将线性地址转化为物理地址来获得。
内存分页(Paging)
从抽象意义上来讲页是一个具有固定尺寸的窗口,从逻辑意义上来讲页是具有固定大小的一组连续线性地址的集合。
分页可以将线性地址空间进行虚拟化。它创建了一个执行环境,大量线性地址空间通过用适量的物理内存和磁盘存储进行模拟。每一个32位的线性地址空间被分为固定长度的片段,称为页(Page),页可以任何顺序将线性地址空间映射为物理内存。 当程序尝试访问线性地址时,这样的映射使用了驻留内存的页目录(Page Directory)及页表(Page Table)来实现。
一个页的大小可以指定为4KB(212=4KB)的任意倍数,这根据不同的体系结构或操作系统的设置而定,而x86架构下的Windows/Linux均采用4KB大小的分页方式,这就说明32位线性地址中必定存在一个12位的指示页内偏移量的域。
物理地址扩展
Intel公司的32位架构的内存分页机制支持物理地址扩展(Physical Address Extension ,简称PAE),该扩展支持允许处理器支持超过4GB的物理地址空间。
程序虽然仍只能拥有最高4GB的线性地址空间,但是内存管理单元可以将那些地址映射为扩展后的64GB物理地址空间。对于支持PAE功能的系统,线性地址分为四个索引:
- 页目录指针表(Page directory pointer table,简称PDPT)
- 页目录(Page directory,简称PD)
- 页表(Page table,简称PT)
- 页偏移(Page offset)
二、 物理内存中数据的价值
计算机终端及移动终端均使用了RAM易失性存储,主要用于数据交换、临时存储等用途。操作系统及各种应用软件均经常需要与物理内存进行数据交互,此外由于内存空间有限,因此计算机系统还可能将内存中的数据缓存到磁盘中,如pagefile.sys(页交换文件)及hiberfil.sys(休眠文件)。
内存中有大量的各类数据,结构化及非结构化数据。通过对物理内存镜像可以提取出有价值的数据。 常见有价值的数据,包含以下内容:
- 进程列表(包括恶意程序进程、Rootkit隐藏进程等)
- 动态链接库(当前系统或程序加载的动态链接库)
- 打开文件列表(当前系统打开的文件列表)
- 网络连接(当前活动的网络连接)
- $MFT记录(常驻文件均可以直接提取恢复)
- 注册表(部分注册表信息,包括系统注册表和用户注册表文件)
- 加密密钥或密码(如Windows账户密码Hash、BitLocker/SafeBoot/PGP/ TrueCrypt/VeraCrypt等全盘加密或加密容器的恢复密钥等)
- 聊天记录(如QQ聊天记录片段)
- 互联网访问(上网记录URL地址、网页缓存及InPrivate隐私模式访问数据等)
- 电子邮件(如网页邮件缓存页面)
- 图片及文档等(尚未保存到磁盘中的图片、文档等文件)
页交换文件(Pagefile.sys)
除了使用物理内存RAM用于数据交换,Windows为了能正常工作还使用了各种各样的文件。从Windows 95开始,Windows开始引入了页交换文件(Pagefile.sys)来协助内存数据的交换。 Pagefile.sys是磁盘中的一个文件,它用于将操作系统中的活动数据临时性地进行存储,在必要的情况下,Windows可将Pagefile.sys文件的中数据移动到物理内存中或从内存中将数据移到该文件中,实现数据的临时交换或缓存。从Pagefile.sys中获得的数据通常是当前活动的相关信息,也通常与调查相关性较高。
Windows操作系统最多支持16个页交换文件。启用物理地址扩展功能(PAE)的Windows 32位和64位系统的最大页交换文件大小为16TB。64位的安腾架构(Itanium)的系统的页交换文件可以支持高达32TB。 页交换文件大小的默认值为计算机物理内存大小的1.5至3倍。
Pagefile.sys用于存储从物理内存中转移过来的数据。 要获得一个正在运行的系统的活动全貌或快照,我们通常除了分析物理内存,还需要分析pagefile.sys。 部分工具支持同时将物理内存和pagefile.sys进行检查分析。通常pagefile.sys文件放置于操作系统所在分区,当然用户也完全可能修改高级设置或注册表调整pagefile.sys的存储位置。
从Windows 7操作系统版本开始,Windows系统开始支持页交换文件pagefile.sys的加密。
休眠文件(HiberFil.sys)
Hiberfil.sys是当系统休眠时,Windows将物理内存的数据写入到磁盘生成的一个文件。当系统进入休眠状态后,网络连接将会中断。 当系统重新加电时,hiberfil.sys文件中的数据重新回写到物理内存中,这也使得从休眠状态恢复到原始状态变得相当快。
休眠文件包含了标准的头部(PO_MEMORY_IMAGE),包含了内核上下文与寄存器的相关信息及压缩的数据块。该文件采用了Xpress算法(带霍夫曼Huffman及LZ编码)。 文件头部通常包含了“hibr”、“HIBR”、“wake”或“WAKE”等特征。 操作系统从休眠状态恢复后,头部就被清零了。清零后的文件头可能导致一些取证软件无法分析该文件。
通过分析hiberfil.sys文件的修改时间戳信息,我们可以了解到该系统最后一次休眠的时间。系统中的休眠文件hiberfil.sys只有一个。当系统重新休眠时,当前物理内存中的内容将会覆盖原有文件的数据。 要对hiberfil.sys进行分析,要求取证工具可以将休眠文件中的数据进行解压为原生数据并进行数据解析。Mattieu Suiche的Windows Memory Toolkit工具hibr2bin.exe支持将休眠文件转为原生转储文件。
当取证人员在现场要制作Windows操作系统的物理内存镜像时,可能由于内存镜像工具不兼容操作系统导致无法获取物理内存数据。当无法成功制作物理内存镜像时,还可以让系统进入休眠模式,从而用变通的方式获得物理内存中的数据。
要进入休眠模式,首先要让系统启用休眠模式支持。Windows 8及以上版本的操作系统,默认启用休眠模式支持。取证人员也可以管理员权限进入命令行模式,并输入powercfg.exe /hibernate ON 来启用休眠模式支持。要让操作系统进入休眠模式,需要输入shutdown /h .
Vista以上操作系统在原有支持休眠模式(Hibernate Mode)的基础上增加了睡眠模式(Sleep Mode)。睡眠模式状态下,操作系统使用极少的电量保证内存可以继续工作,一旦系统电量不足,系统将保存所有内存数据到磁盘并关闭计算机。而休眠模式状态下,系统关闭,将内存中的数据写入休眠文件hiberfil.sys中。
在默认的Windows开始菜单中的“电源”找不到“休眠”,可以通过按Win+X键,选择“控制面板”,找到“硬件和声音”->“电源选项”->“选择电源按钮的功能”,选择“更改当前不可用的设置”,在“关机设置”下将“休眠”选项勾选。后续在开始菜单选择“电源”即可直接看到“休眠”选项。
三、 Windows 内存取证方法和分析技术
内存取证(Memory Forensics)通常指对计算机及相关智能设备运行时的物理内存中存储的临时数据进行获取与分析,提取有价值的数据。内存是操作系统及各种软件交换数据的区域,数据易丢失(Volatile),通常在关机后数据很快就消失。
常见物理内存获取方法:冷启动攻击(Cool Boot Attack)、基于火线(1394)或雷电 (ThunderBolt)接口的直接内存访问(DMA)获取及内存获取软件工具。
不同的操作系统需要用到不同的物理内存获取工具。
Windows操作系统平台支持内存获取的常见工具有:
- DumpIt (早期版本名为Win32dd)
- Belkasoft RAMCapturer
- Magnet RAM Capture
- WinEn
- Winpmem
- EnCase Imager
- FTK Imager
- 取证大师
- 取证神探
Linux操作系统常见的内存获取工具:
- dd (适合Linux早期版本)
- LiME http://code.google.com/p/lime-forensics/
- linpmem
- Draugr http://code.google.com/p/draugr/
- Volatilitux http://code.google.com/p/volatilitux/
- Memfetch http://lcamtuf.coredump.cx/
- Memdump
Mac OSX操作系统内存获取工具有:
- MacMemoryReader
- osxpmem
- Recon for Mac OSX
- Blackbag MacQuisition
Windows操作系统平台下的DumpIt是一个简单易用的计算机内存镜像获取工具。通常直接将该工具存放在大容量移动硬盘或优盘中。可直接在正在运行Windows系统的平台直接运行,根据提示操作即可。
在获取物理内存数据时还需尽量减少对原有内存数据的覆盖,最大程度提取处内存数据。
内存分析技术
Windows操作系统获取出的物理内存镜像需要使用专门的内存分析工具。常见的内存分析工具有Volatility、Rekall、Forensic Toolkit(FTK)、取证大师及取证神探等,可以解析出常见的基本信息,包括进程信息、网络连接、加载的DLL文件及注册表加载信息等。
Volatility Framework
Volatility Framework是一个完全开放的内存分析工具集,基于GNU GPL2许可,以python语言进行编写。由于Volatility是一款开源免费的工具,无需花任何钱即可进行内存数据的高级分析,此外代码开源的特点,遇到一些无法解决的问题时,还可以对源代码进行修改或扩展功能。
在开始使用Volatility之前,我们需要先了解它具有哪些特色功能。
- 即独立又整体统一的框架
支持32位和64位操作系统的内存分析(如Windows、Linux、Mac系统及32位的Android系统)。Volatility的模块化设计允许快速对未来新发布的操作系统进行支持。
- 开放源代码(GPL v2)
意味着可以自行阅读源代码,对源代码进行学习及功能扩充。 通过了解和学习Volatility的工作机制,你也可以成为一名更有效的分析专家。
- 基于Python语言编写
Python是一个公认的取证及逆向工程语言,带有丰富的库文件,也容易集成到Volatility。
- 跨平台运行支持
Volatility只要系统平台有Python运行环境即可运行,因此在Windows、Linux或Mac系统中都可以方便地运行。
- 程序接口扩展性强、脚本编程支持
Volatility让取证人员可以不断创新,自行扩展新功能,例如新增支持恶意程序沙盒分析、虚拟机检测、自动浏览内核内存等功能。
- 丰富的文件格式支持
支持原始数据转储(Raw Dump)、崩溃转储(Crash Dump)、休眠文件及各种其它格式,甚至可以支持多个格式之间的转换。
- 快速高效的算法支持
与其它工具相比,Volatility具备快速高效的分析内存转储文件分析能力,无需消耗多余的内存。
- 社区支持
Volatility的共享者来自各行各业,商业公司、执法部门、学术机构及全球各行业人士。
Volatility支持的操作系统版本
- 64-bit Windows Server 2016
- 64-bit Windows Server 2012 及2012 R2
- 32- and 64-bit Windows 10
- 32- and 64-bit Windows 8, 8.1, and 8.1 Update 1
- 32- and 64-bit Windows 7 (支持所有Service Pack)
- 32- and 64-bit Windows Server 2008 (支持所有Service Pack)
- 64-bit Windows Server 2008 R2 (支持所有Service Pack)
- 32- and 64-bit Windows Vista (支持所有Service Pack)
- 32- and 64-bit Windows Server 2003 (支持所有Service Pack)
- 32- and 64-bit Windows XP (SP2 和 SP3)
- 32- and 64-bit Linux kernels (2.6.11 ~ 4.2.3)
- 32-bit 10.5.x Leopard (64-bit 10.5 Server尚未支持)
- 32- and 64-bit 10.6.x Snow Leopard
- 32- and 64-bit 10.7.x Lion
- 64-bit 10.8.x Mountain Lion
- 64-bit 10.9.x Mavericks
- 64-bit 10.10.x Yosemite
- 64-bit 10.11.x El Capitan
- 64-bit 10.12.x Sierra
Volatility支持的内存镜像格式
- 原始物理内存镜像格式
- 火线获取内存格式(IEEE 1394)
- EWF格式(Expert Witness)
- 32- and 64-bit Windows 崩溃转储文件(Crash Dump)
- 32- and 64-bit Windows 休眠文件 (Windows 7及早期版本)
- 32- and 64-bit MachO 文件
- Virtualbox Core Dumps
- VMware 保存状态文件 (.vmss) 及快照文件(.vmsn)
- HPAK 格式 (FastDump)
- QEMU 内存转储文件
在Windows系统平台下,有两种方式可以运行Volatility工具。第一种是独立安装Python运行环境,再下载Volatility源代码执行命令行。第二种为下载Volatility独立Windows程序(无需另外安装和配置Python环境)。最新Volatility版本为v2.6,可以通过官方网站进行下载。
在Windows 64位平台,最便捷的方式就是直接使用独立Windows程序的Volatility版本。进入管理员命令行模式,运行volatility_2.6_win64_standalone.exe 程序即可。
Volatility常用命令行参数
- -h 查看相关参数及帮助说明
- –info 查看相关模块名称及支持的Windows版本
- -f 指定要打开的内存镜像文件及路径
- -d 开启调试模式
- -v 开启显示详细信息模式(verbose)
由于帮助说明内容太多,通常可以将内容输出为文本文件,方便随时打开参数及模块支持列表。
- volatility_2.6_win64_standalone.exe -h > help.txt
- volatility_2.6_win64_standalone.exe –info > modules_list.txt
表格 1 Volatility支持的插件列表
插件名称 | 功能 |
amcache | 查看AmCache应用程序痕迹信息 |
apihooks | 检测内核及进程的内存空间中的API hook |
atoms | 列出会话及窗口站atom表 |
atomscan | Atom表的池扫描(Pool scanner) |
auditpol | 列出注册表HKLM\SECURITY\Policy\PolAdtEv的审计策略信息 |
bigpools | 使用BigPagePoolScanner转储大分页池(big page pools) |
bioskbd | 从实时模式内存中读取键盘缓冲数据(早期电脑可以读取出BIOS开机密码) |
cachedump | 获取内存中缓存的域帐号的密码哈希 |
callbacks | 打印全系统通知例程 |
clipboard | 提取Windows剪贴板中的内容 |
cmdline | 显示进程命令行参数 |
cmdscan | 提取执行的命令行历史记录(扫描_COMMAND_HISTORY信息) |
connections | 打印系统打开的网络连接(仅支持Windows XP 和2003) |
connscan | 打印TCP连接信息 |
consoles | 提取执行的命令行历史记录(扫描_CONSOLE_INFORMATION信息) |
crashinfo | 提取崩溃转储信息 |
deskscan | tagDESKTOP池扫描(Poolscaner) |
devicetree | 显示设备树信息 |
dlldump | 从进程地址空间转储动态链接库 |
dlllist | 打印每个进程加载的动态链接库列表 |
driverirp | IRP hook驱动检测 |
drivermodule | 关联驱动对象至内核模块 |
driverscan | 驱动对象池扫描 |
dumpcerts | 提取RAS私钥及SSL公钥 |
dumpfiles | 提取内存中映射或缓存的文件 |
dumpregistry | 转储内存中注册表信息至磁盘 |
editbox | 查看Edit编辑控件信息 (Listbox正在实验中) |
envars | 显示进程的环境变量 |
eventhooks | 打印Windows事件hook详细信息 |
evtlogs | 提取Windows事件日志(仅支持XP/2003) |
filescan | 提取文件对象(file objects)池信息 |
gahti | 转储用户句柄(handle)类型信息 |
gditimers | 打印已安装的GDI计时器(timers)及回调(callbacks) |
gdt | 显示全局描述符表(Global Descriptor Table) |
getservicesids | 获取注册表中的服务名称并返回SID信息 |
getsids | 打印每个进程的SID信息 |
handles | 打印每个进程打开的句柄的列表 |
hashdump | 转储内存中的Windows帐户密码哈希(LM/NTLM) |
hibinfo | 转储休眠文件信息 |
hivedump | 打印注册表配置单元信息 |
hivelist | 打印注册表配置单元列表 |
hivescan | 注册表配置单元池扫描 |
hpakextract | 从HPAK文件(Fast Dump格式)提取物理内存数据 |
hpakinfo | 查看HPAK文件属性及相关信息 |
idt | 显示中断描述符表(Interrupt Descriptor Table) |
iehistory | 重建IE缓存及访问历史记录 |
imagecopy | 将物理地址空间导出原生DD镜像文件 |
imageinfo | 查看/识别镜像信息 |
impscan | 扫描对导入函数的调用 |
joblinks | 打印进程任务链接信息 |
kdbgscan | 搜索和转储潜在KDBG值 |
kpcrscan | 搜索和转储潜在KPCR值 |
ldrmodules | 检测未链接的动态链接DLL |
lsadump | 从注册表中提取LSA密钥信息(已解密) |
machoinfo | 转储Mach-O 文件格式信息 |
malfind | 查找隐藏的和插入的代码 |
mbrparser | 扫描并解析潜在的主引导记录(MBR) |
memdump | 转储进程的可寻址内存 |
memmap | 打印内存映射 |
messagehooks | 桌面和窗口消息钩子的线程列表 |
mftparser | 扫描并解析潜在的MFT条目 |
moddump | 转储内核驱动程序到可执行文件的示例 |
modscan | 内核模块池扫描 |
modules | 打印加载模块的列表 |
multiscan | 批量扫描各种对象 |
mutantscan | 对互斥对象池扫描 |
notepad | 查看记事本当前显示的文本 |
objtypescan | 扫描窗口对象类型对象 |
patcher | 基于页面扫描的补丁程序内存 |
poolpeek | 可配置的池扫描器插件 |
printkey | 打印注册表项及其子项和值 |
privs | 显示进程权限 |
procdump | 进程转储到一个可执行文件示例 |
pslist | 按照EPROCESS列表打印所有正在运行的进程 |
psscan | 进程对象池扫描 |
pstree | 以树型方式打印进程列表 |
psxview | 查找带有隐藏进程的所有进程列表 |
qemuinfo | 转储Qemu 信息 |
raw2dmp | 将物理内存原生数据转换为windbg崩溃转储格式 |
screenshot | 基于GDI Windows的虚拟屏幕截图保存 |
servicediff | Windows服务列表(ala Plugx) |
sessions | _MM_SESSION_SPACE的详细信息列表(用户登录会话) |
shellbags | 打印Shellbags信息 |
shimcache | 解析应用程序兼容性Shim缓存注册表项 |
shutdowntime | 从内存中的注册表信息获取机器关机时间 |
sockets | 打印已打开套接字列表 |
sockscan | TCP套接字对象池扫描 |
ssdt | 显示SSDT条目 |
strings | 物理到虚拟地址的偏移匹配(需要一些时间,带详细信息) |
svcscan | Windows服务列表扫描 |
symlinkscan | 符号链接对象池扫描 |
thrdscan | 线程对象池扫描 |
threads | 调查_ETHREAD 和_KTHREADs |
timeliner | 创建内存中的各种痕迹信息的时间线 |
timers | 打印内核计时器及关联模块的DPC |
truecryptmaster | 恢复TrueCrypt 7.1a主密钥 |
truecryptpassphrase | 查找并提取TrueCrypt密码 |
truecryptsummary | TrueCrypt摘要信息 |
unloadedmodules | 打印卸载的模块信息列表 |
userassist | 打印注册表中UserAssist相关信息 |
userhandles | 转储用户句柄表 |
vaddump | 转储VAD数据为文件 |
vadinfo | 转储VAD信息 |
vadtree | 以树形方式显示VAD树信息 |
vadwalk | 显示遍历VAD树 |
vboxinfo | 转储Virtualbox信息(虚拟机) |
verinfo | 打印PE镜像中的版本信息 |
vmwareinfo | 转储VMware VMSS/VMSN 信息 |
volshell | 内存镜像中的shell |
windows | 打印桌面窗口(详细信息) |
wintree | Z顺序打印桌面窗口树 |
wndscan | 池扫描窗口站 |
yarascan | 以Yara签名扫描进程或内核内存 |
查看系统进程列表
volatility_2.6_win64_standalone.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 pslist
将进程列表导出为txt文件
volatility_2.6_win64_standalone.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 pslist > Win7_SP1_x86_pslist.txt
查看网络通讯连接信息
volatility_2.6_win64_standalone -f Win7_SP1_x86.vmem –profile=Win7SP1x86 netscan
提取内存中的注册表信息
volatility_2.6_win64_standalone -f Win7_SP1_x86.vmem –profile=Win7SP1x86 dumpregistry
提取内存中的MFT记录信息
volatility_2.6_win64_standalone -f Win7_SP1_x86.vmem –profile=Win7SP1x86 mftparser
导出内存中的MFT记录数据
volatility_2.6_win64_standalone -f Win7_SP1_x86.vmem –profile=Win7SP1x86 mftparser –output-file=mftverbose.txt -D mftoutput
表格 2 Volatility常用命名参数及功能对照表
注:以下表格中用vol.exe替代volatility_2.6_win64_standalone.exe
功能 | 命令行及参数 |
查看进程列表 | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 pslist |
查看进程列表(树形) | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 pstree |
查看进程列表(psx视图) | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 psxview |
查看网络通讯连接 | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 netscan |
查看加载的动态链接库 | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 dlllist |
查看SSDT表 | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 ssdt |
查看UserAssist痕迹 | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 userassist |
查看ShimCache痕迹 | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 shimcache |
查看ShellBags | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 shellbags |
查看服务列表 | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 svcscan |
查看Windows帐户hash | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 hashdump |
查看最后关机时间 | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 shutdowntime |
查看IE历史记录 | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 iehistory |
提取注册表数据 | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 dumpregistry |
解析MFT记录 | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 mftparser |
导出MFT记录 | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 mftparser –output-file=mftverbose.txt -D mftoutput |
获取TrueCrypt密钥信息 | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 truecryptmaster |
获取TrueCrypt密码信息 | Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 truecryptpassphrase |