内存取证,比使用工具更重要的是遵循正确的分析过程,首要应该是找到第一个异常点。
第一步从进程分析开始,因为它们是内存中最重要的对象。通过仔细检查分配给每个进程的所有各种对象。
第二和第三步,分析加载的库 (DLL)、文件、注册表项、网络套接字等。如果还没有发现任何异常情况,需要考虑是否存在代码注入或者Rootkit 植入的痕迹。Rootkit 可能很难在文件系统上被发现,但从内存的角度来看,它们通常非常明显。最后,提取所有可疑进程、驱动程序和内存页,并通过恶意软件逆向分析或简单的防病毒扫描继续进行分析。
如何对一个内存映像文件进行分析,一般思路如下:
识别异常进程
分析异常进程 DLL 和句柄
分析异常进程的网络通信
发现代码注入的痕迹
发现 Rootkit 植入的痕迹
转储可疑进程和驱动程序
识别异常进程:
正确的图像/可执行名称
正确的文件位置(路径)
正确的父进程
使用正确的命令行和参数
开始时间信息
Volatility 提供了多种识别异常进程的插件:
pslist -p [pid] :进程环境块链表中的高级视图
psscan:进程环境块的低级视图,通过扫描进程块的所有内存,可以识别隐藏的进程,还能识别不再运行的进程
pstree -v :直观地显示父进程关系
malprocfind -x :扫描系统进程是否存在异常,-x 包括退出的进程,扫描smss、csrss、winlogon、services、lsass、svchost、spoolsv、wininit等,执行 13 项检查,包括预期的进程计数和缺失的父进程,旨在发现伪装成合法系统进程的恶意软件
baseline:将可疑映像中发现的内存对象与基线映像中存在的内存对象进行比较
DLL:动态链接库定义进程的功能。例如,如果一个进程需要通过 HTTP 进行通信,它将加载 WININET.dll 文件。在某些情况下,恶意软件会加载其自己的恶意 DLL 来控制进程。
句柄:指向资源的指针,句柄以多种不同的形式存在。一些最重要的数据结构是:
文件句柄:标识文件系统中的哪些项目或哪些 I/O 设备正在被访问过程。
目录句柄:这不是您的标准文件系统目录。相反,目录句柄是内核中允许进程查找内核对象的已知列表。常见的例子是KnownDll、BaseNamedObjects、回调、设备和驱动程序。
注册表句柄:这些是进程正在读取或写入的注册表项。
互斥量或信号量句柄:也称为“突变体”,这些对象控制或限制对资源。例如,一个对象可能会使用一个互斥体来强制同一时间只有一个进程。时间可以访问它。蠕虫通常将互斥量设置为“标记”受感染系统的一种方式,因此它不会被再次感染。
事件句柄:事件是进程线程进行通信的一种方式。恶意软件偶尔会使用独特的事件句柄。
线程:进程只是所有执行实际工作的项目的容器。多线程运行在与各种系统对象交互的每个进程中。
Volatility 插件:
dlllist:打印每个进程加载的 DLL 列表
cmdline:显示每个进程的命令行参数
getsids:打印每个进程的所有权 SID
handles:打印每个进程的打开句柄列表
mutantscan:扫描内存中的变异对象 (KMUTANT)
connections:打印活动的、打开的 TCP 连接列表(XP/2003)
connscan:扫描内存中的 TCP 连接,包括那些已关闭或未链接的连接(XP/2003)
sockets:打印活动的可用套接字列表(任何协议)(XP/2003)
sockscan:扫描内存中的套接字,包括那些关闭或未链接的套接字(任何协议)(XP/2003)
netscan:功能包含以上所有,同时扫描连接和套接字(Vista+)
代码注入在现代恶意软件中非常常见
Windows 的内置功能!
VirtualAllocEx() 和 CreateRemoteThread()
SetWindowsHookEx()
反射注入加载代码而无需向主机进程注册
基于 PowerShell 的注入越来越受欢迎
进程镂空是另一种注射技术
恶意软件启动合法进程的暂停实例
取消分配和替换原始流程代码
可以保留原始进程中的 DLL、句柄、数据等
进程映像 EXE 没有磁盘上的文件 -> 进程镂空
从插件 ldrmodules 开始,以检测未链接的 DLL,这在恶意软件中很常见。malfind 是一个强大的插件,能够检测不同的代码注入攻击。
Hollowfind 是一个专门识别试图进程镂空行为。Hollowfind 将存储在进程环境块 (PEB) 中的信息与应在进程的虚拟地址描述符 (VAD) 中匹配的信息进行比较。它还会查找异常内存段权限。
此类别中的最新插件是 threadmap,用于识别进程镂空行为。
Threadmap 使用线程作为主要信息源,更难操纵和隐藏(线程位于内核中,需要运行代码,所以如果你想让你注入的代码执行,它必须有一个线程指向它)。每个线程都映射到其相应的 VAD 条目,线程映射使 VAD 条目及其包含的代码接受一系列检测以识别异常。threadmap 等插件对于识别这种新型恶意软件将非常有用。
ldrmodules:检测未链接的 DLL 和非内存映射文件
malfind:查找隐藏和代码注入并转储受内存部分
threadmap:分析线程以识别进程镂空
hollowfind:识别已知进程镂空的痕迹
reference
Analyzing Malware Hollow Processes: https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/analyzing-malware-hollow-processes/
系统服务描述符表 (SSDT)
内核指令挂钩
中断描述符表 (IDT)
内核挂钩;在现在系统上不是很常见
导入地址表 (IAT) 和内联 API
用户模式DLL函数挂钩
Volatility apihooks模块最适合识别
I/O 请求数据包 (IRP)
驱动程序挂钩
Rootkit 加载进内核以隐藏响应工具的进程、文件、注册表项和网络连接。然而,一旦我们获得了系统的内存映像,识别 Rootkit 就变得更加可行。
Volatility 中检测Rootkit相关插件:
ssdt:显示系统服务描述符表条目
ssdt_ex:识别并转储系统服务描述符表条目
psxview:通过交叉视图技术查找隐藏的进程
modscan:扫描加载的内核驱动程序
module:列出加载的内核驱动程序
apihooks:查找DLL函数蹦床或内联挂钩
Idt:显示中断描述符表挂钩
driverirp:识别 I/O 请求数据包 (IRP) 挂钩
挂钩系统服务描述符表 (SSDT)非常有效,但也很容易被注意到。SSDT 包含指向为 Windows 提供支持的各种内核函数的指针。
挂钩这些函数的优点是它们是全局的:挂钩对系统上的任何进程都有效。缺点是它需要更改内核,这可能会危及正在运行的系统的稳定性。
从 Vista 开始,当 SSDT 和其他关键内核数据结构发生异常更改时,内核补丁保护(称为 PatchGuard)现在将先发制人地使系统崩溃。虽然这并不能消除在 Vista 及更高版本中找到这些挂钩的可能性(每种保护总是有反制措施,包括现在在野外的几种反 PatchGuard 攻击),但它确实大大降低了挂钩系统服务描述符表 (SSDT)的可能性。
我们可以使用 Volatility 插件 ssdt 识别系统服务描述符表 (SSDT) 挂钩。该插件不仅会显示可疑的系统服务描述符表 (SSDT)条目,还会打印各种可用的 系统服务描述符表 (SSDT)中的每个条目。对于每个表条目,提供以下内容:
条目
函数偏移
功能
函数所有者(SSDT 条目将请求发送到的模块)
为了确定哪些系统服务描述符表 (SSDT)中的系统调用可能被挂钩,我们需要过滤掉 ntoskrnl.exe 和 win32k.sys 中的引用,它们拥有系统服务描述符表 (SSDT)跟踪的绝大多数合法函数。如果我们忽略任何指向这两个模块的系统服务描述符表 (SSDT)条目,那么任何恶意驱动程序都会变得显而易见。
通过将插件结果输送到扩展的 grep 工具中可以轻松完成过滤:egrep -v '(ntoskrnl.exe | win32k.sys)' 。请注意,一小部分系统可能会加载不同的内核(ntkmlpa.exe 或 ntkmlmp.exe)而不是 ntoskrnl.exe,因此可能需要修改 egrep 过滤语句。
ssdt:显示系统服务描述符表条目
ssdt_ex:识别并转储系统服务描述符表条目
直接内核对象操作(DKOM)是一种高级进程隐藏技术,DKOM 允许恶意软件直接在内存中更改内核对象,可用于更改几乎任何内核对象,但一般是从双向链表中取消一个 EPROCESS 的链接。
例子:FU, Myfip.H worm, Fanbot.A worm, Prolaco
psxview:通过交叉视图技术查找隐藏的进程
modscan:扫描加载的内核驱动程序
module:列出加载的内核驱动程序
driverbl:可疑内存映像和要比较的基线映像。它由三个执行比较的初始插件组成:Processbl 比较进程及其加载的 DLL(使用类似于 pslist 和 ldrmodules 的数据对象)。Servicebl 使用 svcscan 组件比较服务,driverbl 将加载的驱动程序与 modscan 进行比较。
reference
https://www.f-secure.com/v-descs/rootkit-w32-tdss-gen!a.shtml
随着 IDT 和 SSDT 挂钩等技术越来越多地被系统保护应用程序扫描和阻止,攻击者转向了新方法。导入地址表 (IAT) 挂钩是这些技术中最简单的,只需要更改进程 IAT 中的地址位置。Inline/trampoline hooks 类似于 IAT hooks,因为它们都拦截进程函数调用。主要区别在于,内联挂钩不是操纵进程导入地址表,而是修改函数本身,向恶意代码添加跳转(或等效)。
apihooks:检测 Rootkit 用来修改和控制返回信息的内联和导入地址表函数挂钩
apihooks 插件的输出可能难以分析。存在大量合法的钩子。合法挂钩应用程序的示例包括 svehost、vmtools、安全工具和 codemeter/hasp 复制保护机制。使用“-p”选项仅将分析重点放在可疑进程上有助于限制数据集。此外,Brian Milliron 在他的 SANS SCORE 调查 rootkit 指南中编制了一份已知可合法挂钩其他函数的 Microsoft DLL 列表。记住这些“合法”挂钩有助于识别许多误报:
reference:
https://www.adlice.com/?s=KernelMode+Rootkits&lang=en
https://memn0ps.github.io/rusty-windows-kernel-rootkit/
Rootkit 隐藏了进程、文件、注册表项和网络等,Rootkit 可能更难识别。
可以挂钩各种系统位置:
系统服务描述符表 (SSDT)
中断描述符表 (IDT)
函数导入地址表 (IAT)
I/O 请求数据包 (IRP)
Volatility具备识别各类系统挂钩:
ssdt:显示系统服务描述符表条目
ssdt-ex:识别并转储系统服务描述符表条目
psxview:通过交叉视图技术查找隐藏的进程
modscan:扫描加载的内核驱动程序
modules:列出加载的内核驱动程序
apihooks:查找DLL 函数(内联和trampoline)挂钩。
Idt:识别中断描述符表挂钩
driverirp:识别 I/O 请求数据包 (IRP) 挂钩
dlldump 从进程中转储 DLL
moddump 将内核驱动程序转储到可执行文件
procdump 将进程转储到可执行文件
memdump 将进程的所有可寻址内存转储到一个文件中
cmdscan 扫描 COMMAND_HISTORY 缓冲区
console 扫描 CONSOLE_INFORMATION 输出
dumpfiles 按名称或物理偏移量提取文件
filescan 扫描内存中的 FILE_OBJECT
shimcachemem 从内存中提取应用程序兼容性缓存