前置步骤/问题解决
下载
Volatility2:https://github.com/volatilityfoundation/volatility
Volatility3:https://github.com/volatilityfoundation/volatility3
python版本
update-alternatives是Debian/Ubuntu系统提供的管理系统级默认命令的工具,通过维护符号链接工作
设置优先级,一般使用整数:
update-alternatives --install /usr/bin/python python /usr/bin/python2 100
update-alternatives --install /usr/bin/python python /usr/bin/python3 150
查看当前可识别的版本:
update-alternatives --list python
/usr/bin/python2
/usr/bin/python3
/usr/bin/python3.11
切换版本:
update-alternatives --config python
有 3 个候选项可用于替换 python (提供 /usr/bin/python)。
选择 路径 优先级 状态
------------------------------------------------------------
0 /usr/bin/python3 150 自动模式
* 1 /usr/bin/python2 100 手动模式
2 /usr/bin/python3 150 手动模式
3 /usr/bin/python3.11 125 手动模式
要维持当前值[*]请按<回车键>,或者键入选择的编号:
输入数字切换版本
虚拟环境
安装
volatility2是基于python2开发的,所以虚拟环境也要使用python2的virtualenv创建
这里以我下载python2.7版本的虚拟环境步骤为例,记录一些遇到的问题
首先下载pip2,需要切换到python2的环境,并且由于linux系统大多放弃了apt对python2的支持,所以无法使用apt install下载,需要手动安装
1.下载脚本:
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py
2.运行脚本:
sudo python2 get-pip.py
3.检查是否安装成功:
pip2 -V
成功显示出pip的版本号,以及它关联的是Python 2.7,就说明已经成功为安装好了pip2
4.安装virtualenv:
安装的版本必须是兼容python2的,直接安装可能会下载到python3的版本,所以要指定版本:
pip2 install "virtualenv<20"
如果是volatility3,也就是基于python3的版本,就可以使用apt直接下载对应的venv工具
先更新,后下载:
sudo apt update
apt install python3-venv
这样就完成了安装
创建
python2:
python2 -m virtualenv 虚拟环境名
python3:
python3 -m venv 虚拟环境名
使用
source 虚拟环境名/bin/activate
提示符前面会多一个(虚拟环境名)的标记,之后的所有python和pip命令都只作用在此环境下
分享依赖
这条命令会将当前环境中所有已安装的库及其版本号写入到requirements.txt中:
pip freeze > requirements.txt
如果别人需要用,只需创建一个新的虚拟环境,再运行:
pip install -r requirements.txt
通常我们也是使用这个命令来下载对应工具需要的依赖
退出
deactivate
删除
rm -rf 虚拟环境名
设置为系统级命令
编写启动脚本
vim /usr/local/bin/vol
向里面写入下面内容:
#!/bin/bash
source /home/kali/volatility2/venv_volatility2/bin/activate && python /home/kali/volatility2/vol.py "$@"
&&的意思是:如果前一个命令成功,则执行后一个命令
前者是启动虚拟环境,要写对应创建的虚拟环境路径
后者是把所有参数传递给volatility脚本,要写对应的vol.py路径
给脚本添加启动权限
sudo chmod +x /usr/local/bin/vol
这样就设置完成了,如果不行,就刷新一下命令缓存再运行:
hash -r
报错解决
缺少运行库
换了两个虚拟机,每次运行volatility2的时候都会遇到库pycryptodome和distorm3不存在的问题
这种情况只要进入对应虚拟环境,然后安装缺少的库即可
source /home/kali/volatility2/venv_volatility2/bin/activate
pip2 install pycryptodome
pip2 install distorm3
deactivate
安装插件
volatility2历史悠久,社区也很强大,很多人开发了非常好用的插件,需要我们手动安装
这里以mimikatz插件为例,具体的下载地址网上一搜就有
下载插件,这里使用wget,其他方式随意:
wget https://raw.githubusercontent.com/volatilityfoundation/community/master/FrancescoPicasso/mimikatz.py
移动到存放插件的目录,一般是volatility2/volatility/plugins/:
mv mimikatz.py /home/kali/volatility2/volatility/plugins/
之后就可以使用了,不过mimikatz使用还需要安装依赖,具体看mimikatz
Volatility常用命令
系统画像
查看系统信息(imageinfo/info)
Volatility2
这是vol2进行任何分析前必须执行的第一步,用于确定操作系统的Profile,即版本
vol2 -f <内存镜像> imageinfo
<内存镜像>的后缀名没有固定的,可能是raw,dump,img,vmem等等
-
Suggested Profile(s):建议的配置文件
在后续执行所有其他插件时,都需要通过
--profile=<profile_name>参数从这个列表中选择一个来使用通常,选择列表中的第一个(
Win7SP1x64)就是最合适的 -
KDBG:内核调试块地址
用于定位其他所有系统信息,如进程列表、驱动列表等
-
Image date and time:镜像日期和时间,世界标准时间零时区UTC+0
这里表明内存快照是在UTC时间2019年12月20日03:47:57被创建
-
Image local date and time:原始机器当时的本地时间,包含时区信息
03:47:57加上5小时30分钟,正好等于09:17:57,这就是当地的时间 -
Number of Processors:处理器数量
这里显示该系统是单核处理器
Volatility3
V3会自动检测Profile,之后的命令无需手动输入,此命令用于显示详细的信息
vol3 -f <内存镜像> windows.info.Info
-
NTBuildLab:Windows操作系统构建版本标签
7601.17514.amd64fre.win7sp1_rtm,代表一个经过后续更新(修订号17514)的、面向64位amd架构的、已正式发布的、基于Windows7SP1开发分支的操作系统 -
KeNumberProcessors:处理器个数
-
SystemTime:内存快照被制作的时间,世界标准时间零时区UTC+0
-
NtProductType: Windows操作系统的产品类型
NtProductWinNt:客户端版本NtProductServer:服务器NtProductLanManNt:域控制器,是特定类型的服务器 -
NtMajorVersion / NtMinorVersion:Windows操作系统内核的主版本号和次版本号
6.1在WindowsNT内核版本中,对应着Windows7或WindowsServer2008R2
-
PE TimeDateStamp:系统内核文件被编译的时间
查看文件信息(mftparser/mftscan)
除了Volatility,还可以使用其他工具导出mft记录:https://github.com/jschicht/Mft2Csv/releases
下载打开软件,选择$MFT文件,然后导出到csv文件即可,导出的条目会以csv文件的形式存放在软件目录下
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> mftparser
-
MFT entry found at offset …:该MFT记录在内存中的物理偏移地址
-
Attribute:In Use & File:表明这是一条活动的、描述文件的记录
-
Record Number:该记录在MFT中的唯一编号
-
Link count:指向这个文件实体的文件名数量(硬链接数)
-
$STANDARD_INFORMATION:主属性,只有当文件内容被编辑时,其
Modified和Updated时间才会改变$FILE_NAME:文件名属性,文件内容被改动、重命名、移动时,其
Modified和Updated时间都会改变 -
Creation:创建时间
-
Modified:修改时间
-
MFT Altered:MFT记录本身最后一次被修改的时间,例如文件名或权限变更
-
Access Date:文件内容最后一次被访问的时间(注意:在现代Windows系统中,为提高性能,这个时间戳不一定总是实时更新)
-
Name/Path:显示具体的文件名
Volatility3
vol3 -f <内存镜像> windows.mftscan.MFTScan
-
Offset :偏移量
这是该 MFT 记录在内存中的虚拟地址
-
Record Type:记录类型
指明该记录是用于一个文件(FILE)还是一个目录(Directory)
-
Record Number:记录编号
这是该文件/目录在整个 MFT 中的唯一索引号
-
Link Count:链接计数
表示有多少个文件名指向这个相同的文件实体
例如,值为2意味着这个文件有两个名字,通常一个是长文件名,一个是8.3格式的短文件名
-
MFT Type:MFT类型
进一步描述MFT条目的类型,通常与Record Type一致
-
Permissions:权限属性
显示文件的属性,如 Archive (存档)、System (系统文件)等
-
Attribute Type:属性类型
指明当前这一行显示的是 MFT 记录中的哪一种具体属性
STANDARD_INFORMATION:主属性,只有当文件内容被编辑时,其Modified和Updated时间才会改变FILE_NAME:文件名属性,文件内容被改动、重命名、移动时,其Modified和Updated时间都会改变最前面带星号的行是隶属于它上面那个不带星号的主记录的子属性
-
Created, Modified, Updated, Accessed:四种时间戳
分别代表了该属性(STANDARD_INFORMATION 或 FILE_NAME)的:
创建时间、修改时间、MFT记录更新时间、访问时间(以UTC标准时间显示)
-
Filename:文件名
当 Attribute Type 为 FILE_NAME 时,这一列会显示具体的文件名
查看windows服务(svcscan)
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> svcscan
-
Service Name:服务的内部名称
-
Display Name:服务的显示名称,在服务管理器中的名称
-
Process ID:该服务的进程的ID
-
Service State: 服务状态,表明服务是
RUNNING(正在运行) 还是STOPPED(已停止) -
Binary Path:服务路径
Volatility3
vol3 -f <内存镜像> windows.svcscan.SvcScan
-
Offset:偏移量
这是该服务记录在内存中的虚拟地址
-
Order:顺序
服务在其服务组内的加载顺序编号
-
PID:进程ID
如果该服务当前正在运行,这里会显示托管它的进程的ID,如果服务已停止,则显示为
N/A -
Start:启动类型
这是在注册表中为该服务配置的启动方式,决定了它如何被启动,有下面几种:
-
SERVICE_BOOT_START:引导启动 -
SERVICE_SYSTEM_START:系统启动 -
SERVICE_AUTO_START:自动启动 -
SERVICE_DEMAND_START:按需启动 (手动) -
SERVICE_DISABLED:已禁用
-
-
State:当前状态
表示在捕获内存时该服务的实时状态,有下面这几种:
-
SERVICE_STOPPED:服务已停止 -
SERVICE_START_PENDING:服务正在启动 -
SERVICE_STOP_PENDING:服务正在停止 -
SERVICE_RUNNING:服务正在运行 -
SERVICE_CONTINUE_PENDING:服务即将继续 -
SERVICE_PAUSE_PENDING:服务即将暂停 -
SERVICE_PAUSED:服务已暂停
-
-
Type:服务类型
描述了该服务的性质,有下面几种:
-
SERVICE_KERNEL_DRIVER:内核模式驱动程序 -
SERVICE_FILE_SYSTEM_DRIVER:文件系统驱动程序 -
SERVICE_WIN32_OWN_PROCESS:独立进程Win32服务 -
SERVICE_WIN32_SHARE_PROCESS:共享进程Win32服务 -
SERVICE_INTERACTIVE_PROCESS:交互式服务,由于安全原因,这个服务已经被弃用
-
-
Name:服务名
服务的短名称或内部名称
-
Display:显示名称
Windows服务管理器中看到的人类可读的名称
-
Binary:二进制/运行命令
这是启动该服务进程时实际使用的命令行
对于共享服务,这里通常会包含
-k <服务组名>参数,例如C:\Windows\system32\svchost.exe -k DcomLaunch -
Binary (Registry):注册表中的二进制路径
这是在注册表中为该服务配置的
ImagePath值 -
Dll:服务DLL
如果该服务是由一个DLL实现并由
svchost.exe托管的,这里会显示该 DLL 的路径
查看驱动模块(modules/driverscan/modscan)
Volatility2
使用modules来查看驱动模块,通过遍历内核中的PsLoadedModuleList官方链表来获取信息:
vol2 -f <内存镜像> --profile=<系统版本> modules
Offset(V):该模块的_LDR_DATA_TABLE_ENTRY结构在内存中的虚拟地址Name:模块的名称,例如ntoskrnl.exeBase:模块被加载到内存中的基地址Size:模块在内存中所占空间的大小File:该模块对应的磁盘文件路径
或者也可以使用driverscan通过扫描内存池来寻找驱动对象,这种方式能发现一部分隐藏的驱动对象:
vol2 -f <内存镜像> --profile=<系统版本> driverscan
Offset(P):该驱动对象在内存中的物理地址#Ptr:指向该驱动对象的指针数量#Hnd:该驱动对象的句柄数量Start:驱动程序在内存中的起始地址Size:驱动程序在内存中所占空间的大小Service Key:该驱动在注册表服务项中的名称,这通常与驱动名相同Name:驱动的名称Driver Name:驱动对象在系统中的完整名称,通常以\Driver\或\FileSystem\开头
还可以使用modscan扫描模块结构特征寻找驱动,最全面,能发现大多数隐藏模块速度慢,但可能有误报:
vol2 -f <内存镜像> --profile=<系统版本> modscan
物理地址不同是正常的,因为它们扫描和定位的目标数据结构不同
Volatility3
使用modules:
vol3 -f <内存镜像> windows.modules.Modules
使用driverscan:
vol3 -f <内存镜像> windows.driverscan.DriverScan
使用modscan:
vol3 -f <内存镜像> windows.modscan.ModScan
查看驱动程序的IRP(driverirp)
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> driverirp
-
DriverName:目标驱动的名称
-
第一列:IRP功能码的编号
-
第二列:IRP功能码的名称,描述了I/O请求的类型,例如:
IRP_MJ_CREATE:当有程序尝试创建或打开文件时,会产生这个请求IRP_MJ_READ:读取文件请求IRP_MJ_WRITE:写入文件请求IRP_MJ_DEVICE_CONTROL:设备控制请求
-
第三列:处理该IRP请求的函数在内存中的实际地址
-
第四列:该函数地址所属的内核模块
Volatility3
vol3 -f <内存镜像> windows.driverirp.DriverIrp
- Offset:该驱动对象在内存中的虚拟地址
- Driver Name:驱动对象的名称
- IRP:IRP的主要功能码,代表了驱动程序注册要处理的I/O操作类型,例如:
IRP_MJ_CREATE:文件或设备创建/打开请求IRP_MJ_CLOSE:文件或设备关闭请求IRP_MJ_READ:读取请求IRP_MJ_WRITE:写入请求IRP_MJ_DEVICE_CONTROL:设备控制请求,是驱动程序功能的主要入口IRP_MJ_INTERNAL_DEVICE_CONTROL:内部设备控制请求IRP_MJ_PNP:即插即用相关的请求
- Address:处理该类型IRP请求的函数在内存中的实际地址
- Module:该函数地址所属的内核模块(驱动文件)
- Symbol:具体的函数名
查看内核回调(callbacks)
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> callbacks
Volatility3
vol3 -f <内存镜像> windows.callbacks.Callbacks
-
Type:回调类型当这类事件发生时,内核会调用所有注册在此的回调函数,例如:
PspCreateProcessNotifyRoutine: 当一个新进程被创建时触发PspLoadImageNotifyRoutine: 当一个可执行文件或DLL被加载到内存时触发KeBugCheckCallbackListHead: 当系统发生蓝屏崩溃时触发
-
Callback:回调函数地址 -
Module:所属模块它指明了这个回调函数属于哪个内核模块,即驱动程序
在正常情况下,这里应该都是
ntoskrnl(内核自身)或已知的、合法的硬件驱动程序(如tcpip,ndis等) -
Symbol:回调函数的具体名称 -
Detail:补充说明
查看系统调用(ssdt)
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> ssdt
Entry:SSDT 表中的索引号(入口点编号),以十六进制表示Address:该索引号对应的内核函数在内存中的实际地址owned by:指明了这个函数地址属于哪个内核模块
如果一个函数的Owner不是 ntoskrnl.exe或win32k.sys,而是另一个可疑的驱动,或者显示为 (unknown),就意味着该函数很可能已被挂钩(Hook),指向了恶意的函数
Volatility3
vol3 -f <内存镜像> windows.ssdt.SSDT
Index:SSDT 表中的索引号(入口点编号)Address:该索引号对应的内核函数在内存中的实际地址Module:指明了这个函数地址属于哪个内核模块Symbol:该内核函数的具体名称
查看符号链接(symlinkscan)
通过扫描内存以寻找并打印出_OBJECT_SYMBOLIC_LINK结构,列出系统内核中存在的符号链接及其指向的目标
Volatility2
vol2 -f <内存镜像> --profile=<配置文件> symlinkscan
输出字段详解
Offset(P):该符号链接对象(_OBJECT_SYMBOLIC_LINK结构)在内存中的物理地址#Ptr:指向该符号链接对象的指针数量#Hnd:该符号链接对象的句柄数量Creation time:该符号链接被创建的时间戳(以UTC标准时间显示)From:这是符号链接自身的名称,可以理解为“快捷方式”的名字To:这是该符号链接实际指向的目标对象的名称,可以理解为“快捷方式”指向的“真实文件”的路径
Volatility3
vol3 -f <内存镜像> windows.symlinkscan.SymlinkScan
Offset:该符号链接对象(_OBJECT_SYMBOLIC_LINK结构)在内存中的虚拟地址CreateTime:该符号链接被创建的时间戳(以UTC标准时间显示)From Name:这是符号链接自身的名称,可以理解为“快捷方式”的名字To Name:这是该符号链接实际指向的目标对象的名称,可以理解为“快捷方式”指向的“真实文件”的路径
进程分析
查看进程列表(pslist/psscan)
Volatility2
仅查看显式进程:
vol2 -f <内存镜像> --profile=<系统版本> pslist
查看包括隐藏进程在内的进程:
vol2 -f <内存镜像> --profile=<系统版本> psscan
- Offset(V):进程对象在内存中的虚拟地址
- Name:进程的映像文件名(通常是
.exe文件名) - PID:进程ID,每个进程唯一的身份编号
- PPID:父进程ID,即启动这个进程的那个进程的ID
- Thds:线程数,该进程拥有的线程数量
- Hnds:句柄数,该进程打开的句柄数量
- Sess:会话ID,用于区分不同的用户登录会话
- Wow64:如果为
True,表示一个32位进程运行在64位系统上 - Start:进程的创建时间
- Exit:进程的退出时间(如果进程已终止)
Volatility3
仅查看显式进程:
vol3 -f <内存镜像> windows.pslist.PsList
查看包括隐藏进程在内的进程:
vol3 -f <内存镜像> windows.psscan.PsScan
- PID:进程ID
-
PPID:父进程ID,即启动这个进程的那个进程的ID
-
ImageFileName:进程的映像文件名,通常是
.exe文件名 -
Offset(V):进程对象在内存中的虚拟地址
-
Threads:线程数,该进程拥有的线程数量
-
Handles:句柄数,该进程打开的句柄数量
-
SessionID:会话ID
-
Wow64:如果为
True,表示一个32位进程运行在64位系统上 -
CreatTime:进程的创建时间
-
ExitTime:如果进程已终止,显示进程的退出时间
-
File output:是否已经被导出(dump)
查看进程父子关系(pstree)
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> pstree
区分父子进程:
wininit.exe:行首没有点,它是这个分支的顶级进程
services.exe:行首有 1个点,它位于 wininit.exe(0个点)的下方,所以 services.exe 是 wininit.exe 的子进程
TCPSVCS.EXE:行首有 2个点,它位于 services.exe(1个点)的下方,所以 TCPSVCS.EXE 是 services.exe 的子进程
当一个进程的父进程ID(PPID)比它自身的进程ID(PID)还要大时,很可能有问题
Volatility3
vol3 vol.py -f <内存镜像> windows.pstree.PsTree
与volatility2不同,3使用*来区分父子进程,*越多,代表进程的层级越深,是更深层的子进程
- Path:每个进程可执行文件在硬盘上的完整路径
- Cmd:启动该进程时使用的完整命令行参数
发现隐藏进程(psxview)
恶意进程一般会隐藏自身,而人工对比pslist和psscan又太麻烦太不可靠
可以使用psxview对比各个扫描方式,寻找隐藏进程
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> psxview
过滤带有false的项目,可以很快看出哪些进程隐藏了自身(主要看第一个pslist和第二个psscan):
Volatility3
python3 vol.py -f <内存镜像> windows.malware.psxview.PsXView
过滤False项:
查看进程启动参数(cmdline)
能看到进程如何被创建的,包括命令行启动和exe文件点击启动
但看不到进程内部的交互,不知道进程干了什么
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> cmdline
Volatility3
vol3 -f <内存镜像> windows.cmdline.CmdLine
查看进程加载的DLL(dlllist)
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> dlllist -p 进程pid
Volatility3
vol3 -f <内存镜像> windows.dlllist.DllList --pid 进程pid
相较于vol2,vol3还给出了dll的加载时间LoadTime:
查看进程权限(privs)
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> privs
Volatility3
vol3 -f <内存镜像> windows.privileges.Privs
查看进程对应用户SID(getsids)
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> getsids
Volatility3
vol3 -f <内存镜像> windows.getsids.GetSIDs
相较于Volatility2,这个输出更加规范化:
-
PID:进程ID
-
Process:进程名
-
SID:安全标识符的字符串表示 -
Name:该 SID 对应的通用名称
一个进程会对应多个SID,是因为一个进程的访问令牌中,不仅包含了其主要运行身份的SID,还包含了该身份所属的所有用户组的SID,这些SID共同决定了该进程的权限
例如,System(PID:4)这个进程,它关联了多个SID:
- S-1-5-18 (Local System):这是它的主身份,代表了系统的最高权限
- S-1-5-32-544 (Administrators):表明它也属于管理员组
- S-1-1-0 (Everyone):表明它也属于Everyone组
查看可能的恶意代码(malfind)
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> malfind
volatility2还有一个社区插件,是malfind的深度扫描版本malfinddeep:
https://github.com/superponible/volatility-plugins
vol2 -f <内存镜像> --profile=<系统版本> malfinddeep
Volatility3
vol3 -f MemoryDump_Lab5.raw windows.malware.malfind.Malfind
提取进程内存(memdump/–dump)
进程内存中潜藏着很多信息,把他们提取出来才能更好的做分析
比如TrueCrypt进程中会有加密密钥,导出其为.dmp文件后,可以交给EFDD解密加密卷
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> memdump -p <PID> -D <保存路径>
提取后的文件为.dump,存储了进程所有的数据,可以在里面搜索目标字符串等
如果进程里有想要的文件,可以使用foremost分离文件
如果目标比较明显(比如图片),也可以用mv命令修改文件后缀再打开,再在里面找目标文件
Volatility3
vol3不再有单独的dump插件,直接在PsList插件使用--dump选项:
vol3 -f <内存镜像> -o <保存路径> windows.pslist.PsList --pid <PID> --dump
这里的-o选项用于指定导出文件的路径,必须放在-f选项后一个!!
网络活动分析
查看网络连接(netscan/netstat)
Volatility2
查看当前以及历史、隐藏网络链接(这个是XP时代的工具了,很老,不一定有用):
vol2 -f <内存镜像> --profile=<系统版本> connscan
查看当前网络链接:
vol2 -f <内存镜像> --profile=<系统版本> netscan
-
LISTENING:表示某个程序正在一个端口上“监听”,等待外部连接的建立 -
ESTABLISHED:表示一个 TCP 连接已经成功建立,双方正在进行数据通信 -
CLOSED/TIME_WAIT/SYN_SENT:表示各种已关闭或正在建立/关闭过程中的连接状态
- UDP 是无连接的协议,所以它没有
State(状态)字段
我们可以从中筛选已经建立链接的项:
vol2 -f <内存镜像> --profile=<系统版本> netscan | grep ESTABLISHED
如果当前系统中存在挖矿进程,网络连接列表又太长,就可以借此筛选,获取到矿池地址
或者也可以根据提供的pid把它dump下来具体分析
Volatility3
更加建议使用NetStat,报告更赏心悦目:
vol3 -f <内存镜像> windows.netstat.NetStat
当然,vol3也是有NetScan的:
vol3 -f <内存镜像> windows.netscan.NetScan
注册表分析
查看注册表整体结构(hivelist)
hivelist的主要作用是为后续的printkey等插件提供每个Hive的虚拟地址(第一列)
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> hivelist
ntuser.dat:用户的注册表文件,这里表明Alissa Simpson和SmartNet是登录状态或近期登录过
Volatility3
vol3 -f <内存镜像> windows.registry.hivelist.HiveList
查看具体注册表项(printkey)
Volatility2
使用逻辑路径:
vol2 -f <内存镜像> --profile=<系统版本> printkey -K "顶层路径\子路径"
一定是从对应的hive开始,比如SAM,SECURITY等,而不是那五个根键:
也可以使用虚拟地址:
vol2 -f <内存镜像> --profile=<系统版本> printkey -o 虚拟地址
再根据结果返回的SubKeys使用-K参数:
vol2 -f <内存镜像> --profile=<系统版本> -o 虚拟地址 printkey -K "子键名称"
Volatility3
vol3只指定路径会去所有hive中寻找,需要使用逻辑路径+虚拟地址才能精确定位:
vol3 -f <内存镜像> windows.registry.printkey.PrintKey --offset 虚拟地址 --key "顶层路径\子路径"
用户活动与执行历史
查看cmd历史命令(cmdscan)
输出干净,有时能找到超出缓冲区范围的命令,即使已经清屏
但没有命令的输出结果,且只限于cmd
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> cmdscan
-
Application:DumpIt.exe:Volatility在内存中定位到的这个命令历史记录区是属于DumpIt.exe的这里cmdcount=0,说明没有发现cmd命令
-
DumpIt.exe是于快速创建物理内存完整转储的工具,也就是创建这个<内存镜像>用的
Volatility3
vol3对于win7等老系统可能不支持,分析会报错,使用时注意
vol3 -f <内存镜像> windows.cmdscan.CmdScan
1.概览信息
PID Process ConsoleInfo Property Address Data
2084 conhost.exe 0x1445c89b900 _COMMAND_HISTORY 0x1445c89b900 None
这部分告诉我们,在 PID 为2084的conhost.exe进程中,于内存地址0x1445c89b900处,找到了一个_COMMAND_HISTORY(命令历史)的数据结构
2.历史记录的元数据
下面几行带单个*的是这个历史记录本身的属性:
* 2084 conhost.exe ... _COMMAND_HISTORY.Application ... cmd.exe
* 2084 conhost.exe ... _COMMAND_HISTORY.CommandCount ... 3
* 2084 conhost.exe ... _COMMAND_HISTORY.CommandCountMax ... 50
Application:cmd.exe:表明这个命令行窗口的应用程序是cmd.exeCommandCount:3:它表示在这个命令历史缓冲区中,一共记录了3条命令CommandCountMax:50:表示这个缓冲区最多可以记录50条命令
3.恢复出的命令内容
下面带两个星号**的部分是用户输入过的命令:
** 2084 conhost.exe ... CommandBucket_Command_0 ... ping easyforensics.com
** 2084 conhost.exe ... CommandBucket_Command_1 ... ipconfig
** 2084 conhost.exe ... CommandBucket_Command_2 ... ping easyforensics.com
CommandBucket_Command_X:代表历史记录缓冲区中的第 X 个槽位- Data 列:清晰地显示了用户按顺序输入的三条命令:
ping easyforensics.comipconfigping easyforensics.com
查看控制台完整交互(consoles)
consoles不仅能看到输入的命令,还能看到命令返回的输出结果,只要是conhost.exe控制的交互式窗口(cmd、poweshell等)就能提取
但它受缓冲区大小限制,只寻找当前屏幕缓冲区的内容,如果清屏了(cls)就找不到了
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> consoles
Volatility3
vol3对于win7等老系统可能不支持,分析会报错,使用时注意
vol3 -f <内存镜像> windows.consoles.Consoles
此处显示未找到控制台信息"Console Information Not Found"
查看GUI程序执行记录(userassist)
展示用户通过GUI启动的程序(点击快捷方式、开始菜单等)的信息,证明用户的主动操作行为
它只记录explorer.exe,不接受cmd.exe/powershell.exe,不能看见用户通过命令行启动的程序
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> userassist
-
Registry:...\ntuser.dat:个人注册表配置文件,用户为Alissa Simpson -
REG_BINARY:程序名称 -
Count:程序启动次数 -
Focus Count:程序点击次数(焦点) -
Last Update:最后一次使用记录
Volatility3
vol3 -f <内存镜像> windows.registry.userassist.UserAssist
查看程序准备记录(shimcache/shimcachemem)
记录任何准备执行的程序(包括后台服务、被浏览的文件等,不一定真的运行了)
它甚至能记录已被删除的程序的执行痕迹
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> shimcache
Volatility3
vol3 -f <内存镜像> windows.shimcachemem.ShimcacheMem
查看剪贴板内容(clipboard)
volatility3没有此功能
vol2 -f <内存镜像> --profile=<系统版本> clipboard
除了使用volatility2之外,也可以查看ActivitiesCache.db数据库
从Windows10版本1803开始,ActivitiesCache.db就开始记录剪贴板活动了,不过前提是要打开下面的设置:
随后,在下面的路径找到ActivitiesCache.db:
C:\Users\<username>\AppData\Local\ConnectedDevicesPlatform\
使用数据库链接后,使用它自带的SmartLookup视图:
这里我的ClipboardPayload字段为空,是因为我没有打开剪贴板历史记录,嘻嘻
查看窗口图像(screeenshot)
从内存中提取窗口图像甚至恢复桌面画面,截图内容通常是窗口的客户区域,不是全屏桌面
需要安装Pillow库:
source /home/kali/volatility2/venv_volatility2/bin/activate
pip2 install Pillow
deactivate
使用的同时必须指定保存路径(–dump-dir=):
vol2 -f <内存镜像> --profile=<系统版本> screenshot --dump-dir=保存路径
| 文件名 | 含义 |
|---|---|
| session_0 | 会话 0,表示本地物理桌面用户或服务(如 SYSTEM) |
| WinSta0 | 用户交互的窗口站(Window Station),默认GUI桌面就在这里 |
| Default | 当前活动桌面 |
| Winlogon | 登录界面桌面,可能在锁屏状态时显示 |
| Disconnect | 断开连接时显示的桌面(比如远程桌面断开) |
| Service-0x0-3e7$ | 代表SYSTEM服务账户的窗口站 |
| mssrestricteddesk | 某些安全子系统(如 Speech 或 Office 隔离)的沙盒桌面 |
比如我这里获得的一张当时的屏幕截图session_2.WinSta0.Default.png,说明用户在查看一张图片:
图片名base64解码就是flag:flag{!!_w3LL_d0n3_St4g3-1_0g_L4B_5_D0n3_!!}
查看记事本中的内容(notepad)
本质是扫描记事本进程notepad.exe,还原的是正在显示和编辑的内容
volatility3没有此功能
vol2 -f <内存镜像> --profile=<系统版本> iehistory
查看用户可能编辑的内容(editbox)
它比notepad插件更加通用,不只针对记事本,而是扫描所有进程的内存,寻找所有编辑控件并提取文本
volatility3没有此功能
vol2 -f <内存镜像> --profile=<系统版本> iehistory
查看ie浏览器历史记录(iehistory)
volatility3没有此功能
vol2 -f <内存镜像> --profile=<系统版本> iehistory
查看chrome浏览器历史记录(chromehistory)
volatility3没有此功能
需要下载插件chromehistory和sqlite_help:
https://github.com/superponible/volatility-plugins/blob/master
vol2 -f <内存镜像> --profile=<系统版本> chromehistory
查看firefox浏览器历史记录(firefoxhistory)
volatility3没有此功能
需要下载插件firefoxhistory和sqlite_help:
https://github.com/superponible/volatility-plugins/blob/master
vol2 -f <内存镜像> --profile=<系统版本> firefoxhistory
根据历史记录,我们可以去内存中查找是否有对应的文件:文件扫描与提取
查看已安装的软件(uninstallinfo)
volatility3没有此功能
需要下载插件uninstallinfo:
https://github.com/superponible/volatility-plugins/blob/master
vol2 -f <内存镜像> --profile=<系统版本> uninstallinfo
查看查入系统的USB设备(usbstor)
volatility3没有此功能
需要下载插件usbstor:
https://github.com/ruokeqx/tool-for-CTF/tree/master/volatility_plugins
vol2 -f <内存镜像> --profile=<系统版本> usbstor
密码和凭证获取(仅volatility2)
volatility3没有下面的功能
提取本地账户哈希(hashdump)
使用SYSTEM里面的SYSKEY提取SAM中的密码哈希
vol2 -f <内存镜像> --profile=<系统版本> hashdump
输出格式是:
[用户名]:[RID]:[LM哈希]:[NTLM哈希]:::
提取LSA密钥(lsadump)
lsa是本地安全机构,通过它可以获取当前登录用户、服务账户等多种形式的凭证,甚至可能是明文密码
vol2 -f <内存镜像> --profile=<系统版本> lsadump
以hex转储的形式输出,可能藏有东西
-
DefaultPassword:系统为自动登录功能存储的密码,如果设置了就是对应用户的密码 -
NL$KM:计算机的密钥,用于计算机和域控制器之间进行安全的通信和认证 -
DPAPI_SYSTEM:系统级DPAPI的主密钥,用于解密用户保存的各种密码(浏览器里的、wifi密码等)
提取明文密码(mimikatz)
实际上也是从lsass.exe里面提取,是lsadump的特化
非官方插件,需要下载:
https://raw.githubusercontent.com/volatilityfoundation/community/master/FrancescoPicasso
还需要安装依赖,必须是对应旧版本的construct库:
source /home/kali/volatility2/venv_volatility2/bin/activate
pip2 install construct==2.5.2
deactivate
随后就可以使用了:
vol2 -f <内存镜像> --profile=<系统版本> mimikatz
查看Chrome记录的登录密码(lastpass)
需要下载插件lastpass:
https://github.com/ruokeqx/tool-for-CTF/tree/master/volatility_plugins
vol2 -f <内存镜像> --profile=<系统版本> lastpass
获取TrueCrypt秘钥信息(truecryptmaster)
vol2 -f <内存镜像> --profile=<系统版本> truecryptmaster
获取TrueCrypt密码信息 (truecryptpassphrase)
vol2 -f <内存镜像> --profile=<系统版本> truecryptpassphrase
文件扫描与提取
扫描内存中的文件(filescan)
Volatility2
vol2 -f <内存镜像> --profile=<系统版本> filescan
如果知道具体文件名称(-i忽略大小写):
vol2 -f <内存镜像> --profile=<系统版本> filescan | grep -i 'secret.txt'
如果想找指定文件类型(-E正则匹配):
vol2 -f <内存镜像> --profile=<系统版本> filescan | grep -E 'jpg|png|jpeg|bmp|gif'
最前面的十六进制是文件地址
Volatility3
vol3 -f <内存镜像> windows.filescan.FileScan
从内存中转储指定文件(dumpfiles)
filescan插件扫描的是_FILE_OBJECT这样的内核结构,相当于找到了文件的档案卡
dumpfiles插件则是根据这张档案卡的指引,去内存中寻找文件的具体内容
如果文件的内容当时没有被加载到内存(RAM)中,或者已经被操作系统置换到了页面文件(pagefile.sys)里,那么dumpfiles就无法从内存镜像中提取出完整的文件数据
Volatility2
vol2 -f <内存镜像> --profile=<配置文件> dumpfiles -Q <物理地址> -D <目录>
下载的文件是.data文件,改后缀或使用foremost等工具分析
Volatility3
vol3 -f <内存镜像> -o <目录> windows.dumpfiles.DumpFiles --physaddr <物理地址>
从内存中搜索字符串 (strings)
Volatility3有windows.strings.Strings插件,不过不太好用,我们主要目的还是搜索字符串
常见的用法是先用memdump转储出某个可疑进程的内存文件,然后对这个小文件执行strings,这样目标更明确,噪音也更少:
strings 1234.dmp | grep -i "关键词"