承接上文,上文中使用cuckoo沙箱的时候提到过,分析恶意代码的时候,首先利用沙箱做粗略分析,然后可以目标程序进行动态分析(OD,Windbg调试)或者静态分析(IDA静态反汇编).如果嫌每次逆向麻烦的话,同样可以借助Volatility这类框架来做内存取证分析.Volatility是一款非常强大的内存取证工具,它是由来自全世界的数百位知名安全专家合作开发的一套工具, 可以用于windows,linux,mac osx,android等系统内存取证,下面一起来体验一下吧.
最新版框架下载地址:
windows版可执行程序:http://downloads.volatilityfoundation.org/releases/2.6/volatility_2.6_win64_standalone.zip
linux版可执行程序:http://downloads.volatilityfoundation.org/releases/2.6/volatility_2.6_lin64_standalone.zip
Max OS X版可执行程序:http://downloads.volatilityfoundation.org/releases/2.6/volatility_2.6_mac64_standalone.zip
源代码:http://downloads.volatilityfoundation.org/releases/2.6/volatility-2.6.zip
可执行文件可以直接在相应的操作系统上运行.但是笔者更偏爱于源码包,因为该框架是使用python语言编写的,通过源码包可以方便的查看各个功能的实现代码.
首先安装python2.7,下载地址:(x64)https://www.python.org/ftp/python/2.7.8/python-2.7.8.amd64.msi,(x86)https://www.python.org/ftp/python/2.7.8/python-2.7.8.msi
如果想安装Volatility的源码,可以在命令行下切换到Volatility源码包的主目录,然后执行安装命令:
python setup.py install
如果不想安装源码包,也可以直接执行如下命令:
python vol.py
应该不出意外的话,会报如下错误.这是因为缺少pycrypto,distorm这两个辅助包.
下面一起来着手解决以上报错.
pycrypto包下载地址: https://github.com/dlitz/pycrypto.
distorm包下载地址:https://github.com/gdabah/distorm.
首先安装distorm包,解压并在命令行下切换distorm根目录下,执行安装命令:
python setup.py install
报错了,这是因为笔者实验机器上安装是vs2010,默认该源码中指定的编译器是vs2008,所以这里不认识.我们可以通过打开visual studio 2010的控制台,
然后输入如下命令:
set DISTUTILS_USE_SDK=1
set MSSdk=1
接下来切换到distorm包的根目录,然后执行安装命令:
python setup.py install
这样就表示这个包安装成功了.
接下来安装pycrypto这个包,同上,利用Visual Studio 2010的控制台,设置好环境变量,切换到pycrypto包的根目录,然后执行安装命令:
python setup.py install
这里报错了,前面的几个警告可以不用处理,后面的这个错误要解决,不然无法继续:
error C2133: "cipher_descriptor":未知的大小
笔者谷歌了一下,发现之前也有网友遇到类似的问题,但是貌似得到解决
其实没那么复杂,有点C语言基础的童鞋应该就很好解决.首先利用文本编辑器打开报错的头文件tomcrypt_cipher.h,接着定位到报错的行.
C语言定义数组要指定明确的数组大小,这里留空了,所以报错.这里我们尝试一下在方括号中间填入1.再安装依然报错.所以笔者接着查找了一下这个cipher_descriptor[]这个名称的交叉引用,发现这个名称并没有哪里引用到了,因此这里可以注视掉:
/*cipher_descriptor[]*/
接着执行安装命令:
python setup.py install
发现安装成功.
接着来运行Volatility,我们查看一下帮助菜单:
python vol.py -h
可以看到运行成功.
好了,windows下的源码包就介绍到这里,因为windows下控制台窗口看着不太舒服,笔者有点强迫症,所以笔者重点介绍linux下的使用.
kali依赖包基本都有,直接在shell下切换到Volatility的根目录,然后查看一下帮助信息.
python vol.py -h
比windows下的控制台看起来爽多了.
因为Volatility分析的是内存dump文件,所以我们需要对疑似受到攻击的系统抓取内存dump.主要有3种方法来抓取内存dump.
利用沙箱能够生成内存文件的特性
首先要修改一下cuckoo.conf以及reporting.conf这两个配置文件用以启用生成内存dump的选项.
接着保存,然后向cuckoo沙箱提交一个恶意样本
分析完毕以后在对应报告的目录下就能找到内存dump文件.
暂停虚拟机系统,然后在对应目录中找到*.vmem,例如:
针对于物理机,通常可以使用如下工具来抓取内存dump:
KnTTools
F-Response
Mandiant Memoryze
HBGary FastDump
MoonSols Windows Memory Toolkit
AccessData FTK Imager
EnCase/WinEn
Belkasoft Live RAM Capturer
ATC-NY Windows Memory Reader
Winpmem
Win32dd/Win64dd
DumpIt
使用-h或者–help可以列举出所有可用的选项以及插件
python vol.py --help
–info可以打印出所有已经注册的对象(插件)
python vol.py --info
结果如下:
这上面Profiles对于windows的内存取证来说至关重要.我们一般需要设置这个选项.
要弄明白这个选项的意义,我们首先需要来看一个新的名词-VTypes.
它是Volatility框架中数据结构定义以及解析的语言.大部分操作系统底层都是使用C语言编写的,其中大量使用数据结构来组织和管理相关的变量以及属性.因为Volatility是用Python语言编写的,所以我们需要一种方式在Python源文件中表示C语言的数据结构.VTypes正是用于实现这一点的.
举个例子:
C语言定义如下数据结构:
struct process{
int pid;
int parent_pid;
char name[10];
char* command_line;
void* ptv;
};
使用VType语言表示上面这个结构体就是这样的:
'process' : [ 26, {
'pid' : [ 0, ['int']],
'parent_pid' : [ 4, ['int']],
'name' : [ 8, ['array', 10, ['char']]],
'command_line' : [ 18, ['pointer', ['char']]],
'ptv' : [ 22, ['pointer', [' void']]],
}]
要看懂以上定义,需要懂一点python的基本语法,譬如:字符串,字典,键-值对,列表,元组,集合.
首先结构的名称process,是字典的第一个键,后面值对应的是一个列表,26表示结构体的大小.然后结构的所有成员是一个元组,
其中包含了成员的名称,然后就是成员位于结构体中的偏移,再就是成员的类型.
Volatility中随处可以见这样的表示法,譬如windows的关键内核数据结构_EPROCESS表示:
profile是特定操作系统版本以及硬件体系结构(x86,x64,ARM)中VTypes,共用体,对象类型的集合.除了这些组件以外,profile还包括如下:
元数据:操作系统的名称(例如:”windows”,”mac”,”linux”),内核版本,以及编译号.
系统调用信息:索引以及系统调用的名称
常量值:全局变量-在某些操作系统中能够在硬编码的地址处找到的全局变量
系统映射:关键全局变量和函数的地址(仅限Linux和Mac)
每个profile(配置文件)有个一个唯一的名称,通常是由操作系统的名称,版本,服务包,系统结构等信息组成.例如:Win7SP1x64是64位的Windows 7 SP1系统配置文件的名称.
我们通过–info选项来查看一下Volatility支持哪些profile值.
我们可以看到从xp-win10都有.为什么要设置配置文件这个选项呢,因为不同版本的操作系统,其中的内核数据结构成员以及偏移可能会发生改变.
python vol.py -f <文件名> --profile=<配置文件> <插件> [插件参数]
例如:
python vol.py -f /opt/cuckoo/storage/analyses/9/memory.dmp --profile=Win7SP1x86 volshel
如果我们不指定–profile这个选项的话,默认这个选项为WinXPSP2x86.
我们可以使用imageinfo插件来猜测dump文件的profile值.
python vol.py -f /opt/cuckoo/storage/analyses/9/memory.dmp imageinfo
我们可以注意到这里有多个profile值可选.因为这些操作系统的很多特性都是类似的.imageinfo这个插件猜测profile值的功能是基于kdbgscan这个插件的功能来实现的.而kdbgscan这个插件是通过查找分析内核调试器数据块(_KDDEBUGGER_DATA64)的特征来猜测profile值的.
调试器数据结构位于NT内核模块中(nt!KdDebuggerDataBlock).它包含一个编译字符串,比如:3790.srv03_sp2_rtm.070216-1710,数字值指明了目标操作系统的主,次版本号以及服务包号.
kdbgscan插件扫描dump文件的profile值
可以看到有多个结果,通常来说第一个结果是正确的.imageinfo,kdbgscan这两个插件仅适用于Windows系统的内存dump文件.而Linux,Mac确定正确的profile值有其他的方法.
现在我们就可以指定profile这个选项的值了.
python vol.py -f /opt/cuckoo/storage/analyses/9/memory.dmp --profile=Win7SP1x86_23418 volshell
volshell这个插件用于进入Volatility专属的shell.在该shell中可以利用dt(“内核关键数据结构名称”)命令来查看操作系统内核关键数据结构的定义.
有没有感觉跟windbg中的dt命令有点类似.
python vol.py -f /opt/cuckoo/storage/analyses/9/memory.dmp --profile=Win7SP1x86_23418 pslist
Exit这一列如果显示出日期时间,表示该进程已经结束.但是pslist这个命令无法显示出隐藏的进程.后续再来介绍如果查看隐藏的进程.
Volatility是一款非常强大的内存取证分析框架,同样可以用于学习研究特定操作系统的内核体系结构.可能有些童鞋说对于windows的取证分析完全可以用AntiRootkit工具,例如,Xuetr(PcHunter),PowerTool,但是这类AntiRootkit通常是通过加载内核驱动程序来实现的相应功能,而且通常都不开源,想要弄清楚其实现原理的话,还需要花费大量时间进行逆向分析。
而Volatility恰恰相反,不需要加载驱动程序,完全python语言编写,开源,需要了解特定功能的实现,完全可以自己查看源代码研究学习,而且支持Windows,linux,Mac OS X,Android,对于提升正向,逆向分析能力大有裨益.全世界数百位安全专家倾力打造.还有有了这款工具,不用每每要查看windows内核数据结构定义的时候都去打开windbg进行双机调试或者本地内核调试.在Volatility的专属shell中执行dt命令就可以完成同样的功能.后续笔者再带来利用Volatility分析Windows恶意代码的其他实践内容.
The Art of Memory Forensics
深入解析Windows操作系统
http://www.volatilityfoundation.org/
https://github.com/volatilityfoundation/volatility