Volatility2内存取证实践

1. 安装Volatility2

最快的上手方式是直接使用官方的预编译二进制版本,无需安装Python环境:

不过预编译版本的插件功能我个人测试是无法使用的,因此如果需要使用第三方插件,则建议从源码安装Volatility2。下面演示在Windwos环境下安装Volatility2。请提前安装好Python2git

首先从GitHub上克隆Volatility2的源码并安装:

1
2
3
git clone https://github.com/volatilityfoundation/volatility.git
cd volatility
python2 setup.py install

安装完成后直接执行 vol.py 会报错,提示缺少Crypto.Hash和distorm3这2个模块:

alt text

其中Crypto.Hash可以通过直接通过pip安装:

1
2
python2 -m pip install --upgrade pip -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
python2 -m pip install pycryptodome -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple

而distorm3直接使用python2的pip安装则会失败,错误提示需要python2.7的Microsoft Visual C++ 编译器,可通过以下任一链接下载VC++编译器:

下载并安装好VCForPython27.msi之后,便可以使用python2的pip安装distorm3了:

1
python2 -m pip install distorm3 -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple

安装完成后,执行vol.py便不再报错:

alt text

如果想在任意位置调用vol.py,并且不加上python命令,可以新建一个批处理文件(vol2.bat),内容如下:

1
2
@echo off
C:\Python27\python2.exe C:\Users\mkbk\Desktop\volatility\vol.py %*

注意:新建的这个批处理文件名称不要直接叫vol,原因是vol是windows自带磁盘查询工具(用于显示当前驱动器的卷标和序列号),并且命令优先级高于环境变量,会导致无法执行到vol.py。

你需要把上面的python和vol.py的路径替换成你自己的实际路径,然后将批处理文件vol2.bat放到一个空目录中,如C:\BatchDir,然后把这个目录添加到用户环境变量中:

alt text

再重启下终端,就可以在任意位置使用vol.py了:

alt text

2. Volatility2第三方插件

插件用法:

1
vol2 --plugin <插件目录>  -f <内存镜像文件> --profile=<操作系统> <插件名称>

注意:--plugin参数一定要放在最前面,否则会报错。

Volatility2常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
imageinfo  # 获取系统基本信息
pslist # 列出进程信息
psscan # 进程扫描
memdump -p <PID> -D . # 提取进程
filescan # 查看文件目录
dumpfiles -Q <虚拟地址> -D . # 下载文件
hivelist # 列出注册表配置单元
prinykey # 打印注册表
ControlSet001\Control\ComputerName\ComputerName # 主机名注册表位置
netscan # 网络扫描
connscan、connections # 查看网络连接
cmdscan # 显示cmd历史命令
pstree # 显示进程树
svcscan # 查看服务
iehistory # 打印浏览器历史记录
clipboard # 查看粘贴板信息
serassist # 查看运行程序相关的记录,比如最后一次更新时间,运行过的次数等
envars # 打印环境变量
dlllist # 列出某一进程加载的所有dll文件
shimcache # 从内存文件中找到异常程序植入到系统的开机自启痕迹

推荐阅读这篇文章,举例解释很多常用参数的作用:https://mp.weixin.qq.com/s/tK3iyB1Ug-c7KstFcJLgkQ

3. 练习题

3.1. 第46届金砖国家世界技能大赛湖北省选拔赛

  1. 从内存中获取到用户admin的密码并且破解密码,以Flag{admin,password} 形式提交(密码为 6 位);
  2. 获取当前系统 ip 地址及主机名,以 Flag{ip:主机名}形式提交;
  3. 获取当前系统浏览器搜索过的关键词,作为 Flag 提交;
  4. 当前系统中存在挖矿进程,请获取指向的矿池地址,以 Flag{ip:端口}形式 提交;
  5. 恶意进程在系统中注册了服务,请将服务名以 Flag{服务名}形式提交。
  6. 获取桌面上的flag.txt文件的内容是什么?
  7. 病毒在自我删除时执行的命令是什么?

题一

1、从内存中获取到用户admin的密码并且破解密码,以Flag{admin,password} 形式提交(密码为 6 位)。

拿到镜像第一件事就是使用imageinfo插件查看镜像信息:

1
vol2 -f 1.vmem imageinfo

alt text

首选第一个操作系统配置文件Win7SP1x64作为--profile选项的参数,并使用hashdump插件提取账户hash:

