前言: 计算机内存取证是计算机取证的一个分支结构,在以往的人们认识中认为只要内存断点后数据会立即消失,但随着大牛(又是美国的)有次的意外发现,只要往里面碰点(类似于固化剂英文我也不知道怎么翻译)试剂就可以固化当前状态。由此拉开了计算机取证中内存取证这个取证分支。 内存取证的步骤之获取计算机内存 顾名思义取证之前你肯定是要将当前内存数据获取到才可以,不难没有数据集你取证啥,当前内存获取的主要方法有两个(科研界是这样说的):硬件、软件。 基于硬件的获取: 利用JTAG技术获取计算机的内存数据。它主要是通过在印刷电路板上与特定的JTAG接头相连以连接智能终端设备中的CPU,在向电路供电后,再借助JTAG软件转储整个内存数据。该方法的优点是无需获得智能终端设备的Root访问权限即可实现内存数据获取,但其缺点是,如果JTAG焊接点出错或供电电压错误,则将导致JTAG无法使用,且对智能终端设备造成严重损坏。这种方法估计很少有人有机会因为个人很少花钱买这种设备,只有大学实验室才会买。 基于软件的获取: 利用计算机蓝屏内存转储技术或者内存转存工具软件,如MoonSols DumpIt、Win32DD和FTKImager等,获得正在运行的Ms-windows内存镜像,也就是内存的一份快照。本人习惯用DUMPIT来获取。当然你还可以利用VMware试验获取。 内存取证之数据分析从内存中可以获取到哪里数据这是我们比较关心的问题。内存取证有哪些作用这才是大家想知道的问题,这里一windows内存取证为例来说明。 一、获取内核对象的数据结构(针对Ms-Windows)②启动Windbg,File->Symbol File Path填写以上Windows Symbol Packages安装路径,如D:\ProgramFiles\Symbols。 ③ File->Kernel Debug->Local选择本地内核调试,如果这个时候调试显示不能加载Symbols package就将第三步的“Symbol File Path”替换成“D:\ProgramFiles\Symbols;SRV*D:\ProgramFiles\Symbols* http://msdl.microsoft.com/download/symbols”这样它就可以在线获取Symbols Packages; ⑤利用dt命令调试计算机内核对象的数据结构,获得内核对象Eprocess,Kprocess和Peb。如“dt !_Eprocess”可以获取Eprocess的数据结构,“dt!_ Kprocess”可以获取Kprocess的数据结构。 获取这个内核对象数据结构的用处主要是用来做分析用的。因为任何进程在内存中都有个EProcess结构来替代。 二、获取当前操作系统运行的进程信息A、遍历Eprocess就可以枚举出系统运行着的进程信息。因为在Eprocess中的第一项是Kprocess,而PCB(Process Control Block)就是Kprocess一个子项。所以有多少个Eprocess结构就有多少个运行着的进程。 B、 重构进程地址空间。 Eprocess中VadRoot指向自适应平衡二叉树树根,利用VadRoot可以重构进程的物理地址空间。 获取Eprocess中VadRoot值之后,可以利用虚拟地址与物理地址转换方法,递归遍历由VadRoot指向的根节点的二叉树,就可以重构进程的地址空间。这里,Eprocess中VadRoot用于指向地址空间的自适应平衡二叉树树根。 说了这么多感觉越讲越复杂了,这个就像是手工注入和用sqlmap注入感觉是一样的其实这些功能都已经集成到了内存取证工具Volatility是一样的。下面是我自己写的一个小工具
三、获取当前进程加载的模块在Eprocess中Peb指向进程的PEB结构,在Peb结构中存在Ldr项,而Ldr指向_PEB_LDR_DATA结构。在_PEB_LDR_DARA的中的结构InLoaderModulist值指向的进程加载模块双链表的头节点。双链表每一项是_LDR_DATA_TABLE_ENTRY结构,_LDR_DATA_TABLE_ENTRY结构代表着进程加载模块信息,每一个加载模块都对应着一个_LDR_DATA_TABLE_ENTRY结构。利用这个模块结构可以获取进程加载模块信息,如加载模块大小、起始地址、名字。 这个主要是用来做什么呢?这个主要可以用来预防一些简单的Rootkit!这是我想到的唯一应用,因为你可以枚举它的所有加载模块,这样别人加载的病毒模块也能枚举出来,望深了就是windows RootKit的东西了,还没研究下去。
四、获取注册表信息注册表在硬盘上是以层次文件的形式存在的,但是其实它是以文件的形式存在的,只是注册表编辑器对其进行了良好的解析,所以我们从对注册表取证主要有注册表文件的获取,但同时对于注册表我们光获取到文件还是不够的,如果不对文件进行获取那么注册表文件对我们就是一堆无用的数据,所以我们还要考虑打开的注册表键值信息的获取。 表 4.2 CMHIVE数据结构 | nt!_CMHIVE +0x000 Hive : _HHIVE +0x2ec FileHandles : [6] Ptr32 Void +0x304 NotifyList : _LIST_ENTRY +0x30c HiveList : _LIST_ENTRY +0x314 PreloadedHiveList : _LIST_ENTRY +0x31c HiveRundown : _EX_RUNDOWN_REF +0x320 ParseCacheEntries : _LIST_ENTRY +0x328 KcbCacheTable : Ptr32 _CM_KEY_HASH_TABLE_ENTRY … +0x3c4 SecurityCache : Ptr32 _CM_KEY_SECURITY_CACHE_ENTRY …… +0x5d0 RootKcb : Ptr32 _CM_KEY_CONTROL_BLOCK …… |
Ms-Windows配置管理器将注册表文件加载进内存后主要是以CMHIVE结构的形式加入到计算机内存中的,所以我们可以通过在内存镜像中查找CMHIVE结构的方式从内存镜像获取到内存注册表文件的值。从表4.2可以知道CMHIVE的第一个结构是HHIVE,我们可以用“reg”命令加上“dt”来得到它的特征串。同时所有的CMHIVE结构通过它_LIST_ENTRY结构链接成一个双向链表。同时HHIVE结构体也是从计算机内核对象池分配的所以它自己的PollTag的值,经过调试发现HHIVE的起始特征串为0xbee0bee0,同时它也是从内核分页内存池分配的,所以也有自己的“pooltag”,最后经过调试发现它的职位“CM10”所以我们可以通过这两个特征来定位内存镜像中的CMHIVE文件,这样就可以得到系统的注册表文件。 写在最后: 随着volatility的发展慢慢的我也加入了他们的队伍,但愿可以看到更多国人的身影。。。。 https://github.com/volatilityfoundation/volatility |