1
vol2 -f 1.vmem --profile Win7SP1x64 hashdump

alt text

提取出了admin用户的LM和NTLM哈希值,其中LM哈希值aad3b435b51404eeaad3b435b51404ee代表空密码,这是Windows Server 2008及以后版本的默认设置,因此只需还原NTLM哈希值29fb61bd2963b1975cf435a2565af910即可。但经测试,hashcat无法破解这个NTLM哈希值,猜测密码明文是强口令,因此可以尝试使用lsadump插件提取明文密码:

1
vol2 -f 1.vmem --profile Win7SP1x64 lsadump  # 从注册表中提取已解密的LSA密钥

alt text

得到了密码明文为flag{406990ff88f13dac3c9debbc0769588c},也可以使用hashcat验证此密码和前面提取的NTLM哈希值是否匹配:

1
hashcat --self-test-disable 29fb61bd2963b1975cf435a2565af910 -m 1000 -a 3 flag{406990ff88f13dac3c9debbc0769588c}

alt text

匹配成功,说明密码是flag{406990ff88f13dac3c9debbc0769588c}。除了lsadump,还可以使用mimikatz插件提取明文密码:

1
vol2 --plugin E:\plugins -f 1.vmem --profile Win7SP1x64  mimikatz

alt text

同样得到了密码明文flag{406990ff88f13dac3c9debbc0769588c}

但这并不是最终的flag,因为题目要求的密码是6位,并且格式为Flag{admin,password},因此还需要对flag{406990ff88f13dac3c9debbc0769588c}中的406990ff88f13dac3c9debbc0769588c进行还原,使用hashcat进行爆破:

1
2
hashcat --self-test-disable 406990ff88f13dac3c9debbc0769588c  # 判断出哈希模式为MD5
hashcat --self-test-disable 406990ff88f13dac3c9debbc0769588c -m 0 -a 3 -O

alt text

爆破出哈希明文是dfsddew,在有网环境下,也可以尝试使用在线网站进行破解,如cmd5

alt text

综上,最终flag为Flag{admin,dfsdde}

题二

2、获取当前系统 ip 地址及主机名,以 Flag{ip:主机名}形式提交;

使用netscan插件获取当前系统ip地址:

1
vol2 -f 1.vmem --profile Win7SP1x64 netscan | findstr ESTABLISHED

alt text

IP地址为: 192.168.85.129

上一题使用mimikatz插件提取明文密码时,已经知道了主机名是WIN-9FBAEH4UV8C:

alt text

不过,更常见的做法还是使用自带的hivelist插件获取当前系统主机名。

首先获取注册表路径:

1
vol2 -f 1.vmem --profile Win7SP1x64 hivelist

alt text

找到关键字”SYSTEM”一行中的虚拟地址,使用printkey插件获取注册表信息,-o参数指定该地址,-K参数指定要获取的键名:

1
2
3
4
5
vol2 -f 1.vmem --profile Win7SP1x64 printkey -o 0xfffff8a000024010
vol2 -f 1.vmem --profile Win7SP1x64 printkey -o 0xfffff8a000024010 -K ControlSet001
vol2 -f 1.vmem --profile Win7SP1x64 printkey -o 0xfffff8a000024010 -K ControlSet001\Control
vol2 -f 1.vmem --profile Win7SP1x64 printkey -o 0xfffff8a000024010 -K ControlSet001\Control\ComputerName
vol2 -f 1.vmem --profile Win7SP1x64 printkey -o 0xfffff8a000024010 -K ControlSet001\Control\ComputerName\ComputerName

alt text

alt text

alt text

得到主机名为WIN-9FBAEH4UV8C,最终flag为Flag{192.168.85.129:WIN-9FBAEH4UV8C}

题三

3、获取当前系统浏览器搜索过的关键词,作为 Flag 提交;

使用iehistory插件获取浏览器历史记录:

1
vol2 -f 1.vmem --profile Win7SP1x64 iehistory | findstr /i url

alt text

得到flag为Flag{admin@file:///C:/Users/admin/Desktop/flag.txt}

题四

4、当前系统中存在挖矿进程,请获取指向的矿池地址,以 Flag{ip:端口}形式 提交;

使用netscan插件扫描已建立的网络连接:

1
vol2 -f 1.vmem --profile Win7SP1x64 netscan | findstr ESTABLISHED

alt text

得到flag为Flag{54.36.109.161:2222}

题五

5、恶意进程在系统中注册了服务,请将服务名以 Flag{服务名}形式提交。

上一题的挖矿进程即为恶意进程,并且获取网络连接时也看到了该进程的PID为2588,使用pslist插件查看该进程的详细信息:

1
vol2 -f 1.vmem --profile Win7SP1x64 pslist -p 2588

alt text

得到父进程PID为3036, 继续查看父进程的详细信息:

1
vol2 -f 1.vmem --profile Win7SP1x64 pslist -p 3036

alt text

得到进程名称:loader.exe

继续使用svcscan插件查看服务信息,并搜索loader.exe:

1
vol2 -f 1.vmem --profile Win7SP1x64 svcscan

alt text

得到服务名称为VMnetDHCP, 最终flag为Flag{VMnetDHCP}

题六

6、桌面上的flag.txt文件的内容是什么?

使用filescan插件扫描所有文件并过滤出flag.txt:

1
vol2 -f 1.vmem --profile Win7SP1x64 filescan | findstr flag.txt

alt text

复制此文件的内存地址并使用dumpfiles插件导出文件到当前目录,最后查看导出的文件内容即可:

1
2
vol2 -f 1.vmem --profile Win7SP1x64 dumpfiles -Q 0x000000007f1b6c10 -D .
type file.None.0xfffffa801a879510.dat

alt text

得到flag为flag{180d163ca48c793cb0db74fb96d6a882}

题七

7、病毒在自我删除时执行的命令是什么?

第5题已经知道了恶意进程的名称为loader.exe,并且PID为3036,使用procdump插件将该进程导出到exe文件:

1
vol2 -f 1.vmem --profile Win7SP1x64 procdump -p 3036 -D .

alt text

接着使用IDA打开该exe文件,按 Shift + F12 打开字符串窗口, 再按 Ctrl + F 搜索关键字 del:

alt text

得到一个残缺的删除命令:/c @ping -n 15 127.0.0.1&del

即flag为flag{/c @ping -n 15 127.0.0.1&del}

也可以在反汇编窗口(IDA View-A)中右键空白处,单击”Text view”将图形视图切换到文本视图,然后 alt + t 搜索关键字 del,再 ctrl + t 逐个排查相关的字符串:

alt text

3.2. [RoarCTF2019] forensic

获取镜像信息:

1
vol2 -f mem.raw imageinfo

alt text

扫描进程:

1
vol2 -f mem.raw --profile Win7SP1x86_23418 pslist

alt text

有5个可疑进程,分别是:

名称 PID 解释
TrueCrypt.exe 3260 磁盘加密软件,可能包含加密密钥、挂载的卷信息或其他加密相关数据
notepad.exe 3524 记事本,可能包含用户输入的文本内容
mspaint.exe 3620 画图工具,可能包含正在编辑的图像数据
iexplore.exe 3700 浏览器
iexplore.exe 3752 浏览器

使用memdump插件将前3个进程的内存数据导出:

1
2
3
vol2 -f mem.raw --profile=Win7SP0x86 memdump -p 3260 -D . 
vol2 -f mem.raw --profile=Win7SP0x86 memdump -p 3524 -D .
vol2 -f mem.raw --profile=Win7SP0x86 memdump -p 3620 -D .

alt text

然后尝试使用foremost从导出的文件中恢复文件:

1
2
3
foremost.exe -i e:\3260.dmp -o 3260
foremost.exe -i e:\3524.dmp -o 3524
foremost.exe -i e:\3620.dmp -o 2620

alt text

三个进程导出的文件中都有一个zip文件,打开后里面有一个flag.txt,不过压缩包被加密了,需要解密:

alt text

其中画图工具提取出来的3260.dmp文件可以还可以利用GIMP进行分析:https://segmentfault.com/a/1190000018813033?utm_source=tag-newest

首先将3260.dmp重命名为3260.dmp.data,然后用GIMP打开,接着把GIMP的窗口拉大,再调整位移、宽度、高度这3个参数,其中宽度和高度调整为适应窗口大小即可,重点在于调整位移,直到看到有明显的空白区域或者类似字符串的图案,如下:

alt text

然后再调整宽度,直到图像清晰,必要时候可以修改图像类型为RGB之外的:

alt text

图像清晰后点击打开,很明显这串字符串是翻转过的,使用视图菜单中的竖直翻转功能恢复即可:

alt text

得到字符串:1YxfCQ6goYBD6Q

将其作为zip文件的密码,解压得到flag.txt:

alt text

flag为:RoarCTF{wm_D0uB1e_TC-cRypt}

以上只是一种解法,实际上还可以对pslist扫描出来的iexplore.exe使用iehistory插件查看浏览过的文件,再结合filescan插件扫描文件可以找到一张图片,使用dumpfiles插件可以将其提取出来,打开就是上面获取到的解压密码,而TrueCrypt.exe导出的3260.dmp文件可以用Elcomsoft Forensic Disk Decryptor爆破磁盘挂载密钥,成功挂载后也会有一个zip文件,解压密码同样是图片中的字符串。具体可以参考:https://blog.csdn.net/weixin_45696568/article/details/115412467

3.3. HDCTF 2019 你能发现什么蛛丝马迹吗

获取镜像信息:

1
vol2 -f memory.img imageinfo

alt text

扫描进程:

1
vol2 -f memory.img --profile Win2003SP0x86 pslist

alt text

扫描失败,尝试使用第二个操作系统配置文件Win2003SP1x86:

1
vol2 -f memory.img --profile Win2003SP1x86 pslist

alt text

进程列表中除了内存转储工具DumpIt.exe,其他程序都是比较常见的系统程序,没有明显的可疑程序,并且这些程序都和DumpIt.exe的运行时间相差几个月,因此可以把重点放在文件分析上。

首先尝试下使用screenshot插件获取下伪屏幕截图:

1
vol2 -f memory.img --profile Win2003SP1x86 screenshot -D .

alt text

报错:ERROR : volatility.debug : Please install PIL,需要安装PIL库,安装命令如下:

参考:https://blog.csdn.net/m0_70712301/article/details/124833814

1
python2 -m pip install pillow

alt text

再次尝试获取伪屏幕截图:

alt text

提取出7张伪屏幕截图,逐个打开查看,只有session_0.WinSta0.Default.png中显示内容:

alt text

从屏幕中可以看到打开了资源管理器中的DumpIt目录,并且运行了DumpIt.exe,在左侧还可以看到有一个flag.png图片被打开,因此可以尝试使用filescan插件扫描该图片的物理内存地址:

1
vol2 -f memory.img --profile Win2003SP1x86 filescan | findstr.exe flag

alt text

再使用dumpfiles插件将物理内存地址对应的文件内容提取出来:

1
vol2 -f memory.img --profile Win2003SP1x86 dumpfiles -Q 0x000000000484f900 -D .

alt text

用图片查看器打开提取出来的file.None.0xfdbd16d0.dat文件,得到一张二维码:

alt text

扫码得到:jfXvUoypb8p3zvmPks8kJ5Kt0vmEw0xUZyRGOicraY4=

看样子像是一个base64编码的字符串,但是解码后会乱码,说明还需要相关的密钥才能解密。继续分析,使用windows插件查看伪屏幕截图中的flag.png图片是被哪个进程打开的:

1
vol2 -f memory.img --profile Win2003SP1x86 windows

alt text

Windows的volatility输出中文会报错退出,可以尝试使用管道符将输出重定向到文件中再查看:

1
vol2 -f memory.img --profile Win2003SP1x86 windows > windows.txt

打开windows.txt,找到打开flag.png的进程:

alt text

可以看到Windows图片和传真查看器这个窗口是由explorer.exe进程管理的,PID是1992,因此可以尝试使用memdump插件将PID为1992的进程内存转储:

1
vol2 -f memory.img --profile Win2003SP1x86 memdump -p 1992 -D .

导出后再使用foremost工具从1992.dmp中提取相关文件:

1
foremost -i e:\1992.dmp -o 1992

alt text

提取出的文件中除了有前面拿到的二维码,还有key和iv:

1
2
3
密文:jfXvUoypb8p3zvmPks8kJ5Kt0vmEw0xUZyRGOicraY4=
key:Th1s_1s_K3y00000
iv:1234567890123456

从密钥的长度来看,可以排除RSA加密,因为RSA的密钥通常是几百到几千位长,而且RSA加密也不需要使用初始向量(IV)。同样的,也可以排除DES,因为DES的密钥长度只有8字节,而这里的密钥”Th1s_1s_K3y00000”是16字节,对应的是128位,符合AES-128的标准密钥长度,因此可以猜测这里使用的是AES-128加密。

使用下面任意一个在线AES解密网站进行解密:

alt text

得到flag: flag{F0uNd_s0m3th1ng_1n_M3mory}