内存取证实用指南-全-
内存取证实用指南(全)
原文:
annas-archive.org/md5/4485621706f1c64128a5ddfcd6116461译者:飞龙
前言
内存取证是一种强大的分析技术,可以应用于从事件响应到恶意软件分析的多个领域。对于经验丰富的调查员来说,内存是获取宝贵数据的重要来源。内存取证不仅能提供关于用户上下文的关键信息,帮助你寻找恶意软件的独特痕迹,而且在某些情况下,还能帮助拼凑出复杂目标攻击的全貌。
本书将带你了解内存取证的概念,并逐步深入到更高级的概念,讲解如何使用免费工具和内存分析框架来捕猎和调查高级恶意软件。本书采用实践导向,通过来自实际事件的内存映像帮助你更好地理解该主题,从而掌握调查和应对恶意软件事件及复杂目标攻击所需的技能。本书涉及 Windows、Linux 和 macOS 的内部结构,并涵盖了使用内存取证检测、调查和捕猎威胁的概念、技术和工具。
本书结束时,你将精通内存取证,并获得使用相关工具的实际操作经验。你将能够独立创建和分析内存转储,检查用户活动,检测无文件恶意软件的痕迹,并重建威胁行为者的行动过程。
本书适用对象
本书面向事件响应人员、数字取证专家、网络安全分析师、系统管理员、恶意软件分析师、学生以及对内存取证感兴趣的好奇的网络安全专业人士。假设读者已具备对恶意软件及其工作原理的基本理解。掌握操作系统内部结构的知识将有所帮助,但并非强制要求。对于该领域的新手,本书将提供足够的信息帮助理解。
本书内容
第一章,为什么选择内存取证?,通过现实世界的例子解释了内存取证为何成为如今许多数字取证检查中的重要部分,描述了 DFIR 专家使用的主要目标和调查技巧,并讨论了他们面临的日常挑战。
第二章,获取过程,介绍了内存获取的基本技巧和工具,以及与此过程相关的可能问题。此外,你将有机会比较实时内存分析与内存转储分析,了解各自的优缺点。
第三章,Windows 内存获取,讨论了 Windows 内存获取工具及其对内存工作的处理方式。书中还将讨论如何选择合适工具的一些建议,并提供全面的示例。
第四章,通过 Windows 内存取证重构用户活动,探讨了重构用户活动的重要性,因为它可以更好地帮助理解发生了什么。本章将提供一些基于运行进程、网络连接、Windows 注册表和内存中的文件系统分析的用户行为恢复技术的见解。
第五章,通过 Windows 内存取证进行恶意软件检测与分析,探讨了现代恶意软件往往尽可能减少在磁盘上的痕迹,这也是内存分析成为法证调查关键要素的原因。本章将解释如何在进程内存中以及在 Windows 注册表、事件日志和内存中的文件系统遗留物中搜索恶意软件痕迹。
第六章,易失性内存的替代数据源,讨论了有时无法创建内存转储进行分析的情况,然而,总有机会在磁盘上找到一些易失性内存。本章介绍了 Windows 中易失性数据的替代来源,以及它们的分析工具和技术。
第七章,Linux 内存获取,展示了 Windows 和 Linux 内存获取之间的核心差异。将介绍用于 Linux 内存获取的工具,并讲解其配置和使用案例。
第八章,用户活动重构,探讨了在 Linux 系统中重构用户活动与 Windows 中有所不同的方式。本章将介绍如何通过 Linux 内存转储追踪用户活动的几种技巧。
第九章,恶意活动检测,重点介绍了在 Linux 系统中搜索恶意活动并进行分析所需的技术。
第十章,MacOS 内存获取,与获取过程相关,重点介绍 macOS 内存获取工具及其使用,帮助你能够从所有流行的操作系统中创建内存转储。
第十一章,使用 macOS 内存取证进行恶意软件检测与分析,探讨了可以帮助我们获取必要数据来追踪用户行为并检测和分析 macOS 内存中恶意活动的技术。
如何最大限度地利用本书
在本书中,我们试图以非常详细的方式描述所有内容,并一步步带领你完成整个过程。因此,你所需要的只是一台安装了 Windows 和 Linux 的计算机或虚拟机。
由于本书以实践为导向,我们建议您尝试书中描述的所有方法和工具,以最大程度地利用本书的内容。
下载彩色图片。
我们还提供了包含本书中使用的截图/图表的彩色图片 PDF 文件。您可以在此下载:static.packt-cdn.com/downloads/9781801070331_ColorImages.pdf。
使用的约定
本书中使用了多种文本约定。
文本中的代码:表示文本中的代码词汇、数据库表名、文件夹名称、文件名、文件扩展名、路径名、虚拟网址、用户输入和 Twitter 用户名。举个例子:“要找到这样的进程,您可以使用 psscan 插件。”
任何命令行输入或输出都如下所示:
C:\WINDOWS\system32> wmic process list full
粗体:表示新术语、重要词汇或您在屏幕上看到的词汇。例如,菜单或对话框中的词汇在文本中呈现如下:这是一个例子:“依赖本地资源是一种非常流行的方法,攻击者利用内置工具和已安装的合法软件为自己谋取利益。”
提示或重要注意事项
如下所示。
联系我们
我们始终欢迎读者的反馈。
customercare@packtpub.com。
勘误:尽管我们已尽最大努力确保内容的准确性,但错误还是会发生。如果您发现本书中的错误,我们将非常感激您能向我们报告。请访问 www.packtpub.com/support/errata,选择您的书籍,点击“勘误提交表单”链接,并输入相关详情。
copyright@packt.com 并附带该材料的链接。
如果您有兴趣成为作者:如果您对某个主题有专业知识,并且有兴趣编写或参与编写一本书,请访问 authors.packtpub.com。
分享您的想法
阅读完《实用内存取证》后,我们很想听听您的想法!请点击 packt.link/r/1-801-07033-4 直接前往亚马逊的评论页面,并分享您的反馈。
您的评论对我们和技术社区至关重要,将帮助我们确保提供高质量的内容。
第一部分:内存取证基础
本节不仅将向你介绍内存取证的好处,还将介绍易失性内存的基本概念及其获取与分析的过程,让你对该主题有一个大致的了解。
本书的这一部分包括以下各章:
-
第一章,为什么选择内存取证?
-
第二章,获取过程
第一章:为什么选择内存取证?
我们生活在一个变化无常的世界里,而网络犯罪也不例外。新的攻击技术不断被开发出来,数百种恶意程序和脚本被编写并测试,以绕过安全控制,同时扫描器也在互联网世界中仔细检查易受攻击的主机和公开的服务。这就是为什么保持与时俱进并拥有各种工具和技术以便与威胁行为者保持同步显得尤为重要。
那么,为什么内存取证在今天的许多数字取证检查和事故响应工作中是至关重要的一部分?数字取证和事故响应专业人员使用的主要调查目标和技术是什么?他们每天面临哪些挑战?你将在本章中找到这些问题的答案。
本章将涵盖以下主题:
-
了解内存取证的主要好处
-
了解调查目标和方法
-
发现内存取证的挑战
了解内存取证的主要好处
自然地,对于拿起这本书的读者来说,好处是显而易见的。既然你已经决定深入了解内存取证,想必你有自己的原因。不过,让我们再来看看随机存取内存(RAM)调查可以在以下几种常见情况下发挥重要作用的场景(不仅仅是在数字取证中,还有事故响应和恶意软件分析中),也许你会发现自己所学的知识和技能还有新的应用场景。
没有留下任何痕迹
过去几年,使用地面生存和无文件攻击技术的威胁行为者数量大幅增加。攻击者不再像以前那样关心清除自己的痕迹,而是尽量留下尽可能少的痕迹以避免被检测到。这使得信息安全专业人员的工作变得更加困难,因为内建工具的使用和磁盘上没有恶意文件可供扫描意味着一些传统的安全解决方案可能失效。缺乏日志记录可能使得在事后检查过程中很难重建威胁行为者如何滥用内建的双用途工具,例如各种命令和脚本解释器,因此获取和分析内存可能在这些案例中起到关键作用。
让我们分别讨论每个案例。
在内存中找到我
让我们从专门在内存中工作的恶意软件谈起。这个概念本身并不新鲜。当谈到内存驻留恶意软件的时代初期时,一些研究人员提到马耳他变形虫,这是一种 1991 年在爱尔兰首次发现的病毒。也有些人喜欢从 2001 年出现的Code Red蠕虫谈起。无论如何,自 21 世纪初以来,无文件攻击势头越来越强,并变得越来越流行。例如,载荷可能通过 PowerShell 直接注入到内存中,这已经变得极为普遍。进程注入技术本身已被许多网络安全厂商列入 2020 年 MITRE ATT&CK®十大技术之一。例如,以下是Red Canary 2021 年威胁检测报告中的十大技术,来源于redcanary.com/threat-detection-report/techniques/:

图 1.1 – 2020 年 MITRE ATT&CK 十大技术
进程空洞化、动态链接库注入、进程双胞胎等进程注入子技术不仅被高级的国家支持的威胁团体使用,甚至普通的恶意软件操作者也会使用。
工作框架
另一个问题是使用大量后渗透框架,如 Metasploit、Cobalt Strike 或 PowerShell Empire。这些工具为攻击者提供了广泛的选项,可以生成各种恶意载荷并将其注入内存。
这些框架最初是为进攻性安全而设计的,最先让渗透测试人员和红队员使用,随后各种威胁行为者也开始使用它们。这些框架使得即便没有出色的恶意软件开发经验的攻击者,也能以非常有限的磁盘足迹使用各种技术。例如,Cobalt Strike 的 Beacon 载荷的非托管 PowerShell 功能允许威胁行为者在不实际运行powershell.exe的情况下执行,反而是滥用 Windows API 来实现。
像 Cobalt Strike 这样的框架已经变得如此普遍,以至于一些威胁行为者甚至使用它们代替定制恶意软件。例如,臭名昭著的 Evil Corp 集团,其成员被认为是多个高知名度勒索软件攻击的幕后黑手,包括 Garmin 公司,已将 Dridex 木马转为 Cobalt Strike 的 Beacon,在其WastedLocker攻击活动中使用。
利用现有资源
利用现有资源是一种非常流行的方法,攻击者利用内置工具和已安装的合法软件来达到自己的目的。例如,大多数工具,如 PowerShell 或 WMI,通常由系统管理员用于执行日常任务,这使得不仅仅是发现攻击者变得困难,而且要阻止攻击者使用的工具也非常有挑战性。
攻击者可以利用“以土地为生”(living-off-the-land)技术,采取多种策略。PowerShell 可以用于从攻击者控制的服务器下载初始有效载荷,像rundll32.exe和regsvr32.exe这样的二进制文件可以用于执行和防御规避,Ntdsutil可以被用来访问凭证,PsExec和WMIC则可以被滥用进行远程执行。有许多类似的例子,如果 IT 基础设施没有先进的日志记录功能,分析师提取这些信息的机会可能非常低。如果能及时获取,内存分析可能会提供极大的帮助!
另一个重要的提醒是,在许多情况下,你只能在磁盘上找到恶意二进制文件的第一阶段——下一阶段(甚至可能是接下来的多个阶段!)直接从服务器加载到内存中,因此,如果没有内存镜像,在事后分析时你将无法看到它。
更重要的是,现在大多数恶意二进制文件都经过打包、编码和加密,以避免被检测到,但在内存中却不会如此!因此,你可以使用像 PE-sieve 这样的工具来收集潜在的恶意代码进行进一步分析。当然,我们将在接下来的章节中向你展示如何操作。
隐私保护者
近年来,隐私问题变得更加严峻。每天都有大量个人数据、照片和消息出现在网络上。服务提供商收集关于我们个性、兴趣和日常习惯的信息,以提高工作效率和实用性。即时通讯工具、带隐私模式的浏览器、内存文件系统、密码管理器和加密容器应运而生。
当然,隐私是每个人关心的问题,但它与网络犯罪分子最为相关,因为他们确实有东西需要隐藏。我们不止一次看到过在嫌疑人计算机上发现的感兴趣文件被加密或保存在加密容器中的情况。在这种情况下,内存收集和分析是打开所有大门的钥匙,因为它可以帮助调查人员恢复解密所需的密码和密钥。
正如你所见,存在不同的案例,但它们都有一个共同点,那就是在每一个案例中,内存取证都可以发挥极其重要的作用。
了解调查目标和方法
任何取证调查的基础都是目标设定。目标决定了要寻找的证据、使用的方法以及我们需要的工具。正确的目标设定方法有助于快速高效地实现预期结果。还记得那个著名的"分而治之"原则吗?尽管它的起源和主要目的是如此,这个原则对于实现任何目标都非常有效,关键是理解该分解什么,以及如何使用它。作为调查目标设定的一部分,这一原则可以用来将主要目标分解成更小、更简单的目标。因此,通过将目标分解成各个部分,我们得到了一个具体行动的集合,最终的结果就是拼凑出事件的全貌,所有我们需要做的就是将这些碎片拼接起来。
让我们从更一般的目标开始。如果我们接收到与事件相关的设备进行检查,那么很可能它是以下之一:
-
被害人的设备
-
嫌疑人的设备
让我们在接下来的部分中探讨这两者。
被害人的设备
假设被害人的设备正在调查中。在这种情况下,主要目标是回答问题,发生了什么? 一种方法是将这个问题分解成几个部分:
-
攻击者是如何进入系统的?
-
启动了哪些工具?
-
攻击者是否获得了持久性?
-
是否有横向移动的迹象?
-
在目标上执行了哪些操作?
现在让我们用相同的方法来思考问题,攻击者是如何进入系统的?:
-
是否有潜在恶意文件/链接被打开的痕迹?
-
是否有远程连接服务正在运行?
-
是否有可疑连接的痕迹?
-
是否有可移动设备连接的痕迹?
让我们也提问有关恶意文件的问题:
-
是否有保存可疑文件的痕迹?
-
是否有打开可疑链接的痕迹?
-
是否有可疑文件被打开的痕迹?
寻找这些问题的答案不仅需要了解数字证据及其来源,还需要了解攻击者的战术、技术和程序,因此这样的评估必须是以网络威胁情报为驱动的。
这是每个上级问题应该分解的层次。因此,我们最终得出了一个问题列表,这些问题将帮助我们拼凑出事件的整体情况,并详细回答第一个问题,发生了什么?
嫌疑人的设备
可以使用类似的方法来调查可能是攻击源的设备。在这种情况下,问题将根据该设备的所有者被怀疑的行为来提出。例如,如果他们被怀疑是恶意软件开发者,我们的问题将与开发工具、源代码的痕迹、恶意软件销售等相关。
所以,我们已经讨论了内存取证如何帮助我们的调查以及我们可以应用的调查方法。然而,我们不能沉默不语,忽视其中的弱点和潜在的风险。让我们来讨论内存取证中的挑战。
发现内存取证中的挑战
我们希望你已经意识到内存分析的重要性。现在是时候去寻找其中的陷阱了。RAM 是一个非常有用且极其脆弱的东西。任何对系统的交互,哪怕是最小的,都可能导致不可逆的后果。因此,内存分析中最重要的挑战之一就是数据保存。
下一部分列出了与内存转储创建相关的几个重要事项。
工具
由于大多数操作系统没有内置的解决方案来创建完整的内存转储,因此你必须使用专门的工具。目前市面上有各种各样的工具可用于创建完整的内存转储以及提取单个进程。调查员在选择工具时可能会根据不同的考量做出选择:
-
对系统的更改
-
成本
-
远程转储创建的可能性
不幸的是,即使使用受信任的工具,也无法保证 100% 成功。而且,这可能会破坏系统,这引出了下一个问题。
关键系统
在某些情况下,运行工具创建内存转储可能会导致系统过载。这就是为什么决定创建内存转储的调查员必须准备好承担可能的风险。被调查的系统可能是一个关键对象,禁用该系统不仅可能导致重要数据丢失,还可能导致关键业务流程中断,极少数情况下甚至可能威胁到人们的生命和健康。对这类系统进行内存转储的决策应当是经过深思熟虑的,考虑到所有的利与弊。
不稳定性
如果被调查的系统感染了编写不当的恶意软件,它本身就会是不稳定的。在这种情况下,尝试创建内存转储可能会导致不可预测的后果。
此外,有时恶意软件会尝试使用反取证技术,并尽一切可能防止内存保存,这同样会导致不可预测的后果。这种情况发生得很少,但这个因素也应该被考虑在内。
总结
内存在经验丰富的调查员手中是一个重要的取证来源。内存分析提供了关于恶意软件活动及其功能、用户上下文,包括最近的操作、浏览活动、消息传递以及独特证据,如无文件恶意软件、内存中的应用数据、加密密钥等信息。
内存分析就像其他任何事情一样,都必须以某种方式进行。最重要的一点是设定调查目标,并将其拆解成简单的组成部分,以便更快速高效地进行调查,更重要的是,决定是否有必要进行调查,或者磁盘上留下的数据是否足够提供答案。
当然,没有万全之策,内存取证也有其缺点。主要的问题是数据保存,但如果你能够妥善处理这一点,你将会获得丰厚的回报。
既然你已经了解了内存取证的好处以及相关挑战,并且理解了调查的方法,那么接下来该做什么呢?我们认为是时候深入实际内容了,我们的第一站是内存获取过程,我们将在下一章中讨论这个话题。
第二章:获取过程
内存获取通常指的是将易失性内存的内容复制到非易失性存储设备中以供保存的过程。为了充分理解这一过程,调查员需要至少了解一些内存管理原则,理解内存提取工具的工作原理,并能够选择最合适的工具并正确使用。此外,重要的是要理解,创建完整的内存转储并不总是唯一的解决方案。还有实时内存分析,它也有其优点,在某些情况下,可能比内存获取更为合适。
在本章中,你将学习以下内容:
-
介绍内存管理概念
-
什么是实时内存分析?
-
理解部分与完整内存获取
-
探索流行的获取工具和技术
介绍内存管理概念
有几个与随机访问内存(RAM)的组织和管理相关的概念。理解这些概念将帮助你使内存调查过程更加有意识和有效。我们从地址空间开始。
地址空间
RAM 是一个内存单元的数组,每个单元都有自己的物理地址,用于访问该单元。然而,进程不能直接访问物理内存。这是因为进程与物理内存交互时,可能会轻易损害操作系统,甚至导致其完全崩溃。此外,进程使用物理地址使得同时执行程序的组织变得困难。为了解决这些问题,创建了一个叫做地址空间的抽象概念。
地址空间是一组可以用来访问内存的地址。每个进程都有自己隔离的地址空间,这解决了进程之间以及进程与操作系统之间的安全和隔离问题。但是,如果没有足够的物理内存来容纳所有正在运行的进程的代码和数据,该怎么办呢?
这里我们来到了下一个抽象概念。
虚拟内存
0x00000000 到 0x7FFFFFFFF,如下面的图示所示:

图 2.1 – x86 系统中内核空间和用户空间的默认分配
对半分割是标准做法,但不是强制要求。例如,在 Windows 中,有一个选项可以使用 3:1 的分割,其中 3 GB 属于用户空间。
在 x64 架构中,可以为进程分配更多的内存。在这种情况下,用户空间占用地址 0x0000000000000000 到 0x000007ffffffffffffff,而内核空间从地址 0xffffff08000000000000 开始。
分页
整个进程地址空间被划分为固定大小的块。这样的块被称为页,它们代表一系列连续的地址。正是这些页被映射到物理内存中。
内存管理器负责卸载页面并释放物理内存。内存管理器还通过硬件的帮助将虚拟地址转换为物理地址。
因此,进程使用其地址空间中的虚拟地址来访问内存,操作系统将此地址转换为物理地址,以从内存中检索所需的数据。
以下图表直观地展示了分页:

图 2.2 – 分页概念的示意图
这种方法使得我们可以仅将那些在特定时间内程序正常运行所需的页面加载到物理内存中。其余的页面存储在磁盘上,等待加载。
决定哪些进程内存页应该位于物理内存中,哪些应该保留在磁盘上的机制称为分页。存在许多页面替换算法(FIFO、LRU、Clock、WSClock 等)。它们的共同目标是:提高稳定性和性能。
为了存储未使用的内存页面,操作系统会使用一个单独的文件(pagefile、swapfile)或磁盘上的特殊分区(交换区)。因此,在创建内存转储时,我们只会获取加载到 RAM 中的页面内容。同时,包含对调查员有重要信息的页面可能位于磁盘上。为了获得完整的画面,建议将内存转储分析与非内存驻留数据的分析结合起来。
共享内存
如前所述,每个进程都有自己的隔离地址空间,但也有例外。开发者总是寻求提高性能、增加效率并减少资源消耗,而内存也不例外。结果就是共享内存。
共享内存是多个进程可以同时访问的内存区域。这个机制有几个用途。首先,能够访问同一内存空间的进程可以利用它来交换数据或执行相同的代码段。其次,这个机制提高了使用库的效率。例如,如果多个进程使用相同的动态库,那么将库的一个实例放入物理内存,并将所有需要它的进程的虚拟内存页映射到这个实例中会更简单。
栈和堆
每个进程包含静态数据和动态数据。静态数据被放置在与进程虚拟地址空间相关联的区域中。动态数据通常存储在称为栈和堆的内存区域中。为了更好地理解这些概念,这里有一张进程虚拟内存的示意图:

图 2.3 – 进程虚拟内存的示意图
堆栈存储与可执行代码直接相关的数据。如果程序执行过程中调用了某个函数,就会为该函数分配一个独立的堆栈帧。被调用函数的参数、变量和返回地址会被放入其中。堆栈帧数据只存在于给定函数执行的范围内;然而,这一部分的内容能够告诉调查员在特定时刻该进程执行了哪些函数。
与堆栈不同,堆中的数据会在进程的整个生命周期中存储,这对于数字取证专家来说至关重要。此外,它存储动态分配的数据,例如在文本编辑器中输入的文本、可能包含密码的剪贴板,或正在运行的消息软件中的聊天内容。
我们已经讲解了基本概念,接下来我们将在后续章节中提及。现在是时候进入下一个主题——实时分析了。
什么是实时内存分析?
有几种情况是无法创建内存转储的。我们已经在第一章中讨论了这些情况,为什么选择内存取证? 另外,对于远程系统或内存大于 32 GB 的系统,内存提取可能变得低效。在这种情况下,您可以使用实时内存分析手动检查正在运行的进程、它们的内存内容、网络连接以及当前的系统状态。
重要提示
请记住,您通常需要一个具有管理员权限的用户才能执行实时分析。如果攻击者能够访问目标系统并使用凭证挖掘工具,那么以特权用户身份登录就相当于直接泄露了您的凭证。
Windows
要在 Windows 主机上执行实时内存分析,有许多工具可供选择,从内置工具到高级取证框架都有。此外,现在许多 EDR/XDR 解决方案也允许事件响应人员执行实时内存分析。
让我们来看一个非常常见的实时分析工具,Process Hacker,如下图所示:

图 2.4 – Process Hacker 进程标签
Process Hacker 允许您获取以下信息:
-
正在运行的进程列表
-
启动的服务
-
活跃的网络连接
-
磁盘使用情况
此外,双击正在运行的进程可以进入该进程的内存。您可以在其中找到有关使用的资源的信息,查看进程的地址空间,包括堆栈和堆,甚至可以使用正则表达式在其中搜索特定数据。
当你已经知道需要寻找什么时,这种方法可能非常有用。例如,你知道某个恶意软件将有效负载注入到explorer.exe(Windows 资源管理器)中。通常,explorer.exe的实例不多;而且,它通常不应该进行网络连接。因此,使用如 Process Hacker 等工具和一些网络威胁情报,你可以轻松地发现恶意进程。
如前所述,也有一些内建工具,如Windows 命令行、PowerShell或Windows 管理工具(WMI)。这些工具提供了广泛的功能,帮助你获取活动进程列表、它们使用的资源、内存内容、活动网络连接等。
让我们看一下以下命令:
C:\WINDOWS\system32> wmic process list full
CommandLine=powershell.exe -nop -w hidden -enc SQBmACg<edited>
CSName=DESKTOP-1J4LKT5
Description=powershell.exe
ExecutablePath=C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe
该命令通过wmic(WMI 命令行工具)列出所有活动进程,包括它们的命令行和可执行文件路径。
Linux 和 macOS
对于运行 Linux 和 macOS 的系统,前面描述的方法同样有效。Apple Terminal和Linux Terminal都允许你查看网络连接信息、资源使用情况或正在运行的进程,如下截图所示:

图 2.5 – 基于 Linux 系统的活动进程列表
尽管实时分析方便且快速,但它也有其缺点。检查实时系统无法查看已终止进程和关闭的网络连接信息,限制了与内核对象的交互,并且可能导致重要痕迹被抹去,因为与目标系统的任何交互都会导致内存中的变化。
还值得注意的是,内存内容是不断变化的,在实时分析过程中很容易忽视某些信息,这也是为什么在可能的情况下进行转储永远不会多余。我们将在下一部分中讨论这一点。
理解部分与完整内存获取
我们已经确定,处理内存转储有其一定的优势。剩下的唯一问题是要转储什么。Windows 系统上有一些工具允许你创建特定进程的转储。其中一个工具是ProcDump,它是Sysinternals Suite的一部分。
以下截图展示了使用Telegram Messenger通过 ProcDump 创建完整进程转储的示例:

图 2.6 – Telegram 进程的内存转储
在图 2.6中,ProcDump 也有适用于类似 Linux 系统的工具,它提供了一种方便的方式来创建 Linux 应用程序的核心转储。同样,通过GDB(GNU 调试器)也可以在 macOS 上创建进程转储,但这是一项更复杂的任务,因为它需要直接指定内存地址来创建转储。
单个进程的转储可以稍后通过调试器进行分析。以下截图展示了在WinDbg中打开的 Telegram 进程的转储:

图 2.7 – 在 WinDbg 中打开的 Telegram 进程转储
这种分析技术适用于例如事件响应过程中,当需要从内存中快速提取某些数据(如 IP 地址或可执行代码)时。然而,如果需要进行全面调查,提取用户数据或加密密钥,或者构建基于 RAM 的时间线,则需要创建完整的内存转储。接下来,我们将讨论这一点。
探索流行的获取工具和技术
创建内存转储并非一项简单的任务,涉及多个因素。我们将在本章的这一部分单独讨论它们。
虚拟或物理
环境在转储创建过程中起着重要作用。这是因为虚拟机内存的转储不需要额外的工具。
事实上,虚拟机内存的内容部分或完全被放置在具有特定扩展名的文件中,因此获取转储实际上就是获取该精确的文件。以下截图展示了用于存储虚拟机内存的基本虚拟化工具和文件:

图 2.8 – 虚拟化工具和包含内存相关数据的文件
获取虚拟机内存的一个重要标准是其状态。需要理解的是,如果虚拟机正在运行,内存内容是不断变化的。因此,有两种可能的解决方案:
-
挂起:虚拟机的内存将在稳定状态下保存到磁盘。然而,一些解决方案在挂起虚拟机之前执行几个进程,这可能导致重要数据丢失。例如,VMware 在虚拟机进入挂起状态之前关闭所有活动的网络连接。
-
创建快照:创建快照时,虚拟机当前的状态和内存将被写入单独的文件中,不做任何更改。
因此,为了保存原始数据,创建快照以获取虚拟机内存更为可取。之后对虚拟机文件的进一步操作将取决于具体的供应商和内存保存的格式。
本地或远程
如果我们的目标系统是裸金属,我们无法避免使用额外的工具来创建内存转储。在这种情况下,物理访问主机起着关键作用。
在当今世界,远程从目标系统收集数据并不罕见。可以使用以下方案,在最简单的情况下远程创建内存转储:
-
创建一个带有管理员权限的临时用户,这将帮助您防止攻击者窃取特权用户的凭据。
-
创建一个网络共享(
$C或$ADMIN),并复制所需的工具以创建转储。 -
使用任何远程控制工具、服务创建或任务调度来运行您的工具,然后通过反向连接将转储发送到网络共享。
-
删除临时管理员账户。
重要提示
确保在将转储文件发送到网络之前和之后计算其校验和以检查其完整性。
如果可以物理访问主机,则我们需要解决的第一个问题是在哪里存储数据。强烈建议不要将内存转储保存在目标系统上,因为这可能导致在磁盘上覆盖法庭重要数据。在写入转储时,应预先准备可移动设备。不建议使用同一设备处理多个疑似感染主机,以及将设备直接连接到调查员计算机。这是因为存在恶意软件(主要用于对能源部门的攻击,例如USBferry、Crimson.USBWorm或USBCulprit),这些恶意软件使用可移动设备进行自我传播和数据传输。在这种情况下,最好将设备连接到中间主机,从中将所有必要的数据发送到调查员的主机,例如通过网络。
如果可以物理访问目标系统,则可以使用硬件和软件解决方案创建内存转储。
一种硬件解决方案是使用直接内存访问(DMA),例如FireWire。应该立即指出的是硬件解决方案有许多限制(例如,从 Windows 10 和 macOS 10.7.2 开始,对于锁定系统,DMA 被禁用),并且通常需要额外的驱动程序,这并不是一个优点。
使用软件解决方案完全是另一回事。市场上有大量免费和商业工具,可以创建不同格式的内存转储。总的来说,大多数工具的工作方式相似。在转储时,加载内核模块,将物理地址映射到进程的虚拟地址空间,从中写入数据到文件。重要的是要注意设备内存的存在。设备内存是保留给固件使用的物理内存的一部分。尝试访问内存的这一部分可能会导致不可预测的结果。这就是为什么大多数现代工具设计为跳过设备内存区域。
如何选择
对于这么多工具的显而易见的问题是如何选择最合适的工具。这个问题非常个体化。我们只想列举一些在选择工具时应考虑的因素:
-
支持的操作系统和硬件架构
-
远程转储能力
-
对目标系统的影响
-
可靠性
前两个因素是情境性的——根据必须进行转储的环境,可能适合某些工具。后两个因素则更为普遍。无论背景如何,我们始终尽量减少对目标系统的影响。至于可靠性,必须强调的是,不要使用你之前未在目标系统上使用过并测试过的工具,因为它们可能会出现不可预测的行为。因此,建议在创建目标系统的内存转储之前,先在相同条件下测试该工具。
是时候了
唯一需要弄清楚的是,何时进行转储最为合适。显然,转储创建的时刻在很大程度上决定了其内容。让我们回想一下在第一章中讨论的两个主要案例,为什么选择内存取证?
-
嫌疑人设备:在这种情况下,我们很可能希望在攻击者没有明显活跃时创建内存转储。这将帮助我们避免外部干扰转储过程。
-
嫌疑人设备:这里的情况恰恰相反,因为重要的是要找到设备所有者非法活动的证据。基于这一点,最好在目标主机上有任何活动时进行内存转储。
关于转储时间的一般建议是选择启动、关机、重启、系统更新以及其他活动较多的时段之外的时间。
总结
对内存结构和内存管理概念的基本理解是进行智能有效调查过程的关键。
在某些情况下,创建内存转储可能变得复杂或效率低下。在这种情况下,实时内存分析提供了帮助,它允许你获取目标系统当前状态的基本信息。
创建完整内存转储的另一种替代方法是提取单个进程的内存。这在事件响应中可能会有所帮助,但它无法提供完整的图景,极大地限制了调查员的能力。
创建内存转储是一个复杂的过程,取决于多个因素。为了成功创建转储,检查员应考虑各种细微差别,包括数字环境、远程数据提取的需求、使用工具的可靠性以及转储创建的时间。
在接下来的章节中,我们将更详细地介绍在不同操作系统上创建内存转储所需的工具,并进行实际操作。
第二部分:Windows 取证分析
本部分将带你了解 Windows 内存获取过程和内存转储分析,包括恢复用户操作和在内存中追踪恶意活动。
本书的这一部分包含以下章节:
-
第三章,Windows 内存获取
-
第四章,通过 Windows 内存取证重建用户活动
-
第五章,使用 Windows 内存取证进行恶意软件检测与分析
-
第六章,易失性内存的替代来源
第三章:Windows 内存获取
你已经掌握了一些理论知识,但正如你所知道的,理论和实践本质上是没有区别的,但实际上是有差别的。所以,让我们继续深入实际任务,从Windows 内存获取开始,因为 Windows 是最广泛使用的操作系统。
这意味着什么?它是威胁行为者最常见的目标!这也意味着在你处理事件响应时,你会经常遇到它(当然,也包括一些刑事案件)。因此,了解如何从 Windows 主机获取内存是一个非常好的起点。
本章将向你介绍用于 Windows 内存获取的四种最常见工具,当然,你还将学习如何使用它们并获取内存镜像,以供后续分析。
我们将讨论以下主题:
-
了解 Windows 内存获取问题
-
准备进行 Windows 内存获取
-
使用 FTK Imager 获取内存
-
使用 WinPmem 获取内存
-
使用 Belkasoft Live RAM Capturer 获取内存
-
使用 Magnet RAM Capture 获取内存
了解 Windows 内存获取问题
在上一章中,我们详细介绍了内存转储的基本概念,并讨论了可能出现的问题。然而,每个操作系统都有其特殊性。与 Windows 内存提取相关的主要特点是访问随机访问内存(RAM),但首先还是从基础开始。
还记得我们之前谈到过的设备内存吗?那是为设备保留的物理内存区域。这些设备包括显卡、声卡、外部组件互联(PCI)卡等等。它们直接访问物理内存对其高效且质量良好的运行至关重要。你还记得尝试访问设备内存可能会导致什么吗?没错——它可能会导致不可预测的后果。
问题在于,尝试访问或写入设备内存会被转换为发送到相应设备的请求。然而,不同的设备可能会对试图与它们保留的物理内存交互的尝试做出不同的反应。在某些情况下,这可能会导致依赖于设备功能的关键信息发生变化。然而,从法医角度来看,这种后果可能是重要证据的丧失,或者在最坏的情况下,系统的冻结或关闭。
在 Windows 操作系统中,访问物理内存是通过 \Device\PhysicalMemory 内核对象实现的。以前,这个文件很容易操作,因为它对用户空间程序完全可访问。然而,如果我们考虑之前的信息,很明显这种方法并不是完全安全的。
这一切都随着Windows Server 2003 Service Pack 2 (SP2)的发布发生了变化。当然,用户空间程序仍然可以读取这个文件,但写入访问现在只能从内核空间进行。因此,获取工具必须在内核级别工作,或者使用特殊的驱动程序来创建内存转储。
另一个影响内存提取工具变化的因素是虚拟化的广泛使用。这导致当在启用虚拟安全模式(VSM)的系统上运行这些工具时,系统会崩溃。尽管如此,最常用工具的最新版本已经成功解决了这个问题。
尽管这些变化发生了,但用于 Windows 内存获取的工具数量仍然很大。
让我们在接下来的章节中看一下最常用的一些工具。
准备 Windows 内存获取
在我们开始使用映像工具之前,我们需要准备一些东西。首先,你需要找到一个闪存驱动器,用来存储工具本身和创建的内存转储,所以确保它有足够的空间。其次,你需要对它进行清理。这意味着你需要法证擦除驱动器。
重要说明
在标准删除过程中,与已删除文件相关的元数据会被更改,并且这些文件所在的空间会被标记为可供重用。换句话说,删除后,文件的内容仍会保留在驱动器上,并且可以恢复。格式化过程也非常相似。一些特定的主文件会被重写,但信息仍然可以从驱动器中提取。因此,要安全地删除文件,你需要用零或随机数据覆盖内容。
要擦除驱动器,可以根据可移动介质的类型使用不同的工具和方法。我们已经决定使用闪存驱动器;在这种情况下,有两种非常有效且快速的选项,概述如下:
-
写入一个与闪存驱动器整个容量成比例的预先准备好的文件。
-
使用Secure Erase(安全擦除)选项。
不幸的是,并不是所有厂商都有自己的工具,允许你使用安全擦除选项来安全地擦除他们的驱动器。你可以在闪存驱动器厂商的官方网站上查看这些信息。
当你的闪存驱动器被清理干净后,你可以在其中添加一些映像工具。
使用 FTK Imager 获取内存
AccessData FTK Imager是最受欢迎的免费工具之一。它通常被法证分析师和事件响应人员用来查看磁盘映像预览,甚至进行实时响应,因此它不仅可以用于按位映像,还可以用于创建自定义内容映像,当然也可以用于创建内存映像。让我们更详细地了解一下!请按照以下步骤操作:
-
要获取FTK Imager,请访问AccessData的官方网站:
accessdata.com/products-services/forensic-toolkit-ftk/ftkimager。 -
选择产品与服务 | FTK® Imager。点击立即下载 FTK Imager!链接并按下立即下载。你将被要求填写一份包含你联系信息的简短表格。之后,一个链接将发送到你提供的电子邮件地址。
现在,你需要在闪存驱动器上安装 FTK Imager。你可以使用InstallShield 向导工具,它提供了逐步安装说明。
要创建内存转储,FTK Imager 会将设备驱动程序加载到内核中,并随后通过映射 \Device\PhysicalMemory 内核对象来读取内存。从用户的角度来看,使用 FTK Imager 进行内存获取非常简单直观。按照以下步骤创建你的内存映像:
- 将闪存驱动器连接到目标系统,并运行 FTK Imager。主窗口将出现,如下所示:

图 3.1 – FTK Imager 主窗口
- 进入文件,点击捕获内存…,或者在工具栏上找到相关图标。下图展示了前一种选项:

图 3.2 – FTK Imager 文件菜单
- 在对话框中,点击
memdump.mem。我们还建议你勾选包括页面文件复选框,如下所示:

图 3.3 – 内存捕获对话框窗口
- 按下捕获内存按钮。结果,你将看到如下所示的对话框,展示了转储创建的进度:

图 3.4 – 映像进度
等待几分钟后,我们获得了内存转储,这是一个 .mem 扩展名的文件。该映像已准备好使用你选择的工具进行分析——例如,Volatility 框架。
FTK Imager 是一款功能强大的工具,具有广泛的功能,但我们希望你有选择权,所以让我们看看其他一些工具。
使用 WinPmem 获取内存
WinPmem最初由谷歌开发,并作为Rekall 框架的一部分发布,但现在已作为独立的内存获取工具发布。该工具支持从XP到10的各种 Windows 版本,并且为 32 位和 64 位系统提供独立的可执行文件。
WinPmem 使用三种独立的方法来创建内存转储,具体如下:
-
页面表项 (PTE) 重映射
-
使用
MMMapIoSpace内核 应用程序编程接口 (API) -
传统的
\Device\PhysicalMemory映射
上述方法中的第一种方法默认使用,因为它被认为是最稳定的。然而,用户可以手动选择其他任何方法。
要下载此工具,请访问 Velocidex GitHub 页面上的 WinPmem 仓库,github.com/Velocidex/WinPmem。
页面如下所示:

图 3.5 – WinPmem GitHub 仓库
在页面的右侧,找到winpmem_mini_x64.exe。将该可执行文件复制到你的闪存驱动器。此程序无需任何额外的依赖项,且是独立运行的。同时,你不必担心 x64 和 x86 的区别,WinPmem 会自动加载正确的驱动程序。
以下说明将帮助你使用 WinPmem 获取内存:
- 将闪存驱动器连接到目标系统。以
管理员身份运行cmd或PowerShell,如下图所示:

图 3.6 – 从搜索框运行 PowerShell
- 移动到你的闪存驱动器,并以内存转储文件名作为参数运行
winpmem_mini_x64.exe。如下面的截图所示,memdump.raw是提供的参数:

图 3.7 – WinPmem 执行
- 在内存转储过程中,你将能够看到所有相关信息,如下图所示:

图 3.8 – 使用 WinPmem 创建转储
一会儿后,我们将得到一个指定名称的原始内存转储。
这是我们如何使用 PowerShell 和 WinPmem 提取 Windows 内存的方法,但这还不止这些。让我们再添加几个工具到我们的工具集。
使用 Belkasoft RAM Capturer 获取内存
Belkasoft RAM Capturer是另一个免费的内存获取工具。与前述工具类似,它使用内核驱动程序提取物理内存并创建转储。该工具兼容所有 32 位和 64 位版本的 Windows,包括 Windows XP、Windows Vista、Windows 7 和 8、Server 2003 和 2008 以及 Windows 10。
你需要采取以下步骤:
-
要获取此工具,请访问官方Belkasoft网页的下载标签:https://belkasoft.com/。
-
选择
x64和x86文件夹,这些文件夹应当被提取到闪存驱动器中。 -
这次,你需要找出你正在处理的是 x64 还是 x86 系统。为此,使用
system并运行系统信息应用程序,如下图所示:

图 3.9 – 从搜索框运行系统信息
在打开的窗口中,搜索系统类型,位于系统摘要下,如下图所示。x64 基础 PC值表示 64 位系统:

图 3.10 – 系统类型检测
如果是x64文件夹,请选择它;否则,选择x86文件夹中的其他一个。你准备好创建内存转储了。请按照以下步骤操作:
-
将闪存驱动器连接到目标系统并运行
RamCapture可执行文件。 -
在指定字段中输入输出文件夹路径,并按下Capture!按钮。
转储创建过程将如下所示:

图 3.11 – 使用 Belkasoft RAM Capturer 进行成像
最终,我们得到一个 .mem 扩展名的内存转储。默认情况下,文件名由采集日期组成,但你可以将其替换为更具描述性的名称。
现在,你可以使用三种不同的工具创建内存转储。让我们来看看最后一个工具,虽然它并不是最不重要的。
使用 Magnet RAM Capture 获取内存
Magnet Forensics 也发布了自己的免费内存获取工具,名为 Magnet RAM Capture,它可以用来从 Windows 系统中获取内存。为了提取物理内存,Magnet RAM Capture 使用内核模式驱动程序。它创建的是原始格式的内存转储,这种格式既可以被开源内存取证工具支持,也可以被功能完整的数字取证套件支持。
下载 Magnet RAM Capture 时,按照以下步骤操作:
-
访问官方 Magnet Forensics 网页的 RESOURCES 标签页,然后点击 FREE TOOLS 标签页:
www.magnetforensics.com/。 -
选择
MRCv120.exe文件到你的闪存驱动器。
使用 Magnet RAM Capture 进行内存转储非常简单,按照以下步骤操作即可:
-
将闪存驱动器连接到目标系统,并以管理员身份运行
MRCv120.exe。 -
在下拉菜单中选择一个 Segment size 选项(默认值为 Don't Split,这是推荐的模式)。
-
点击 Browse… 按钮,选择内存镜像的文件名和保存位置。
-
点击 Start 按钮。
成像过程将开始;你应该等待进度条达到 100%。这是使用 Magnet RAM Capture 进行成像过程的一个例子:

图 3.12 – 使用 Magnet RAM Capture 进行成像过程
处理完成后,你将在之前指定的位置找到一个原始内存镜像文件。
总结
在创建内存镜像时,你不仅需要考虑一般概念,还需要考虑每个操作系统独有的因素。对于 Windows 操作系统来说,一个重要因素就是访问 /Devices/PhysicalMemory 内核对象。
大多数现代工具使用内核驱动程序来创建转储,但一些工具有自己独特的方法,表现为使用与经典的 /Devices/PhysicalMemory 映射不同的替代方案。
尽管有多种 Windows 内存提取工具,但值得记住的是,最好的工具是那些已经在与目标系统相同或至少非常相似的系统上经过成功测试的工具。
在本章中,我们已经学习了如何使用各种免费工具创建内存转储。现在,到了深入查看这些转储内容的时候了!在下一章,我们将了解 Windows 内存转储分析工具,并学习如何搜索用户活动的痕迹。
第四章:通过 Windows 内存取证重建用户活动
用户活动重建对于许多使用场景至关重要,因为它帮助我们更好地理解发生了什么。在第一章中,我们讨论了如果收到参与事件的设备,受害者或嫌疑人可能是设备的拥有者。如果我们分析受害者的设备,用户活动可以告诉我们感染是如何发生的,或者攻击者在远程访问计算机时是如何行动的。如果我们谈论的是攻击者的设备,这种分析可以帮助我们了解攻击准备是如何进行的,威胁行为者执行了哪些操作,并且如何找到非法活动的证据。另外,如果您处理的案件与黑客攻击无关,而是涉及传统犯罪,如儿童色情、人口贩卖和毒品交易,内存镜像可能包含关键证据来源。在这里,您可能能够恢复私人通信和浏览器历史记录,以及嫌疑人用来隐藏数据的容器的加密密钥。
本章将提供一些有关用户行为恢复技术的见解,这些技术不仅基于正在运行的进程,还基于分析内存中的 Windows 注册表和文件系统。
本章将涵盖以下主题:
-
分析已启动的应用程序
-
搜索已打开的文档
-
调查浏览器历史记录
-
检查通信应用程序
-
恢复用户密码
-
检测加密容器
-
从注册表中提取最近的活动
技术要求
使用下一章介绍的工具并进行 Windows 内存取证时,您不需要满足特定的技术要求。只需要在主机或虚拟机上安装 Windows 操作系统即可。
分析已启动的应用程序
应用程序分析可以帮助调查员建立嫌疑人的档案。分析运行中的进程可以帮助我们了解嫌疑人是否在使用一些具有高度匿名性的消息应用程序或网络浏览器,或者是否有加密容器正在挂载。这些数据源可能充满了有价值的取证文物,且在事后分析中可能无法访问。
每次用户启动程序时,相应的进程会在内存中创建并添加到活动进程列表中。通过分析这个列表,我们可以获得关于在转储时运行的程序的信息。这就是我们一旦掌握分析工具后将要做的事情。
介绍 Volatility
Volatility 框架是最流行的免费内存转储分析工具。许多厂商已经在他们的解决方案中加入了对该工具的支持,包括Autopsy和Magnet AXIOM。该工具的源代码是用 Python 编写的,因此 Volatility 可以在不同的操作系统上使用。此外,Volatility 还允许你分析各种操作系统,从Windows XP到Linux和macOS。当然,我们也决定以 Volatility 为基础,但我们不会仅限于此。
要运行 Volatility,你可以使用以下其中一种选项:
-
Volatility 独立版:此版本是一个独立的可执行文件。最后发布的该格式版本是Volatility 2.6。你可以从官方网站下载:
www.volatilityfoundation.org/26。只需下载适合你操作系统的版本并将可执行文件复制到一个方便的位置。 -
Python 脚本:使用脚本有其优势,因为它们更新频繁,支持更多的配置文件。要获取这些脚本,你只需访问 Volatility 的 GitHub 仓库并克隆该项目:
github.com/volatilityfoundation/volatility。 -
Volatility Workbench:此选项适用于那些喜欢使用具有图形界面的工具的用户。Workbench 的开发者定期更新该工具,因此它也支持 Volatility 的最新版本,包括 Volatility 3。然而,它也有一些缺点,比如对 Volatility 中所有可用参数的支持不完整。你可以从官方网站免费下载 Workbench:
www.osforensics.com/tools/volatility-workbench.html。
Volatility 项目得到了积极支持,因此你总能在适当的公共资源中找到详细的安装说明、官方插件描述、社区插件以及更多信息。这些资源包括官方网页、Volatility 的 GitHub 仓库以及各种论坛。
截至写作时,Volatility 的最新版本是 Volatility 3。然而,该版本仍在开发中,我们所需的一些插件尚未开发完成,甚至完全缺失。此外,Volatility 3 的输出处理不像 2.6 版本那么简便,因此我们优先选择了之前的版本。
截至写作时,Volatility 的最新版本是 Volatility 3。然而,该版本仍在开发中,我们所需的一些插件尚未开发完成,甚至完全缺失。此外,Volatility 3 的输出处理不像 2.6 版本那么简便,因此我们优先选择了之前的版本。
我们将选择简单的方式,使用独立版本。如果你在 Windows 系统上运行,下载 Volatility 后,你将获得 volatility_2.6_win64_standalone.exe 可执行文件。Volatility 是一个命令行工具,因此你需要使用 Windows PowerShell 或 Windows 命令提示符 来运行它。为了检查一切是否正常工作,你可以打开 PowerShell,进入包含工具的文件夹(在我们的案例中是 D:\ 驱动器),并使用 --info 选项运行 Volatility。该选项会打开帮助菜单,如下图所示:

图 4.1 – Volatility 信息
请注意 Profiles 部分,因为它列出了你的 Volatility 版本支持的所有操作系统版本。如果没有正确指定配置文件,工具将无法按预期工作。
配置文件识别
imageinfo 插件中的每个配置文件都会尝试为你找到最合适的配置文件。运行此插件时,你还需要使用 -f 选项,并指定你要分析的内存转储路径。我们使用的内存转储文件名为 Win10Mem.vmem,位于 D:\user activity 文件夹中。整个命令应如下所示:

图 4.2 – Volatility imageinfo
如果你成功运行该命令,Suggested profiles 行会显示 Volatility 认为适合分析的配置文件列表。在大多数情况下,列表中的第一个配置文件是最合适的,但如果你发现某些插件在该配置文件下无法正常工作(可能是没有输出、不正确的输出或错误消息),可以尝试更换配置文件。
另一个重要的点是,如果转储的操作系统非常新,可能没有适合的配置文件。在这种情况下,你可以在 GitHub 上搜索并将新的配置文件添加到 Volatility,查看 Volatility 的下一个版本——此时是 Volatility 3——或者使用其他工具。当然,如果你无法找到合适的配置文件,你也可以自己编写,但这将需要更深入的编程和操作系统知识。
在我们的案例中,我们将使用 Win10x64_14393 配置文件来分析 Win10Mem.vmem 转储文件。
到此,我们已经拥有工具和合适的配置文件。现在,我们可以分析活动进程列表了。
搜索活动进程
Volatility 提供了多个插件,用于列出内存转储创建时系统上运行的进程。第一个插件 pslist 允许你按时间获取进程列表。如果你更关心父进程与子进程之间的关系而非创建时间,使用 pstree 插件会更好。两个插件都使用内存中活动进程的列表,并显示可以在实时系统中通过 任务管理器 获取的数据。
启动任何插件的通用命令如下:
volatility_2.6_win64_standalone.exe -f <memory dump location> --profile <suitable profile from profile list> <plugin to run>
让我们尝试按时间排序获取活动进程的列表:

图 4.3 – Volatility pslist
看一下前面的截图。在插件的输出中,我们不仅可以找到正在运行的进程的名称,还能找到其唯一标识符、父进程的标识符、关联的句柄和线程数、进程创建的时间以及如果进程已经终止,则可以看到它退出的时间。
重要提示
内核对象种类繁多。当一个进程需要打开某个特定对象时,会为其打开一个称为句柄的引用。由于每个活动进程必须至少有一个线程(表示最小程序指令序列的对象),因此这种类型的对象总是有一个句柄。此外,句柄通常还会为文件、注册表项,甚至是其他进程等对象创建。
然而,如果进程最近已经终止,并且它的信息已经从活动进程列表中删除了,那该怎么办呢?
正在查找已结束的进程
从操作系统的角度来看,所有进程都是某种_EPROCESS结构的对象。当一个进程完成工作后,它的数据仍会在内存中保存一段时间,直到被该进程占用的空间被覆盖。Volatility 允许你通过类似_EPROCESS结构的对象搜索来查找这些进程。
要查找这些进程,可以使用psscan插件。其执行过程如下所示:

图 4.4 – Volatility psscan
如你所见,显示的信息与pslist的结果非常相似,但现在我们可以获得更多关于已终止进程的信息。
现在,我们可以搜索在创建转储时由用户运行的程序或最近终止的程序。然而,如果我们需要进一步查找,并搜索那些较早终止的程序呢?
在这种情况下,Volatility 提供了一个userassist插件,它可以获取用户经常运行的程序的信息。它还包括用户最近操作过的程序。
我们可以获取这样的数据,如通过Windows 资源管理器启动的应用程序的名称、运行次数以及最后一次运行的时间:

图 4.5 – Volatility userassist
首先,在执行后,你将能够看到关于信息所在具体位置的详细信息。例如,\??\C:\Users\Ben\ntuser.dat意味着显示的子键和值与用户Ben相关。
以下截图展示了与每个应用程序相关的独立条目:

图 4.6 – Userassist 条目
如你所见,userassist显示了可执行文件的完整路径、运行次数、聚焦时间,以及与应用程序最后一次运行时间相关的键更新的日期和时间。在这里,你不仅可以找到内存转储创建时正在运行的程序,还可以找到之前启动的程序。
现在,假设在正在运行或最近完成的进程列表中,我们有WINWORD.exe(当你启动 MS Word 时,会创建这样的进程):

图 4.7 – 活跃的 MS Word 进程
哪个文档在这里被打开了?我们能从内存中获取这些信息吗?
查找已打开的文档
在某些情况下,你可能想了解是否有任何微软 Office 文件或只是文本文件被相应的应用程序打开。为什么?它们可能包含密码或一些从调查角度来看有价值的数据。Volatility 有多个插件可以让你在内存中处理文件。例如,filescan插件可以让你获取内存转储中遇到的所有文件的信息,而dumpfiles插件则可以尝试提取这些文件(记住,有些文件在转储创建时可能已被卸载)。那么,我们如何找到在 MS Word 中打开的文件呢?
进程内存中的文档
如果我们注意到-p选项,只对该进程运行 Volatility 插件。如果我们想查看我们的进程使用了哪些资源,handles插件可以帮助我们。让我们使用-p选项和-t File选项,它将帮助我们仅显示与文件相关的资源。

图 4.8 – Volatility 句柄
在前面的截图中,我们可以看到我们的进程资源提到了一个名为GOT-7_HR的文件。让我们来找出这个文件在内存中的位置。为此,我们需要运行filescan插件,并将其输出重定向到一个文本文件,如下所示:
PS D:\> .\volatility_2.6_win64_standalone.exe -f '.\user activity\Windows7x64.vmem' --profile Win7SP1x64 filescan > D:\filescan.txt
当插件运行完成时,我们可以在指定路径下找到一个名为filescan.txt的文本文件,其中包含以下内容:

图 4.9 – Volatility filescan 输出
在这里,我们可以看到文件被找到的物理偏移量,一些相关的属性,以及文件在磁盘上的完整路径。让我们来找找我们的文件:

图 4.10 – 文件偏移
我们现在知道了文件的物理偏移量,并且可以使用dumpfiles插件从内存中提取它。这里,我们将使用-Q选项来指定物理偏移量,并使用-D选项来指定我们希望保存文件的路径。

图 4.11 – Volatility dumpfiles
如你所见,我们的文件在这个偏移位置被检测到。现在,D:\user activity 文件夹中出现了两个新文件,分别是 file.None.0xfffffa80282a6b80.vacb 和 file.None.0xfffffa80258625f0.dat。
文件数据扩展名标识数据提取自的对象:
-
dat:DataSectionObject -
vacb:ImageSectionObject -
img:SharedCacheMap
这些文件是容器,其中存储着文件的内容和数据。要获取原始文件,尝试使用其扩展名重命名容器。通过这种方式,你可以使用合适的工具打开提取的文件并继续分析。
重要提示
如果你导出了一个你认为是恶意的文件,请确保不要在你的工作机器上运行它进行分析。最好在沙箱中处理此类文件,或使用专门的工具处理它们,我们将在下一章讨论这些工具。
文件已经处理完了,那么与浏览器相关的进程呢?
调查浏览器历史记录
浏览器中可能包含很多有用的数据。通过分析浏览器历史记录,我们可以了解用户访问了哪些网站、执行了哪些搜索查询以及下载了哪些文件。即使用户使用了隐私模式或特殊浏览器(例如 Tor Browser)上网,我们仍然可以在内存中找到有用的信息。
下图显示了 pslist 插件的输出,我们可以看到几个与Google Chrome、Mozilla Firefox 和 Tor Browser 相关的进程:

图 4.12 – 浏览器相关进程
那么,如何获取访问过的资源信息呢?有几种方法可以做到这一点:
-
导出进程内存并使用
Strings工具进行处理(docs.microsoft.com/en-us/sysinternals/downloads/strings),该工具允许你从各种文件中获取 ASCII 和 Unicode 字符列表。 -
导出进程内存并使用
bulk_extractor工具进行处理(downloads.digitalcorpora.org/downloads/bulk_extractor/),该工具允许你扫描磁盘映像、内存转储、特定文件或目录并提取有用信息。 -
使用正则表达式或 YARA 规则搜索 URL。
我们有三个浏览器和三个选项,因此这个计划看起来不错。让我们从 Google Chrome 和正则表达式搜索开始。
使用 yarascan 分析 Chrome
Yarascan 是 Volatility 插件之一,允许你使用正则表达式或 YARA 规则搜索特定的信息。
重要提示
YARA 最初是为帮助恶意软件研究人员检测和分类恶意软件样本而开发的。然而,这个工具也适用于内存取证,因为它允许我们使用文本或二进制数据创建搜索模式。有关更多信息,请参阅 yara.readthedocs.io/en/v4.1.0/gettingstarted.html。
要使用 yarascan 和 YARA 规则文件,我们需要提供 .yar 文件的路径,并使用 -Y 选项。在我们的案例中,我们将使用 -y 选项,并使用 /(https?:\/\/)?([\w\.-]+)([\/\w \.-]*)/ 正则表达式。此外,我们只扫描一个 Chrome 进程——ID 4236 的进程,如下所示:

图 4.13 – Volatility yarascan
在这里,你可以看到我们通过这个正则表达式直接找到了几个链接——这些链接存在于 ID 4236 的 Google Chrome 进程的内存中。
现在我们已经看过 Chrome,让我们继续分析 Firefox。
使用 bulk extractor 进行 Firefox 分析
Bulk extractor 是一个命令行工具,允许你在不同来源中搜索特定的信息,例如 URL、电子邮件和 PDF 文件。还有 BEViewer,这是一个用于 bulk extractor 的图形界面,但需要额外安装。
在使用此工具之前,我们需要转储 Firefox 进程的内存。memdump 插件非常适合此任务,因为我们只需添加 -p 选项,并指定所需进程的 ID,还需要添加 -D 选项,并指定保存转储的文件夹。在我们的案例中,ID 为 6380,路径为 .\user activity\firefox。
当插件完成时,一个以进程 ID 为文件名并带有 .dmp 扩展名的文件将在指定的目录中出现。
现在,我们可以启动我们的 bulk extractor。

图 4.14 – Volatility memdump 和 bulk extractor
对于 bulk extractor,我们使用了几个选项:
-
-o:提供输出目录 -
-x all:禁用所有扫描器 -
-e email:启用电子邮件扫描器,搜索电子邮件和 URL
最终,我们需要提供我们要分析的文件路径。
重要说明
要查看所有可用的 bulk extractor 扫描器,只需运行 bulk_extractor.exe,而不添加任何选项。
结果,多个文件将出现在指定的目录中:

图 4.15 – Bulk extractor 的输出
在这些文件中,我们可以找到有关在 Firefox 内存中出现的电子邮件和 URL 的信息。例如,我们可以查看 url_histogram.txt 文件:

图 4.16 – URL 直方图文件内容
或者,我们可以检查通过 Firefox 浏览器进行的搜索,查看 url_searches.txt 文件:

图 4.17 – URL 搜索
从中我们可以看到,用户正在搜索 Tor 浏览器。
既然我们已经看过了 Chrome 和 Firefox,现在是时候进入最有趣的部分了。让我们尝试使用Strings工具分析 Tor 进程。
使用 Strings 工具分析 Tor
Tor 是一款私人浏览器,它不仅可以访问标准资源,还能访问深网和暗网中的网站,这些网站上有一些私人或有时是非法的资源。因此,我们不能忽视这个过程。
在分析时,我们将使用 Strings 工具,它是 Sysinternals Suite 的一部分,可以用来搜索文件中的不同字符。在分析像 Tor 这样的私人浏览器时,这个工具非常有用。
在开始之前,我们需要转储 Tor 内存。我们可以使用之前的技术来进行。我们的 tor.exe 文件的 ID 是 4708,因此我们将使用 -p 选项和 memdump 插件。不要忘记添加 -D 选项,并提供存储转储文件的路径。
创建转储文件后,我们可以运行 Strings 工具。为此,我们必须将进程转储的路径作为参数传递,并将输出重定向到文本文件中,正如我们之前所做的那样。结果将得到以下输出:

图 4.18 – Volatility memdump 和 Strings 工具
这个选项需要更长的时间,最终的文件也更难以处理,但可以找到比标准 URL 更多的数据。
最终我们得到的文本文件大致如下:

图 4.19 – Tor 内存中的 URL
我们也可以使用正则表达式或常规关键词搜索,快速找到感兴趣的信息。
这样,我们已经了解了浏览器的历史,甚至简要涉及了电子邮件分析的话题。现在,让我们更进一步,仔细看看电子邮件和即时通讯工具。
分析通讯应用程序
你多久使用一次通讯应用程序进行聊天、发送视频或查看你收到的可爱猫咪照片?答案可能是每天。电子邮件和即时通讯工具已经成为我们生活的必需品,因此我们无法避免它们。在分析受害者电脑的内存转储时,我们可能会发现通过电子邮件发送的恶意文档,而在嫌疑人电脑的内存转储中,可能会找到与同谋的通信记录。
我们已经讨论过电子邮件了,因此从这里开始。
电子邮件,电子邮件,电子邮件
如今,有许多不同的电子邮件客户端,一些人更喜欢使用浏览器来查看邮件。因此,我们可以将分析简化为以下几点:
-
如果在运行的进程列表中看到与电子邮件客户端相关的进程,我们可以使用
handles插件检查该进程所使用的资源,并寻找可能是附件的文件。 -
此外,如果有一个活跃的电子邮件客户端进程,我们可以使用
memdump插件提取其内存,并使用Strings工具处理转储文件。这将使我们不仅能搜索附件中的文件名,还能查找电子邮件内容的片段。 -
按照前一节中的方法运行 bulk extractor,但这次用它来分析整个内存转储。在这种情况下,我们将能够收集所有电子邮件和附件的信息,无论是使用电子邮件客户端还是浏览器。不过,要小心,因为 bulk extractor 运行的时间会比之前更长。
由于这些方法已经有详细的描述,我们将只关注其中一种:使用 bulk extractor 进行分析。
由于我们现在将使用整个转储进行搜索,我们无需单独提取每个进程的内存。相应的命令如下所示:

图 4.20 – 使用 bulk extractor 的完整内存转储分析
现在,我们可以检查email_histogram.txt文件,其中包含了所有在内存中出现的电子邮件地址的信息:

图 4.21 – 电子邮件直方图
我们还可以在url_histogram.txt文件中进行关键词搜索,以查找关于邮箱和附件的信息:

图 4.22 – URL 直方图中的电子邮件附件
关于电子邮件一切似乎都很清楚,但即时通讯软件呢?我们如何查看对话并从中找到有用的内容?
即时通讯软件
说到即时通讯软件,最简单的方法是使用即时通讯内存分析工具。我们再看看进程列表:

图 4.23 – 活跃进程列表
在活跃进程列表中,我们可以看到一些知名的即时通讯软件,包括Telegram和Discord。我们可以转储这些进程的内存,并使用Strings工具进行解析,如下图所示:

图 4.24 – Telegram 内存提取与解析
在输出文件中,你可以搜索特定的用户名、消息、网址或关键词:

图 4.25 – Telegram 内存中的消息历史
这就是我们如何获得即时通讯软件内存中的一些信息。顺便提一下,有些人可能会用即时通讯软件和自己聊天,在多个设备间共享密码,所以你也可以检查密码的出现情况。
恢复用户密码
即时消息并不是我们唯一可以搜索密码的位置。我们还可以在缓存中、文本编辑器的内存中、缓冲区、命令行中,甚至一些特定的系统进程中找到它们。Volatility 有多个插件可以收集有关凭证的信息:
-
hashdump -
lsadump -
cachedump
让我们一一查看它们。
Hashdump
hashdump插件可以用于转储 Windows 8 之前的 Windows 系统上本地用户密码的哈希。命令如下所示:

图 4.26 – Volatility hashdump
在输出中,你可以看到账户名,接着是相对标识符、LM 和 NT 哈希。请注意,我们在管理员和来宾用户上有相同的哈希值。这些特定的哈希值表示空密码。
另一种转储凭证的方法是使用cachedump插件。
Cachedump
这个插件可以用于转储缓存的域用户密码哈希。默认情况下,我们的系统会存储最多 10 个最新的域帐户凭证。我们可以尝试使用cachedump访问它们。其执行方式与hashdump非常相似:

图 4.27 – Volatility cachedump
在这里,你可以看到域用户名,接着是密码哈希和域名本身。
另一件我们可以做的事情是搜索本地安全权限(LSA)信息。
Lsadump
LSA 子系统服务负责用户身份验证,因此其分析可以帮助我们获取一些有用的信息。请看以下示例:

图 4.28 – Volatility lsadump
在这里,我们可以看到来自不同资源的信息,并且在其中一些资源中,我们能够识别出明文密码。明文密码的其他位置可以在文本编辑器进程的内存中,或一些特定工具的命令行中找到,例如PsExec。
明文密码
由于我们已经学习了如何提取和分析进程内存,现在让我们集中精力分析命令行。Volatility 有多个插件可以让我们检索命令行参数。其中一个插件是cmdline,它不需要任何额外的参数:

图 4.29 – Volatility cmdline
从一开始,我们就可以看到关于系统进程启动的信息以及为此目的使用的命令行。在需要传输明文密码的程序运行情况下,我们将能够找到类似于以下内容的信息:

图 4.30 – PsExec 命令行中的明文密码
在这种情况下,我们可以看到 PsExec 已被用来远程连接到win7主机,并且最大用户密码已以明文传输。
现在,您有几种方法可以获取用户的密码信息。但是,那些使用加密和加密容器的用户怎么办呢?
检测加密容器
Windows 上有几种流行的加密工具:
-
Bitlocker
-
TrueCrypt
-
VeraCrypt
虽然这些工具的实现有所不同,但它们的目的是相同的——加密用户数据。对于某些人来说,这可能是保持数据私密的机会,而对其他人来说,这可能是隐藏非法活动的机会。对于我们这些调查人员来说,重要的是要理解,如果加密磁盘在转储时正在使用,我们可能会找到缓存的卷密码、主加密密钥、一些未加密文件的部分内容或它们在内存中的确切位置。
我们调查的第一步是确定是否存在任何加密工具以及哪些数据被加密。有时,我们可以轻松从正在运行的进程列表中识别该工具,正如以下截图所示:

图 4.31 – VeraCrypt 进程
不幸的是,Volatility 提供的功能不足以与不同的加密解决方案配合使用,但它为 TrueCrypt 提供了一套很好的插件:
-
truecryptmaster搜索加密主密钥。 -
truecryptpassphrase搜索所使用的密码短语。 -
truecryptsummary收集与 TrueCrypt 相关的信息。
最后一个插件允许我们收集关于 TrueCrypt 进程、服务、驱动程序、相关符号链接和文件对象的信息。

图 4.32 – Volatility TrueCrypt 总结
在这里,我们可以看到其中一个驱动器被TrueCrypt加密了,因此我们可以尝试从内存中提取主密钥:

图 4.33 – Volatility TrueCrypt 主密钥
默认情况下,TrueCrypt 和一些其他工具使用 AES 进行加密。这就是为什么获取加密主密钥的另一种方式是使用任何具有 AES 检测功能的工具。我们已经讨论过这样一个工具:可以使用其中一个批量提取器扫描器来实现这一目的。让我们运行 AES 扫描器:

图 4.34 – 批量提取器 AES 扫描器
作为结果,我们将得到一个名为 aes_keys.txt 的文本文件。该文件的内容如下所示:

图 4.35 – 提取的 AES 密钥
在这里,我们发现了几对 AES256 密钥。通过将这些 256 位密钥对结合起来,我们可以获得 512 位的主密钥。
这个过程并不容易,这也是一些取证软件开发人员在他们的解决方案中包含密钥提取功能的原因。
Passware 是最流行的工具之一,用于搜索加密文件、解密加密驱动器以及恢复 Windows 密码和存储在密码管理器中的密码。此工具支持大多数全盘加密解决方案,包括BitLocker、TrueCrypt和PGP。

图 4.36 – Passware
如果你想尝试这个工具,可以从他们的官方网站申请一个演示版:www.passware.com/kit-forensic/。
我们已经讨论了如何查找已启动的程序和打开的文档,如何恢复密码以及如何检测加密驱动器。然而,还有一件重要的事情被忽视了——Windows 注册表。
调查 Windows 注册表
关于用户常用的程序、最近打开的文档、外发的 RDP 连接等信息都被写入计算机的注册表中,我们总是能在内存中找到它们的最新版本。为了避免混淆,我们需要理解注册表在 Windows 中的工作原理。
虚拟注册表
为了正常工作,你的计算机需要存储关于硬件和软件配置的信息、所有系统用户的数据、每个用户的设置,以及更多信息。当我们的系统启动时,它会从硬件和存储在非易失性内存中的注册表文件中收集这些信息,并在内存中创建一个虚拟注册表。这个虚拟注册表是当前配置存储的地方,也是所有将被写入磁盘的更改的初始存储位置。与注册表的交互过程是持续进行的,因此我们总是能够在内存转储中找到虚拟注册表的蜂巢和相关文件。
大多数时候,我们需要处理多个文件:
-
SAM包含关于组和用户的信息,包括他们的权限、密码和最后登录日期。 -
SYSTEM包含操作系统相关的信息,例如计算机的名称、服务、连接的 USB 设备、时区信息和网络适配器配置。 -
SOFTWARE包含已安装软件、计划任务、自动启动和应用程序的向后兼容性信息。 -
NTUSER.DAT包含与特定用户相关的信息:最后查看的文档、常用的程序、资源管理器历史记录以及外发的 RDP 连接。
还记得userassist插件吗?它从注册表中提取信息——更确切地说,是从NTUSER.DAT文件中提取。hashdump和cachedump也使用注册表。
让我们看看如何在内存中处理注册表文件。
重要提示
我们不会深入讲解 Windows 注册表取证的细节,因为这个主题需要深入研究。然而,我们将拆解出为实现目的所需的主要键。
Volatility 提供了几个插件用于一般的注册表工作:
-
Printkey显示注册表键、它们的子键及其值。 -
hivelist列出了可访问的注册表 hive。 -
dumpregistry允许我们从内存中提取注册表文件。 -
一些插件还提取了某些键的值:
-
userassist -
shutdowntime -
shellbags
所有这些插件在启动后都会显示具有相同名称的键的值。
然而,以这种方式处理注册表并不总是方便。此外,它们并不适应与更新版本的 Windows 10 一起使用。如果我们需要分析一个新的构建版本,应该怎么办呢?有一个很棒的工具,可以让你将物理内存作为虚拟文件系统中的文件查看。它叫做 MemProcFS。
安装 MemProcFS
查看这个链接,了解 MemProcFS 的安装过程:github.com/ufrisk/MemProcFS/blob/master/README.md。
该工具有多个依赖项。首先,你需要安装 LeechCore。为此,你需要在 PowerShell 中执行以下命令:

图 4.37 – 安装 LeechCore
下一步是安装 Microsoft Visual Studio 2019 的 Visual C++ 可再分发组件。你可以从 go.microsoft.com/fwlink/?LinkId=746572 获取安装程序。接下来,你需要安装 DokanSetup_redist 版本。你所需要的最后一个组件是 Python 3.6 或更高版本。你可以从官方网页获取适合的 Python 版本:www.python.org/downloads/windows/。
恭喜 – 你现在已经准备好下载 MemProcFS!前往 MemProcFS 的 GitHub 仓库 github.com/ufrisk/MemProcFS,并搜索最新版本。

图 4.38 – MemProcFS GitHub 仓库
下载 files_and_binaries ZIP 压缩包并解压到合适的位置。要运行 MemProcFS,打开 PowerShell 并进入你解压文件的文件夹。运行以下命令以从你的内存转储创建一个虚拟文件系统(使用 -device 选项提供你的内存转储位置)。

图 4.39 – MemProcFS 执行
如你所见,我们的操作系统已被识别,转储成功地挂载在 M:\ 驱动器上。现在,我们可以通过资源管理器打开这个驱动器,并搜索一些有趣的内容。
与 Windows 注册表的工作
我们决定告诉你这个工具的原因。因为使用 MemProcFS,你可以轻松地从内存中提取所有的注册表文件。(老实说,你甚至不需要提取任何东西。)打开你的驱动器(在我们的例子中是M:\驱动器),进入registry > hive_files,如下图所示。在这里,你将找到我们在转储中所有可用的注册表文件。

图 4.40 – MemProcFS Hive 文件
所以,我们找到了注册表,但接下来该做什么呢?这里有几种选择。首先,你可以使用Eric Zimmerman 的 Registry Explorer 工具。最新版可以从官方仓库下载:ericzimmerman.github.io/#!index.md。包含工具的压缩包必须用 7-Zip 解压,否则工具将无法正常工作。Registry Explorer 允许你查看各种键值,并使用包含有用信息的预设书签。

图 4.41 – 注册表查看器
另一方面,你也可以使用RegRipper来解析这些文件。这样,所有信息都会作为一个单一的文本文件提供给你。你可以从以下 GitHub 仓库下载这个工具:github.com/keydet89/RegRipper3.0。
要运行图形界面工具,你需要使用rr.exe文件。在出现的窗口中,你需要指定要处理的文件路径和保存执行结果的文本文件路径。填写完所有字段后,点击ntuser文件夹中的文件,从我们的hive_files文件夹中复制它到方便的位置,然后尝试分析它。

图 4.42 – RegRipper
结果是,你将得到两个文本文件。第一个文件,带有.log扩展名,是程序的日志。第二个文件,带有.txt扩展名,包含了解析结果。你可以在任何文本编辑器中打开它并使用关键词搜索。例如,要查找用户运行的程序,你可以搜索userassist。

图 4.43 – Userassist 注册表键
如果你想查看用户最近处理的文档,可以查找opensave或recentdocs。

图 4.44 – RecentDocs 注册表键
最后,如果你想查看用户在本地或远程主机上访问过的目录,可以从相应的 GitHub 仓库下载ShellbagsExplorer(https://ericzimmerman.github.io/#!index.md)。找到usrclass注册表文件并将其拖入运行中的工具中。你应该能看到如下输出:

图 4.45 – ShellBags Explorer
请注意,这个文件是从内存转储中提取的,我们在其中发现了由 TrueCrypt 加密的 S 盘的痕迹。通过分析usrclass文件,我们能够看到加密磁盘的一部分内容。
总结
分析用户活动是内存调查中的一个非常重要的部分。在本章中,你学到了可以恢复很多痕迹。这对于刑事调查尤为重要,因为这些痕迹能帮助你重建用户活动,即使他们使用了匿名浏览器或安全通讯工具。
波动性是内存转储分析的一个重要工具,但不要因此而停滞不前。在需要时,千万不要害怕使用额外的工具或替代解决方案。
尽管进程内存中信息丰富,但不要忽视虚拟注册表,它存储了大量有用的信息,包括与用户活动相关的信息。此外,一些注册表键值能够告诉我们很多关于恶意软件活动和持久性痕迹的信息。我们将在下一章讨论这些及其他恶意活动的痕迹。
第五章:使用 Windows 内存取证进行恶意软件检测与分析
内存转储的取证分析并不仅限于分析用户的行为,尤其是在处理受害者计算机时。在这种情况下,专家通常需要进行分析,以寻找恶意活动的痕迹。这些痕迹可能是恶意进程、网络连接、代码注入,或者任何与恶意软件或攻击者工具行为相关的内容。由于现代恶意软件倾向于尽可能少地在磁盘上留下痕迹,而威胁行为者会使用 PowerShell 和批处理脚本保持隐蔽,内存分析正成为取证调查中的一个关键元素。
本章将解释如何在网络连接和活动进程中搜索恶意活动的痕迹,同时还会分析 Windows 注册表、事件日志和文件系统伪迹。
本章将涵盖以下主题:
-
搜索恶意进程
-
分析命令行参数
-
检查网络连接
-
检测进程内存中的注入
-
寻找持久化证据
-
创建时间线
搜索恶意进程
我们已经学会了如何分析在转储时活跃的进程,以识别用户活动。类似的技术也可以用于搜索攻击者留下的痕迹;然而,在这里,我们的重点将转向检测一些特定标志,帮助识别恶意活动。用户程序,如浏览器或 MS Office 组件,不会像云存储相关进程那样,成为关于用户及其近期活动的信息来源,而更可能成为初始访问痕迹的潜在来源。与此相关的进程,将被视为可能的数据外泄技术。我们调查的主要目标是寻找潜在恶意活动的标志和各种异常——如奇怪的进程名称或不寻常的参数、它们的非典型行为等。然而,先从最简单的开始——进程名称。
进程名称
在上一章中,我们讨论了如何获取活跃进程列表以及一个名为 pslist 的插件。所以我们不会重复这一部分;我们只会讨论你需要注意的要点。
首先,你需要了解系统进程。Windows 有许多这样的进程,负责运行个别服务和系统本身。这些进程常常成为恶意软件的目标,恶意软件会试图伪装成系统进程,或者在最坏的情况下,利用一个合法进程。但我们会在后面详细讨论这一点。让我们看看下面的示例:

图 5.1 – Volatility pslist 插件
图 5.1显示了通过pslist插件收集的进程列表。我们故意添加了一个正则表达式,用于选择那些包含host的进程名称。请注意svchost进程。这些是从动态库加载的服务的标准进程。现在,看看ID 1664的进程名称。你能看到不同之处吗?这个转储来自一个被IcedID感染的主机,IcedID是一种非常常见的恶意软件,通过钓鱼邮件传播,并与恶名昭著的勒索病毒运营者如 REvil、Conti 和 Egregor 有关联。在执行过程中,这种恶意软件会将一个名为svhost.exe的可执行文件丢入临时目录并将其作为子进程运行。
为了快速找到这种伪装的进程,不仅需要了解关键系统进程的名称及其特点,还需要考虑上下文,因为不同版本的 Windows 系统中的进程可能有所不同。这些差异通常是微不足道的,但了解这些差异将帮助你更有效地浏览进程列表并进行分析。
虽然一些恶意程序隐藏在合法进程的伪装后面,但另一些则非常公开地运行。这就是双重用途工具和一些攻击者使用的程序的情况。让我们看一下进程列表,如图 5.2所示:

图 5.2 – 正在运行的进程列表
在这里,我们可以看到大量看似合法的进程:whoami.exe、ipconfig.exe、netstat.exe等。这些工具可以被系统管理员或高级用户用来检查设置和配置网络。然而,这些相同的工具也可以被攻击者用来收集关于系统的信息,正如我们在场景中所做的那样。
像cmd.exe、powershell.exe、wscript.exe、cscript.exe和rundll32.exe这样的进程需要特别注意,因为它们经常被攻击者和现代恶意软件用作执行、持久化、防御规避、发现、收集等战术的一部分。在进程列表中出现这些进程不仅仅是重要的,相关的父进程同样也至关重要。父子进程的不典型组合是潜在恶意行为的标志之一。
检测异常行为
异常行为可能表现为许多不同的形式。对于某些进程,建立网络连接是非常不典型的,而对于其他进程,生成新进程或访问某些文件系统对象则是不典型的。
让我们考虑以下示例:

图 5.3 – 进程树
这里,WINWORD.EXE 进程生成了一个子进程 rundll32.exe,这在正常情况下是非常不典型的行为。这种行为可能是由嵌入在用户打开的文档中的宏所引起的。通常,MS Office 文档会成为网络钓鱼电子邮件的附件,长期以来,这一直是用于初始访问的最常用技术之一。Trickbot、Qakbot、Dridex 和 IcedID 都是通过这种方式传播的。例如,在 Trickbot、IcedID 和 Qakbot 的网络钓鱼活动中,用户会收到一封网络钓鱼邮件,其中附带了一个包含以下内容的文档:

图 5.4 – 欺骗性文档
你可能会问:为什么不同的威胁行为者使用相同的诱饵? 其实,他们利用了另一个威胁行为者 Shathak(也称为 TA551)的服务,后者专注于恶意软件分发。
在我们的案例中,要验证恶意文档的假设,我们需要找出哪个文件在 MS Word 中被打开,并尝试将其导出以供进一步分析。为此,我们可以使用 handles、filescan 和 dumpfiles 插件。我们回顾一下操作的顺序,如下所示:
-
使用
handles插件并结合-tfile和--silent选项来获取有关我们进程使用的文件的信息,并查找由用户打开的文档。 -
使用
filescan插件来搜索有关包含所需文档的物理偏移量的信息。 -
使用
dumpfiles插件,并结合-Q选项以及先前步骤中获得的物理偏移量,再加上-D选项和我们想要保存文件的路径。
在上一章中,我们已经从 WINWORD.EXE 的内存中转储了 GOT-7_HR (00000007).docm 文件。现在让我们探索如何分析这个文档是否含有恶意内容。为此,你可以使用 https://github.com/decalage2/oletools)。Oletools 是一个 Python 工具包,用于分析 Microsoft OLE2 文件,如 MS Office 文档或 Outlook 消息。你只需安装 Python 3,并在 PowerShell 中运行以下命令,就可以安装这些工具:
pip3.exe install -U oletools
必要的依赖项将自动安装。因此,你将能够通过 PowerShell 使用 oletools 包中的任何工具来分析可疑文档。让我们检查导出的文档:

图 5.5 – olevba 输出
在该工具的输出中,你还可以找到有关宏、参数、导入的库等更详细的信息:

图 5.6 – 详细的宏描述
如你在前面的屏幕截图中看到的,我们的文档包含了内嵌的宏,具有混淆字符串和向进程注入代码所需的功能。
那么,我们在这里得到了什么?好吧,用户在 MS Word 的未保护模式下打开了文档,然后嵌入的脚本被执行,创建了rundll32.exe进程,该进程产生了多个相同名称的子进程。
让我们来看另一个例子,如图 5.7所示:

图 5.7 – 进程树
你是否记得svhost.exe进程伪装成合法的svchost.exe?让我们考虑它的父进程——nwe.exe,其PID 1744。即使我们在最初的分析中没有注意到 svhost 名称中缺少 c,父进程仍然会揭示它的秘密。因为svchost进程是系统进程,它们有一个预定义的父进程——services.exe。
注意
除了某些父进程外,所有系统进程都有固定的实例数量、预定义的用户、启动时间和磁盘上可执行文件的位置。任何偏离定义参数的情况都会引起怀疑,并需要额外检查。
回到我们的nwe.exe进程,注意到除了恶意的svhost.exe,它还创建了几个cmd.exe进程。像cmd.exe、powershell.exe等嵌入式工具常被攻击者用来进行无文件攻击。通过这种方式,攻击者利用经过批准的应用程序执行恶意命令和脚本。与传统方法不同,这种方式不需要在目标系统上安装任何代码,从而使检测变得更加困难。
让我们考虑无文件勒索软件的例子。在第一阶段,向用户发送一封钓鱼邮件,其中包含一个恶意宏,如前面所讨论的那样。运行宏会启动一个命令行,执行 PowerShell 脚本。该脚本下载加密密钥和额外模块——其执行结果是数据加密和赎金通知展示。
这样的攻击场景已经变得越来越经典。这就是为什么我们需要找出启动这些进程时使用了哪些参数,以及执行了什么。
分析命令行参数
分析命令行参数非常重要,因为它允许你检查可执行文件运行的位置以及传递给它的参数。这些参数可能包括其他受感染主机的 IP 地址或主机名、被盗的凭证、恶意文件名和整个脚本,如下图所示:

图 5.8 – Emotet 操作员使用的命令行参数
让我们探索几种获取感兴趣数据的方法。
进程的命令行参数
首先,我们可以使用我们已经熟悉的pstree插件并添加-v选项。这将允许我们输出进程树,同时显示启动特定程序时使用的命令行详细信息。这就是添加-v选项后,输出如图 5.7所示的变化:

图 5.9 – 详细的 pstree 输出
如你所见,我们有了新的行:audit、cmd和path。在这里,我们可以找到关于可执行文件的位置以及启动它时使用的参数的信息。你也可以使用一个独立的插件——cmdline,它的输出将如下所示:

图 5.10 – cmdline 输出
为了清晰起见,cmdline是使用-p选项和进程 ID 运行的,如前面的示例所示。从两个命令的输出中,我们可以看到我们的svhost.exe文件是从C:\Users\lesly\AppData\Local\Temp目录可执行的,这对于合法的svchost进程来说也不标准。这是另一个标志,表明该进程是恶意的。
让我们来看另一个例子,展示参数的作用:

图 5.11 – 通过正则表达式选择的进程的 cmdline 输出
在这种情况下,我们可以观察到运行 PsExec 时使用的参数,PsExec 是一种在攻击中经常用来远程执行命令和在主机上运行脚本的工具。那么,这告诉调查员什么呢?首先,它告诉我们攻击者正在使用PsExec进行执行和横向移动。其次,它揭示了他们正在交互的主机的名称。第三,它识别了已被攻破的用户凭据。
除了关于启动程序时使用的参数的信息之外,了解攻击者通过命令行执行的命令也会很有用。我们接下来讨论这个问题。
命令历史记录
自然,通过命令行执行的命令信息也会存储在内存中。为了获取这些数据,你可以使用 Volatility cmdscan 插件,它可以帮助你在内存中查找命令历史记录对象。该插件的输出如图 5.12所示:

图 5.12 – cmdscan 输出
请注意,这个插件的功能是有限的。例如,它只搜索默认历史记录大小的实例。如果你愿意,可以使用-M选项并设置其他任何值;然而,如果历史记录大小已被更改,找到该值会存在问题。
这个插件的替代方案是使用yarascan,我们在cmd命令中已经讨论过它,你可以编写规则来查找 PowerShell 和其他感兴趣的工具:

图 5.13 – 使用 YARA 规则检测恶意 PowerShell
图 5.13展示了一个简单的YARA 规则示例,用于搜索带有典型-nop、-w hidden和-enc选项的恶意 PowerShell 脚本。使用带有此规则的yarascan插件,你不仅可以找到恶意脚本本身,还可以获得在其中找到它们的进程的相关信息。
能够理解命令行上执行了什么是好的,而知道执行结果更好。consoles插件允许你获取不同命令行解释器执行的命令的数据:cmd、PowerShell、Python shell 和 Perl shell。consoles的主要优势是,它还允许你输出来自输入和输出缓冲区的信息,这样你就可以查看命令执行的结果。运行consoles与运行cmdline类似。让我们来看一个使用此插件获取的输出示例:

图 5.14 – Volatility 的 consoles 插件
在图 5.14中,首先,我们查看关于conhost.exe进程及其附加进程的信息,并伴随着当前使用的设置详情。最有趣的部分是dump。在这里,我们可以观察到实际执行的内容。请注意,在顶部,我们可以看到关于cmd.exe进程和updater.bat文件的信息,而在dump中,我们看到的是 PowerShell。那么,发生了什么呢?让我们稍微明确一点,并将3008和3672进程的cmdline插件输出添加到这里:

图 5.15 – 所选进程的 cmdline 输出
在图 5.15中,我们可以观察到,ID 为3008的进程是通过cmd.exe /c启动的。在我们的案例中,这意味着Updater.bat文件(其路径在/c选项后面指定)必须通过cmd来运行。在consoles插件的 dump 中,我们看到 PowerShell 正在运行,因此我们可以得出结论,PowerShell 及其所有选项是在同一个Updater.bat文件的内容中,这个文件是通过cmd执行的。
请注意 PowerShell 运行时的-enc选项。这个选项告诉我们,后面跟着的是 Base64 编码的命令。在法医调查中,这并不罕见。你可以使用在线的 CyberChef 工具(https://gchq.github.io/CyberChef/)解码这样的代码。你只需将 PowerShell 中的编码部分复制并粘贴到输入窗口中。接下来,选择需要应用的配方,搞定,一切准备好:

图 5.16 – 使用 CyberChef 解码的 Base64 代码
请注意,这个脚本的一个功能是创建一个WebClient对象。这类对象通常用于执行网络通信。
网络可以被恶意软件用来与命令与控制(C2)服务器进行通信并下载恶意负载。除此之外,如果攻击者以交互方式连接到远程主机,也会建立网络连接。因此,分析网络连接并寻找其中的异常是搜索恶意活动痕迹的另一个关键部分。
检查网络连接
Volatility 的netscan插件用于分析网络连接。它可以帮助你收集有关所有活动和最近连接的信息,以及打开的套接字。让我们看一个例子:

图 5.17 – Volatility netscan 输出
在图 5.17中,我们可以查看标准的netscan输出。这为我们提供了有关 OSI 传输层协议及其版本、涉及的 IP 地址和端口、PID,以及启动网络活动的进程名称和创建时间等信息。对于 TCP 协议,它与 UDP 不同,建立连接来传输数据,还会指定连接状态。例如,如果一个进程在某个端口上监听并等待传入连接,状态将是LISTENING。此外,如果连接到远程主机已建立,状态将是ESTABLISHED,而如果连接已终止,状态则是CLOSED。那么,我们如何处理这些信息?我们该寻找什么呢?
进程 – 启动者
让我们从一个简单的开始。就像在分析进程时,我们通过分析父子关系来寻找不典型的组合一样,我们也可以从启动连接的进程数据开始。显然,对于一些进程来说,创建网络连接是正常的。我们可以将这些进程称为浏览器、邮件代理或即时通讯工具。此外,一些程序可能会建立网络连接以检查更新和下载,这也是正常行为。现在,假设一个由资源管理器进程建立的网络连接。该进程需要通过图形用户界面向用户提供文件和目录的访问,或显示开始菜单。它创建网络连接并不 100%典型。当然,explorer.exe确实有可能会创建网络连接;例如,在传输 Windows 遥测数据时,特别是在开始菜单设置发生变化时。然而,请记住,这些连接将使用特定的 IP 地址建立,因此外部地址将是恶意活动的标志。不过,我们稍后会更详细地讨论这一点。
除了非典型的发起者外,还有一些进程我们需要特别注意。包括 cmd.exe 和 powershell.exe。如果你检测到这些进程建立的连接,一定要检查 Foreign Address 字段中指定的 IP 地址:

图 5.18 – cmd.exe 进程连接到远程 IP 地址
看一下前面的示例。在这里,cmd.exe 进程(PID 2860)与 IP 地址 216.58.207.206 建立了网络连接。我们来检查一下这个地址。为此,你可以使用各种在线资源,例如 VirusTotal(www.virustotal.com/gui/home/search)。这个资源允许你搜索 IP 地址、URL、文件哈希值或文件本身的信息:

图 5.19 – VirusTotal 中的可疑 IP 地址
在图 5.19中,你可以查看我们 IP 地址的搜索结果。乍一看,一切似乎都很好——没有检测到任何威胁。然而,请注意 10+ 个检测到的文件与此 IP 地址通信 的消息。为了查看更多关于与这个 IP 地址通信的文件的信息,你可以切换到RELATIONS标签,找到Communicating Files字段,如下截图所示。如果你在 VirusTotal 上有账户,你还可以点击右侧的图标查看所有的通信,以图形化方式展示:

图 5.20 – VirusTotal 通信文件
在图 5.20中,我们可以看到,尽管这个 IP 地址没有被识别为恶意的,但它与很多恶意文件相关联,这意味着它并不安全。
如你所见,IP 地址在取证调查中起着重要作用。
IP 地址和端口
不仅仅是 IP 地址和端口的使用情况能告诉你某个网络连接是否恶意,有时候,它们还可以告诉你攻击者使用了哪些工具。我们来看看接下来的截图:

图 5.21 – Volatility netscan
显示的信息不多;然而,即使在这里,你也可以看到可以通过 RDP 连接到此主机。那么,接下来的连接呢?你看到什么可疑的地方吗?来看看:

图 5.22 – 另一个可疑的连接
成功了!你可以看到 UWkpjFjDzM.exe 进程,而这个奇怪的名字背后是一个 meterpreter。
重要提示
Meterpreter 是 Metasploit 负载之一,提供交互式 shell,攻击者可以用它在目标机器上执行各种操作。
那么,我们是如何仅通过一行网络连接信息就知道这些的呢?事实上,端口在这里发挥了重要作用。我们已经提到过用于建立连接的传输层协议。当两个主机使用这些协议建立连接时,它们会根据端口号进行识别。通常,特定用途的端口是由互联网号码分配局(IANA)分配和注册的,尽管在实际操作中,经常会出现非官方使用的情况。然而,确实有一份用于特定用途的默认标准端口列表。有时,使用这些默认端口可以泄露攻击者使用的某些服务或工具。以下是最常用的 TCP 端口及其用途:

图 5.23 – 常用端口及其用途
如你所见,前表中列出的部分端口可以被攻击者利用。例如,80、443、445 或 3389。
除了标准服务常用的端口外,还有一些工具使用的默认协议,例如端口扫描器或后期利用框架。下表列出了这些工具及其默认端口:

图 5.24 – 特定工具使用的默认端口
这样,就解决了 Meterpreter 载荷的其中一个谜团。但这可真是个棘手的问题,不是吗?通常,Meterpreter 是通过注入进程的内存来部署的。它完全存在于内存中,因此不会写入磁盘。此外,也不会创建新的进程。这是因为 Meterpreter 被注入到一个受感染的进程中,然后它可以迁移到其他正在运行的进程。因此,攻击的取证痕迹非常有限。你明白这意味着什么吧?是时候谈谈注入和如何检测它们了。
检测进程内存中的注入
进程内存中有不同类型的注入。有些相似,而有些则差异很大。根据使用的技术,检测注入的方法可能会有所不同。我们将尝试讨论最相关的几种注入类型及其检测方法。
动态链接库注入
攻击者可以利用此技术进行防御规避或特权提升战术。通常,动态链接库(DLLs)注入是用于在合法进程的地址空间中执行任意代码的方法之一。DLL 注入有两种主要类型:远程注入和反射注入。
远程 DLL 注入
恶意进程获取 SeDebugPrivilege 权限,这使它能够作为调试器操作,并获得对其他进程地址空间的读写权限。利用这些权限,恶意进程打开目标进程的句柄,访问其地址空间,并将恶意库的完整路径写入其中。该库应该已经存在于磁盘上。然后,恶意进程使用 Windows API 函数在目标进程的上下文中创建一个新线程。这个新线程是用来将恶意库加载到目标进程地址空间中的。当这一过程发生时,恶意进程会清除写入磁盘的库路径所在的内存位置,并关闭目标进程的描述符。如果我们将这一过程整合成一个算法,它会是以下内容:
-
获取权限并打开目标进程的句柄。
-
将恶意 DLL 的完整路径写入目标进程的地址空间。
-
创建一个新线程,使用 Windows API 函数从磁盘加载 DLL。
-
从目标进程的内存中删除恶意 DLL 的路径。
-
关闭目标进程的句柄。
由于远程 DLL 注入会将库写入磁盘,我们可以使用像 dlllist 和 ldrmodules 这样的 Volatility 插件来检测这一点。
有趣的是,dlllist 是一个插件,允许你获取已加载到进程中的库列表:

图 5.25 – Volatility dlllist 插件
请注意,关于进程使用的库的信息存储在三个不同的列表中:
-
LoadOrderList组织了模块加载到进程中的顺序。 -
MemoryOrderList组织了模块在进程虚拟内存中出现的顺序。 -
InitOrderList组织了DllMain函数执行的顺序。
dlllist 插件只与 LoadOrderList 一起工作。问题在于,有时候恶意库可能会从此列表中取消链接以隐藏它们的存在。这也会影响 dlllist 插件的输出,因为有关取消链接库的信息将不会显示。在这种情况下,ldrmodules 插件将提供帮助,因为它不仅输出三个列表中的所有信息,还提供关于该库是否存在于每个列表中的数据:

图 5.26 – Volatility ldrmodules 插件
通过这种方式,你可以检测已被取消链接的库。这些库在 InLoad 列中会显示为 False,而在其他列中则显示为 True。
重要提示
可执行文件本身也出现在这两个插件的输出中。在 ldrmodules 的输出中,InInit 列始终显示为 False。这是因为它的初始化方式不同,不像其他模块那样。
那么,如何判断这些插件提取的库中是否包含恶意库呢?你可以通过分析库的名称和位置来开始。注意一些不寻常的名称和库所在的磁盘目录。特别关注用户目录和临时目录。如果你在视觉上很难识别异常,可以随时使用dlldump和dumpfiles插件,并尝试将 DLL 提取到磁盘上进行额外检查。运行dlldump插件类似于dumpfiles插件。你只需要使用-p选项指定你感兴趣的进程 ID,使用-D选项指定你希望保存结果的目录路径。带有标准.dll扩展名的文件将出现在你指定的目录中。此时,你可以统计库的哈希值,并在VirusTotal上检查它们。
假设我们已为进程 ID 为1072的进程运行了以下命令,我们认为它可能是可疑的:
PS D:\> .\volatility_2.6_win64_standalone.exe -f .\dll.bin
--profile=Win7SP1x64 dlldump -p 1072 -D .\output\
结果,我们的库已保存在输出目录中。为了快速计算 DLL 的哈希值,你可以使用以下 PowerShell 命令:

图 5.27 – 使用 PowerShell 计算 DLL 的哈希值
这个命令对目录中的每个文件调用Get-FileHash函数。
让我们用 VirusTotal 检查我们的哈希值:

图 5.28 – 使用 VirusTotal 检测到的恶意 DLL
这是我们的恶意 DLL。现在,我们可以分析它是如何进入系统的,并更详细地探讨它的功能。
另一个需要记住的重要点是,恶意 DLL 可能会使用打包工具进行打包。如果在解包阶段 DLL 代码被写入新的内存区域,我们可以使用malfind插件来检测它,稍后会讨论该插件。
反射式 DLL 注入
另一种注入库的方法是通过反射式 DLL 注入。这种方法更受欢迎,因为它不需要库存在磁盘上,因此留下的痕迹更少。这样的库可以通过网络下载,并立即注入到进程内存中。此方法的另一个特点是使用反射加载器,它嵌入在库本身中,而不是标准的 Windows 加载器。这个加载器会处理执行环境,并运行DllMain函数。
反射式 DLL 注入的逐步算法如下:
-
获取权限并打开目标进程的句柄。
-
在目标进程中分配内存并将恶意 DLL 写入其中。
-
创建一个新线程以调用反射加载器。
-
关闭目标进程的句柄。
这种技术被商业恶意软件广泛使用。例如,SDBbot 从 C2 下载恶意库并将其注入到新创建的 rundll32.exe 进程中。Netwalker 勒索病毒也使用相同的方式,将库反射性地注入到 explorer.exe 进程中。除此之外,许多后渗透框架也具备反射注入 DLL、shellcode 或可执行文件到进程的功能。我们熟知的 Metasploit、CobaltStrike 和 PowerShell Empire 都具有此功能。
你可以使用 malfind 插件来检测反射 DLL 注入。关键是,当使用这种技术时(就像使用压缩工具一样),会在目标进程内存中创建一个带有 EXECUTE_READWRITE 保护的页面。这是为了能够在该页写入恶意代码并执行它。malfind 插件可以帮助你找到这样的页面,并检查它们是否包含可执行文件头或者正确的 CPU 指令。
重要提示
一些程序可能会作为其合法活动的一部分注入库或代码。例如,反病毒解决方案就具有这样的功能。
malfind 插件有几个有用的选项,你可以根据需要单独或组合使用它们:
-
-p <PID>允许你在具有特定 ID 的进程中搜索注入内容。 -
-n <正则表达式>允许你搜索所有进程中与正则表达式匹配的注入内容。 -
-D允许你转储注入的代码段。
让我们来看一下以下示例:

图 5.29 – Volatility malfind 插件
在这里,我们用 rundll32.exe 的进程 ID 运行了 malfind,并使用 -D 选项将注入的代码转储保存到输出目录。正如你所看到的,在这种情况下,我们的插件发现了具有有效 CPU 指令的 PAGE_EXECUTE_READWRITE 页面。
继续检查插件的输出,你还可以观察到带有可执行文件魔术数字的页面,如下图所示:

图 5.30 – 带有 MZ 魔术数字的 malfind 输出
你并不总是能够找到这些魔术数字。这是因为攻击者通常会使用各种掩蔽技术,包括移除头部信息。因此,你不应该只关注这些魔术数字的存在;更好的做法是检查所有看起来可疑的内容。
由于我们已经将 malfind 的输出提取到磁盘上,我们可以检查它们是什么内容。为此,你可以使用专门的工具,如 CFF Explorer(https://ntcore.com/?page_id=388)。另外,你还可以回到我们熟悉的 VirusTotal,它不仅可以给出提取代码的恶意性,还能帮助分析其性质。
在我们的案例中,以下是一个有趣的结果:

图 5.31 – 被 malfind 检测到的恶意 DLL
在这里,我们转储的一个注入被识别为恶意的。在右侧,注意到转储的内容是一个 DLL 文件。
如前所述,可执行文件也可以以类似的方式注入到进程中。接下来我们来看一个例子。
可移植执行文件注入
这种注入方式背后的思想非常简单。如前所述,它首先通过获得调试器权限并为目标进程打开句柄开始。接下来,在目标进程的地址空间中分配一块内存区域,然后用来写入恶意代码。当代码写入完成后,会创建一个新线程,目的是执行注入的恶意代码。通过这种方式,我们能够使恶意代码在合法进程的上下文中运行。
在这种情况下,逐步算法如下:
-
获取权限并打开目标进程的句柄。
-
在目标进程中分配内存并在其中写入恶意代码。
-
创建一个新线程来运行注入的代码。
-
关闭目标进程的句柄。
正如你所看到的,一切尽可能简单,最重要的是,磁盘上没有留下任何痕迹。第二步中分配的页面通常具有 EXECUTE_READWRITE PROTECTION 权限。这意味着 Volatility 的 malfind 插件也能帮助我们检测这种类型的注入。然而,请注意,malfind 只分析具有读、写和执行权限的私有内存区域。这意味着该插件的可检测性是可以被绕过的。想象一下,攻击者最初分配一个具有读写权限的页面;然后,在写入恶意代码后,他们将其更改为读和执行权限。从恶意活动的角度来看,一切照常工作,但 malfind 无法检测到。此时,我们可以使用手动分析。
进行这种分析的一个方便工具是 Fireeye 的 Redline,它可以通过填写一个简短的表单从官网 (www.fireeye.com/services/freeware/redline.html) 下载。这个工具有图形界面,可以让你查看内存区域及其内容和保护标志:

图 5.32 – 使用 Redline 进行内存分析
正如你在前面的截图中看到的,我们可以在表格视图中检查感兴趣的信息。如果我们需要了解某个特定区域的更多细节,可以双击该区域进行查看:

图 5.33 – Redline 完整详细信息
除了malfind,还有其他插件可以用于查找特定的注入。例如,cobaltstrikescan是由日本 CERT 专家开发的。它专门用于通过YARA 规则查找注入到进程中的 Cobalt Strike 信标。
重要提示
除了内置的 Volatility 插件外,您还可以使用社区开发的插件。为此,您需要在与 Volatility 版本相同的目录中创建一个plugins文件夹,并将您要使用的插件代码放入其中。要启动一个新的插件,只需在 Volatility 命令行中添加--plugins=<插件文件夹路径>,并且不要忘记指定插件名称。
要使用此插件,我们在与 Volatility 本身相同的目录中创建一个plugins文件夹,并在其中保存从 GitHub 仓库下载的.py扩展名的文件(github.com/JPCERTCC/aa-tools/blob/master/cobaltstrikescan.py)。启动 Volatility 时,我们指定--plugins=./plugins。为了检查插件是否已成功加载,我们可以使用-- info命令,此时插件列表中应显示一个新名称:

图 5.34 - 检查已添加的社区插件
现在我们可以进行测试了。让我们来看看cobaltstrikescan如何处理注入信标的搜索:

图 5.35 – cobaltstrikescan 的结果
如上图所示,Cobalt Strike 信标在Outlook.exe和rundll32.exe进程中被检测到。这意味着在这些进程的内存中,您可以找到其配置文件,其中包含诸如 C2 IP 地址等有用参数。
像 DLL 注入和代码/可执行文件注入这样的技术已经存在相当长的时间,因此已经有了或多或少可靠的检测方法。当检测到较新的技术时,事情变得更加复杂,但这些技术被攻击者频繁使用。当前最流行的技术之一是进程空壳化。
进程空壳化
空壳进程注入的基本思路是创建一个合法进程的新实例,并将其设置为SUSPEND状态,然后用恶意代码覆盖其可执行代码所占据的地址空间。因此,与以前的技术不同,经过进程空壳化后,合法进程的可执行代码将不再存在。与此同时,进程环境块(PEB)中的进程数据保持不变。因此,我们最终得到一个容器,包含合法进程的数据(DLL、堆、堆栈和句柄),其中执行恶意代码。
重要提示
PEB 是一个存储有关 DLLs、堆、环境变量以及进程命令行参数、当前工作目录和标准句柄信息的结构。
为了便于理解,我们再来看看操作的算法:
-
启动一个合法进程的新实例,并使其第一个线程挂起。
-
释放或取消映射包含合法进程代码的内存区域。
-
分配一个新的内存段,具有读、写和执行权限。
-
将从磁盘或网络上获得的恶意代码复制到新分配的内存段中。
-
将挂起线程的起始地址设置为恶意代码的入口点。
-
恢复线程。
由于这些操作,恶意代码会在由合法进程创建的容器中执行。进程空洞化的使用并不罕见。例如,Trickbot 就使用这种技术将其有效载荷注入到 wermgr.exe 进程中。
可以使用两种方法来检测进程空洞化。第一种方法涉及比较 PEB 和 虚拟地址描述符 (VAD) 结构,寻找不一致之处。
重要提示
VAD 是另一个重要的结构,用于跟踪已保留或已提交的、虚拟上连续的页面集合。这些描述符包含内存映射文件的名称、初始保护设置及一些与页面及其内容相关的其他标志。
这可以通过由 Monnappa K. A. 编写的 psinfo 插件来完成。该插件从 VAD 和 PEB 中收集信息,并以易于比较的格式输出。此外,psinfo 还尝试检测具有执行可能性的可疑内存区域:

图 5.36 – psinfo 输出
在 图 5.36 中,你可以看到 psinfo 输出显示了来自 VAD 和 PEB 的基地址、进程路径和保护设置,以及命令行和其他与进程相关的详细信息。那么,我们在进程空洞化的情况下会看到什么呢?从 PEB 获取的信息将与作为容器的进程匹配,但 VAD 结构将不再将文件映射到此内存区域。
另一种检测空洞进程的方法是使用我们已经知道的 ldrmodules 插件。你还记得在那里的可执行文件是什么样子的吗?没错;在除 InInit 外的所有列表中,它设置为 True,然后是文件在磁盘上的完整路径信息。在进程空洞化的情况下,标志(True False True)仍然会保持,但可执行文件的路径将会缺失。
除了进程空洞化,攻击者还常用另一种注入方式:进程双胞胎(Process Doppelgänging)。
进程双胞胎
该技术首次在 2017 年的 BlackHat 大会上介绍,此后一直被攻击者广泛使用。例如,Bazar Loader 就使用进程双胞胎技术来注入其有效载荷。
该技术基于 NTFS 事务的使用。事务性 NTFS 是在 Windows Vista 中引入的,目的是使文件系统的更改更加安全高效。使用事务时,会创建特殊的事务文件,任何预期的更改都写入这些文件中。一旦更改完成,可以提交事务以一次性应用所有更改,或者通过删除事务文件及其更改来回滚事务。此技术在安装新程序时非常有用,因为如果在更改过程中发生崩溃,事务将被回滚,系统将恢复到原始的稳定状态。让我们看看该技术如何在进程双重伪装算法中使用:
-
创建事务并打开一个干净的交易文件。
-
用恶意代码覆盖交易文件。
-
创建一个内存区域,指向交易文件。
-
回滚事务(这将从文件系统中删除所有交易文件的痕迹,但不会删除映射了恶意代码的内存区域)。
-
创建对象,进程和线程对象;将线程的起始地址设置为恶意代码的入口点。
-
创建进程参数并将其复制到新创建的进程地址空间。
-
运行双重伪装的进程。
使用此技术相当难以检测。对于 Windows 10 之前的系统,你可以检查与可疑进程相关联的File_Object。如果该文件启用了写访问权限,可能是进程双重伪装。对于 Windows 10 系统,由于_EPROCESS结构的新成员,这会稍微容易些。关键在于,对于双重伪装的进程,_EPROCESS的ImageFilePointer被设置为NULL。要检查可疑进程的相关信息,可以使用 Volatility 的volshell。
首先,在volshell中运行ps()来识别可疑进程的偏移量:

图 5.37 – 执行 volshell ps()
然后,使用dt('_EPROCESS',<offset>)来获取与目标进程相关的信息:

图 5.38 – 获取进程相关数据
搜索0x448 ImageFilePointer。如果出现NULL而不是正常值(如图 5.39所示),恭喜!看起来你刚刚找到了双重伪装的进程:

图 5.39 – 正常的 ImageFilePointer 值
值得在这里提到的是,即使攻击者使用隐秘的注入技术,如进程双胞胎(Process Doppelgänging),也有可能使用广泛使用的工具,如mimikatz或来自后期利用框架的 payload,在合法进程的上下文中执行。这为我们提供了使用关键字、正则表达式和YARA 规则搜索进程内存的可能性。让我们来看一下以下的例子。我们有一个名为wscript.exe的进程。如前所述,这是我们必须警惕的进程之一,因为威胁行为者可以利用wscript.exe来执行他们的恶意脚本。
重要提示
WScript 是微软 Windows 的一个组件,旨在运行用脚本语言(如 Visual Basic)编写的脚本。
在我们的场景中,调查命令行参数和进程使用的文件句柄仅让我们得到了正在使用的脚本的名称。因此,我们转储进程内存并使用strings工具来获取 ASCII 和 UNICODE 字符:

图 5.40 – 转储 wscript 的内存并使用 strings64 解析
在生成的文本文件中,你可以使用powershell、cmd、vbs和base64关键字来搜索任何感兴趣的信息:

图 5.41 – Base64 关键字搜索结果
在图 5.41中,你可以查看使用base64关键字找到的 Base64 编码代码。为了更好地理解该代码的性质,你可以使用CyberChef解码它:

图 5.42 – 解码后的 Base64
CyberChef 已经自动检测到我们的 Base64 编码代码是一个 PE 文件。此时,我们可以保存生成的 PE 文件进行进一步分析。通过继续分析这些行,我们发现该文件是通过网络下载的,并且随后被注入到一个新的进程中。
这就是我们如何检测恶意进程并在内存转储中找到各种注入。然而,这并不是全部。攻击者通常需要在系统上保持持久性,以保持对受感染主机的访问。可以通过多种方式实现这一点。接下来让我们讨论这些方式。
寻找持久化证据
恶意软件和攻击者有许多技术可以用于在系统中占据立足点。这些技术包括已经使用多年的经典技术。此外,还有一些相对较新的技术,正逐渐流行起来。我们并不是在这里讲解每一个存在的技术,而是提供一些我们认为最有可能帮助你发现系统中恶意软件持久性工具的工具。当然,例子也不会缺少。
启动或登录自动启动执行
在这种技术中,攻击者通过更改系统设置,在系统启动或登录时自动执行程序。例如,他们可以将恶意可执行文件的路径添加为以下键的某个值的数据:
-
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -
HKLM\Software\Microsoft\Windows\CurrentVersion\Run -
HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce -
HKCU\Software\Microsoft\Windows\CurrentVersion\Run -
HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce
在上一章中,我们讨论了几种从内存中提取注册表的方法。你可以选择最适合你的方式,导出与前述键对应的SOFTWARE和NTUSER.DAT注册表文件。要处理这些文件,你可以使用Registry Explorer或RegRipper,就像我们之前所做的那样:

图 5.43 – 运行键分析
在前面的截图中,可以清楚地看到Temp值和temp.bat。你还可以使用 Volatility 的prinkey插件,配合-K选项,检查虚拟注册表中该键的内容。
如果你想更有逻辑地构建搜索持久化使用的键,你可以先检查handles插件的输出,使用-t Key选项,它会显示该进程使用的所有注册表键:

图 5.44 – Volatility handles
这种方法不仅加速了搜索用于持久化的注册表键,而且还提供了恶意软件感兴趣的注册表键的信息,以及它可能如何使用这些键。需要注意的是,如果你在handles插件的输出中没有看到你寻找的键,不能保证它没有被使用。因此,如果结果不理想,建议你还是检查注册表。如果仍然能找到该键,你可以使用prinkey -K <key>检查其内容,如图 5.45所示:

图 5.45 – 使用 Volatility printkey 检查 Load 值
当然,通过滥用运行键来实现持久化并不是威胁行为者使用的唯一技术,另一个常见的技术是 Windows 注册表操作。以下是一些其他示例:
-
Winlogon 助手 DLL(MITRE ATT&CK 中的 T1547.004):威胁行为者修改
Software\Microsoft\Windows NT\CurrentVersion\Winlogon注册表键来实现持久化。 -
图像文件执行选项注入(MITRE ATT&CK 中的 T1546.012):威胁行为者修改
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options和HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit注册表键来实现持久化。 -
登录脚本 (T1037.001,依据 MITRE ATT&CK):威胁行为者修改
HKCU\Environment\UserInitMprLogonScript注册表键值来实现持久化。
让我们继续查看其他流行的持久化技术。例如,创建新账户。
创建账户
这种技术通常被勒索软件操作员使用,因为它非常适合保持对受感染系统的访问。可以再次使用注册表查找新账户的痕迹。记住,在前一章中,我们讨论了 SAM 注册表文件及其如何包含用户信息,包括创建日期。为了便于分析用户创建数据,最好使用Registry Explorer工具和书签选项卡。操作方法是,将导出的 SAM 文件拖入 Registry Explorer,点击书签,然后选择用户。这将显示一个包含所有用户的表格:

图 5.46 – 用户书签
如你所见,在前面的截图中,创建时间列显示了每个用户的创建日期和时间。你可以通过比较这些时间戳来识别在攻击期间创建的用户。
当然,这种方法有一个显著的局限性——关于域用户的相关信息可能缺失。因此,我们将考虑的另一种方法是导出事件日志。
重要提示
Windows 事件日志是位于C:\Windows\System32\winevt\Logs目录下的.evtx文件。它们包含与系统操作、用户活动等相关的各种事件。
这种方法与常规文件导出没有区别。操作步骤如下:
-
运行
filescan插件,并将其输出重定向到文本文件中。 -
打开包含
filescan结果的文本文件,并找到你感兴趣的日志。 -
从文本文件中复制所需日志的偏移量。
-
运行
dumpfiles-Q <offset>。 -
重命名生成的文件,包括扩展名。
与创建新用户相关的事件存储在Security.evtx日志中。请注意,在普通用户的计算机上,这个日志会记录本地用户创建的信息,而对于域用户,你需要查看位于域控制器上的日志。
要在 Windows 中打开导出的事件日志,你可以使用内置的事件查看器。有关创建和启用用户的其他信息可以在4720和4722事件中找到。你可以使用这些事件 ID 来创建过滤器。最终结果应该是这样的:

图 5.47 – 通过事件查看器打开的 Security.evtx
在这里,我们有关于在seriouscats域中创建honka用户的信息。还有一个时间戳,表示事件发生的时间,也就是用户被创建的时间。
重要提示
有时候,事件日志在从内存转储中导出时会损坏。若要尝试恢复来自损坏日志的事件,您可以使用 CQURE 的优秀工具CQEvtxRecovery。
因此,根据情况,你可以在注册表或事件日志中寻找新用户创建的痕迹。
事件日志本身是关于系统中发生的事情的极好数据来源:远程连接、创建用户及更改其属性、启动 PowerShell 脚本、Windows Defender 崩溃等。让我们来探索导出的内存事件日志还可以用来做什么。
创建或修改系统进程
当使用这种持久化技术时,攻击者会安装一个新服务,该服务应该运行磁盘上的可执行文件或执行脚本。通常,像Emotet和Trickbot这样的木马会利用安装新服务的方式。
有关服务安装的附加信息记录在System.evtx事件日志中,这也可以从内存转储中导出。我们会关注事件 ID 为7045的记录:一个服务被安装到系统中。分析此类事件时,您应该注意可执行文件的名称和位置,以及在脚本的情况下,所使用的参数:

图 5.48 – System.evtx
在图 5.48中,你可以看到一个恶意服务的示例。请注意,可执行文件位于用户的临时文件夹中。
分析服务的另一种方式是使用专门的 Volatility 插件。例如,你可以使用svcscan插件获取关于正在运行的服务、服务名称、类型、状态、二进制路径等信息,如图 5.49所示:

图 5.49 – svcscan 输出
还有一个由社区开发的插件,名为autoruns(github.com/tomchop/volatility-autoruns/blob/master/autoruns.py):

图 5.50 – autoruns 输出
这个插件不仅收集有关服务的信息,还收集可能被用于持久化的各种注册表键值。一方面,插件提供了相当简便的方式来访问各种信息;另一方面,收集的数据集是有限的。因此,在使用该插件之前,我们建议您阅读收集的数据列表,该列表可以在同一 GitHub 仓库中找到。
除了安装新服务外,攻击者还可以通过调度器创建任务。让我们来看看这一技术及如何检测它。
调度任务
创建调度任务是最常见的技术之一。它被商用恶意软件广泛用于在被感染系统上获取持久性。有关调度任务的信息存储在多个位置:
-
C:\Windows\System32\Tasks:在这里,你可以找到带有任务描述的 XML 文件。 -
Microsoft-Windows-TaskScheduler%4Operational.evtx:你可以分析与创建新任务相关的事件 ID 106。 -
SOFTWARE:任务缓存的信息也存储在注册表中。
我们将继续进行注册表分析。所以,我们需要像之前一样导出 SOFTWARE 文件。这次,我们将使用 RegRipper 来解析我们的注册表文件:

图 5.51 – 使用 RegRipper 解析 SOFTWARE
我们可以使用 taskcache 关键字来搜索所需的信息。有两个插件可以显示与任务相关的数据:tasks 和 taskcache。这两个插件都显示关于任务的路径和创建时间的信息,但第二个插件还会显示任务 ID,如下所示:

图 5.52 – taskcache 和 tasks 插件
如你所见,存在各种持久性技术,这只是其中的一小部分。然而,利用我们已经回顾过的分析方法,你将能够分析更多的技术。
法医调查中的另一个重要步骤是时间线的创建。其应用在很大程度上取决于你的目标,因为你不仅可以寻找与恶意活动相关的信息,还可以收集关于用户文件的数据。让我们更详细地看看这个话题。
创建时间线
时间线非常有用。它们在调查中扮演着重要角色,因为你不仅可以了解目标系统在特定时间段内发生了什么,还可以一步步重建攻击者的行动。以下是使用时间线的几种方法:
-
事件期间系统变化分析:如果你已经有了事件发生时的数据,可以使用时间线分析目标系统在此期间发生的变化。
-
文件时间戳分析:通过基于文件系统的时间线,你可以搜索与特定文件相对应的条目,并分析它们的出现时间戳或对其执行的操作。
-
.pf扩展名的文件在C:\Windows\Prefetch目录中创建,文件与正在运行的程序相对应。这个文件的名称通常包含正在运行的程序的名称。因此,时间线中关于预取文件创建的记录不仅可以告诉你某个程序已启动,还可以让你确定到底是哪个程序启动了。
如你所见,时间线有多种类型。我们将讨论那些可以通过内存转储构建的时间线。
基于文件系统的时间线
这个时间线基于文件系统元文件。例如,对于 NTFS 文件系统,这个文件可能是主文件表($MFT)。这个文件包含关于文件系统中所有文件及其时间戳的信息。
要基于 $MFT 构建时间线,首先需要获取其数据。这可以通过 Volatility 的 mftparser 插件完成,该插件从内存中收集所有 $MFT 条目。运行此插件的过程如下:

图 5.53 – Volatility mftparser
注意所使用的选项;它们用于以我们想要的格式保存数据。结果是一个包含无序 MFT 记录的文本文件。要将它们转换为时间线,您可以使用 TheSleuthKit 中包含的 mactime 工具。要运行此工具,您需要安装 Perl。为此,您只需从官方网站下载安装程序并按照说明进行操作(strawberryperl.com/)。
要获取 mactime 工具本身,请访问 TheSleuthKit 的官方网站(www.sleuthkit.org/sleuthkit/download.php)并下载 Windows 版本的二进制文件。将下载的压缩包解压到您方便的目录中。
现在我们准备将 MFT 记录转换为时间线。使用以下命令:
PS D:\> C:\Strawberry\perl\bin\perl.exe .\sleuthkit-4.10.2-win32\bin\mactime.pl -b .\output\body.txt > .\output\timeline.txt
使用 -b 选项时,我们指定了以正文格式传递文件。我们将工具的输出重定向到 timeline.txt 文本文件中。
您可以使用文本编辑器或 MS Excel 来查看此文件:

图 5.54 – 基于文件系统的时间线
在之前的时间线中,我们可以看到 Gnh3J8f.EXE 的预取文件被创建,这表明它已被执行。
自然地,时间戳不仅存储在文件中,还存储在创建的进程、网络连接等内容中。所有这些信息也可以添加到时间线中。让我们来看看如何做。
基于内存的时间线
您可以使用 Volatility 的 timeliner 插件来构建存储在内存中的所有信息的时间线。由于此插件的输出非常庞大,我们建议您立即将其重定向到磁盘上的文本文件中:
PS D:\> .\volatility_2.6_win64_standalone.exe -f .\nwe.mem
--profile=Win7SP1x64 timeliner > .\output\timeline.txt
这次,我们的文件中将有更多的信息:

图 5.55 – 基于内存的时间线
有时候,这些信息量过大,特别是当以文本文件的形式处理这些数据时并不太方便。作为替代方案,您可以使用 Redline,它也允许基于内存转储中的数据构建时间线。与此不同的是,您将拥有一个图形界面,并且可以轻松地添加和删除某些数据源:

图 5.56 – Redline 的时间线
看起来更方便了,不是吗?
通过这种简单的方式,我们可以构建不同的时间线并将其添加到我们的调查中。
总结
搜索恶意活动的痕迹是一个复杂但有趣的过程。
你可以使用各种标记来检测恶意进程。这些标记可以包括进程名称、可执行文件位置、启动参数、非标准的父子进程组合以及异常行为。此外,与恶意软件或攻击工具相关的进程通常会执行网络活动。对这些活动的内存分析不仅可以帮助你检测恶意进程并获取 C2 服务器的 IP 地址,还能帮助你了解攻击者使用的工具。
如果你检测到一个进程正在与远程 IP 地址通信,但没有发现其他恶意标记,那么是时候在内存中寻找恶意软件注入的痕迹了。最常见的注入类型包括 DLL 注入、可执行文件注入、进程空洞化以及 Process Doppelgänging。可以在内存转储中找到这些注入的痕迹。
一旦识别出恶意进程,值得寻找持久化痕迹,这些痕迹通常在攻击中用于维持对受损主机的访问。为了搜索这些痕迹,你可以使用专门的 Volatility 插件,或进行注册表和事件日志分析。
在调查中,构建时间线是一个很好的补充,它不仅可以帮助你查找与系统中某个变更相关的时间戳,还能帮助你将所有信息整理到一起。
这就是我们如何进行内存转储的取证调查,寻找恶意活动的痕迹。然而,内存转储并不是唯一的易失性数据来源。Windows 还具有其他来源,如pagefile、swapfile、hibernation files和crash dumps。我们将在下一章讨论这些来源并进行分析。
第六章:易失性内存的替代来源
在前几章中,我们讨论了内存转储作为法医调查中有用数据来源的重要性。我们查看了许多不同的分析工具,讨论了用户活动检查的技巧,并讨论了检测恶意软件痕迹的技术。然而,关于 Windows 操作系统内存取证的内容还没有结束。
我们一开始就提到过,除了主内存本身外,还有其他可能包含相似信息的内存来源。如果由于某些原因,你无法创建完整的内存转储或其分析失败,你总是可以转向这些来源:休眠文件、页面文件、交换文件和崩溃转储。这正是我们将在本章中讨论的内容。
本章将解释如何访问其他易失性数据来源,使用哪些工具进行分析,当然,还会讲解使用哪些技术来检索特定的信息。
本章将涵盖以下主题:
-
调查休眠文件
-
检查页面文件和交换文件
-
分析崩溃转储
调查休眠文件
我们将首先查看的替代来源是休眠文件。我们之所以从这里开始,是因为休眠文件是关闭电源前hiberfil.sys文件的压缩副本。这是睡眠模式和休眠模式之间的主要区别,因为休眠模式下电源完全切断。
由于休眠文件是计算机进入节能模式时 RAM 的副本,它可以包含用户正在处理的文件,即使这些文件在休眠文件进行分析时已经不再存在于磁盘上。因此,这个来源可能在法医调查中起着重要作用,那么我们该如何获取这个文件呢?
获取休眠文件
完整的休眠文件通常位于根目录下;然而,该文件受系统保护,默认情况下是隐藏的。如果你正在处理一台运行中的计算机,并且休眠文件已经创建,你可以使用成像工具将文件复制到可移动媒体上。
你可以使用著名的法医工具包成像工具(FTK Imager)来完成这项工作。在目标主机上运行它,点击文件 -> 添加证据项...,如以下截图所示:

图 6.1 – FTK Imager 的添加证据项选项
在出现的窗口中,选择逻辑驱动器,如以下截图所示,然后点击下一步:

图 6.2 – 选择源窗口
从下拉菜单中选择根目录(C:\),然后点击完成,如以下截图所示:

图 6.3 – 选择驱动器窗口
然后你将看到目标主机的文件系统出现在主窗口的左侧。在根目录下,你可以找到休眠文件。为了将其复制到可移动媒体,右键点击该文件并选择 导出文件…,如以下截图所示:

图 6.4 – 导出文件选项
在对话框中,选择你想要保存休眠文件的可移动媒体,并点击确定,如以下截图所示:

图 6.5 – 目标路径
你应该看到一个进度条,显示将文件复制到可移动媒体的过程,如下截图所示:

图 6.6 – 导出过程
这将导致一个 hiberfil.sys 文件出现在可移动媒体上,准备进一步处理。
如果目标主机上没有休眠文件,但你仍然想创建一个,你需要执行以下操作:
- 确保已启用休眠模式。
为此,请以管理员身份运行 PowerShell 并执行以下命令:
PS C:\windows\system32> .\powercfg.exe /availablesleepstates
-
如果休眠已启用,你将在出现的列表中看到
Hibernate。否则,你可以通过执行以下命令启用它:PS C:\windows\system32> .\powercfg.exe /hibernate on
命令示例如下截图所示:

图 6.7 – powercfg.exe
- 创建一个休眠文件。
要执行此操作,只需运行以下命令:
PS C:\windows\system32> .\shutdown.exe /h
该命令将使目标计算机进入休眠模式,你将得到一个带有时间戳的 hiberfil.sys 文件,时间戳对应命令执行的时间。然后你可以使用 FTK Imager 导出这个文件。
请注意,在法医调查中,你更可能与法医镜像打交道,而不是与实时系统打交道。要从法医镜像中提取休眠文件,只需使用特殊工具打开它。你可以使用相同的 FTK Imager 和 添加证据项… 菜单选项,但现在,你必须选择镜像文件,并指定驱动器上法医副本的路径,而不是实时系统的逻辑驱动器。导出休眠文件到磁盘的其余过程将与之前描述的过程类似。
现在我们已经成功获取了休眠文件,接下来让我们看看如何分析它。
分析 hiberfil.sys
由于休眠文件是 RAM 的压缩副本,我们首先需要解压它并获取原始副本。这可以通过使用一个名为 imagecopy 的 Volatility 插件来完成。这个插件允许我们将内存转储转换为不同的格式,并将休眠文件转换为原始格式。它的界面如下所示:

图 6.8 – Volatility imagecopy
我们使用 -f 选项指定休眠文件的路径,使用 -O 或 --output-image 选项指定我们希望保存结果的路径,并指定文件名和扩展名。别忘了使用 --profile 选项,在此处需要指定与目标主机操作系统版本相对应的配置文件。这将为您提供一个准备好进行分析的文件,在本例中是 hiberfil.raw。
将休眠文件转换为原始格式的另一种方法是使用 Comae 工具包中包含的 Hibr2Bin 工具。要获取此工具,您需要通过在官方网站上注册成为测试计划的成员,网址是 www.comae.com/。
该工具可以通过命令行运行。除了输入和输出文件外,还必须指定多个选项,例如平台以及操作系统的主版本和次版本,如下所示:

图 6.9 – Comae 工具包 Hibr2Bin
Hibr2Bin 支持以下版本:
-
/MAJOR 5/MINOR 1Windows XP -
/MAJOR 5/MINOR 2Windows XP x64;Windows 2003 R2 -
/MAJOR 6/MINOR 0Windows Vista;Windows Server 2008 -
/MAJOR 6/MINOR 1Windows 7;Windows Server 2008 R2 -
/MAJOR 6/MINOR 2Windows 8;Windows Server 2012 -
/MAJOR 6/MINOR 3Windows 8.1;Windows Server 2012 R2 -
/MAJOR 10/MINOR 0Windows 10;Windows Server 2017
这也将产生一个原始文件。此类文件可以使用您已经熟悉的工具进行分析。例如,您可以使用 Volatility 获取活动进程列表,搜索文件,或者检测恶意活动的痕迹。
重要提示
由于休眠文件有其自身的结构,因此其中某些信息仍然会缺失。例如,当您进入休眠模式时,关于活动网络连接的信息会被清除,因此您无法从 hiberfil.sys 文件中获取有关网络连接的完整信息。
让我们看看如何使用 Volatility 从休眠文件中获取活动进程列表。为此,我们使用 pslist 插件,如下图所示:

图 6.10 – 来自休眠文件的活动进程列表
同样,我们可以获取休眠文件中遇到的文件的详细信息,如下图所示:

图 6.11 – 来自休眠文件的文件列表
我们甚至可以尝试提取它们,如下所示:

图 6.12 – 从休眠文件提取文件
如您所见,这一分析步骤与完整内存转储的分析没有太大区别。因此,您可以毫无疑虑地应用我们在前几章中讨论的技术。
对于休眠文件的自动处理和分析,您可以使用如 Arsenal Recon 的 Hibernation Recon 等付费工具,或像 Magnet AXIOM 或 Belkasoft Evidence Center 这样复杂的解决方案。
这就是我们分析休眠文件的方式,但这只是我们考虑的替代数据源之一。接下来,我们继续。
检查页面文件和交换文件
我们在前几章中已经提到过页面文件和交换文件。在那里,我们讨论了操作系统用来让大量进程同时运行的机制。当物理内存不足时,该机制会将临时进程数据存储到磁盘上一个专门保留的空间——页面文件中。
重要提示
数据按页面逐页加载到页面文件中,每页大小为 4 千字节(KB),因此数据可以占据连续区域以及页面文件的不同部分。因此,在分析过程中,您可以同时使用文件雕刻和字符串搜索。此外,Windows 在运行时仅在内存中跟踪页面文件条目及其与特定进程的关系,因此无法在页面文件分析过程中恢复这种关系。
交换文件和页面文件的主要区别在于,交换文件存储来自 Microsoft Store 应用程序(以前称为 Metro 应用程序)的数据。它存储那些当前不需要,但在切换应用程序或从动态磁贴打开应用程序时可能需要的数据,这些数据存储在 pagefile.sys 中。
获取页面文件
默认情况下,页面文件是启用的,因此您无需手动创建它。此外,系统中可能会有多个此类文件,它们不一定位于根目录。要查找分页文件,您需要检查 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management 注册表项中的 ExistingPageFiles 和 PagingFiles 值。这可以通过在在线机器上使用注册表编辑器,或通过分析从取证映像中获得的 SYSTEM 注册表文件来完成,如下图所示:

图 6.13 – SYSTEM 注册表文件中的 ExistingPageFiles 和 PagingFiles 值
一旦检查了分页文件的数量和位置,您可以像提取休眠文件一样提取它们,如下所示:

图 6.14 – 页面文件提取
此外,一些工具允许您在创建内存转储的同时创建页面文件的副本。回顾 FTK Imager 转储创建过程;在那里,您可以通过启用 包含页面文件 复选框来捕获页面文件,如下图所示:

图 6.15 – FTK Imager 包含页面文件
这将创建两个文件:一个内存转储文件和一个页面文件的副本。
一旦你成功提取了页面文件,就可以开始分析它了。
分析 pagefile.sys
分析页面文件有不同的方法。我们将尽量详细阐述一些最重要的方法,以便你可以选择最适合你调查目标的方法。
重要说明
从 10525版本开始,Windows 10 使用页面文件压缩。这意味着你需要先解压页面文件才能进行分析。你可以使用 Maxim Sukhanov 开发的winmem_decompress工具来实现这一目的(github.com/msuhanov/winmem_decompress)。
一些工具——例如 MemProcFS——允许联合分析内存转储、页面文件和交换文件。为此,-pagefile0...9选项会添加到-device选项中。页面文件的默认值为 0;而交换文件则是 9。下面展示了运行 MemProcFS 的一个示例:

图 6.16 – 联合分析内存转储与相应页面文件
在这种情况下,页面文件中的数据将补充内存转储中的数据,但在这种情况下更容易遗漏特定信息。因此,最好使用独立工具来分析页面文件。
我们之前已经提到,页面文件中的数据是以 4 KB 的块存储的。由于这些块可能占据文件的不同部分,而且很难获得数据内容的结构化表示,因此页面文件分析不会很直接。因此,开始分析页面文件的最佳方法之一是查找字符串。
字符串搜索
分析页面文件最简单的方法是查找特定的字符串。你可以使用你已经熟悉的Strings工具来提取给定文件中所有的 ASCII 和 Unicode 字符。运行该工具时,可以通过 PowerShell 和以下命令来执行:
PS D:\> .\strings64.exe .\pagefile.sys > D:\output.txt
输入是我们页面文件的路径,输出会重定向到一个文本文件,即 output.txt。在生成的文件中,像之前一样,我们可以使用关键词搜索,或者简单地检查输出,查看是否有与执行任何程序(可能是攻击者使用的程序)相关的字符串,如下图所示:

图 6.17 – 字符串输出
你可以在前面的截图中看到,Strings工具的分析结果检测到了一个HTTPS 反向 shell运行。
既然我们在谈论字符串搜索,自然不能忘记使用yara工具来帮助我们。这个工具的原理与 Volatility 的yarascan插件相同。你可以通过官方的 GitHub 仓库下载这个工具,链接为 github.com/VirusTotal/yara/。你可以在以下截图中看到 GitHub 页面:

图 6.18 – yara GitHub 仓库
页面右侧有一个指向最新版本发布的链接,这正是你需要的。在Releases页面,选择所需的版本,然后下载并解压包含可执行文件的档案。你可以使用 PowerShell 来运行它。要查看所有可用的选项,请运行以下命令,如下图所示:

图 6.19 – yara 选项
你可以使用来自公共来源的 YARA 规则,也可以编写自己的规则。我们来使用一个 YARA 规则来查找文件中的 URL。规则及其结果如下所示:

图 6.20 – yara 扫描结果
我们还可以通过 bulk_extractor 扩展搜索,查找域名、电子邮件、SQL 查询等,正如以下截图所示:

图 6.21 – bulk_extractor 执行
在这里,我们不仅能找到 IP 地址和域名,还能找到完整的 URL,如下所示:

图 6.22 – bulk_extractor URL 直方图
请注意 IP 地址。你可以随时在 VirusTotal 或任何你喜欢的资源上检查它们。如果你检查我们找到的其中一个地址,你将看到以下结果:

图 6.23 – VirusTotal 结果
VirusTotal 已检测到多个包含此 IP 地址的恶意文件。最好检查我们的页面文件是否包含此类文件。
文件切割
除了字符串搜索外,你还可以使用工具进行文件切割。你可以使用 PhotoRec 作为工具。此工具支持基于签名的搜索,可以识别超过 300 种文件类型,包括归档文件、图片、Microsoft Office 文件、PDF 文件等。
PhotoRec 可以和 TestDisk 工具一起从官方网站下载,网址是 www.cgsecurity.org/wiki/PhotoRec。为此,在页面右侧找到最新版本的链接并点击它。在打开的窗口中选择适当的版本,然后下载并解压档案。你需要一个名为 photorec 的可执行文件。
运行以下命令分析分页文件:
PS D:\> .\testdisk-7.2-WIP\photorec_win.exe D:\pagefile.sys
这将打开一个独立的窗口,如下所示:

图 6.24 – PhotoRec 媒体选择
按Enter继续,你将看到如下内容:

图 6.25 – PhotoRec 文件系统类型
由于我们的文件系统是新技术文件系统(NTFS),无需更改任何设置,直接再次按Enter。在接下来的窗口中,您需要选择保存结果的目录,如下图所示:

图 6.26 – PhotoRec 目标文件夹选择
在我们的例子中,output文件夹将用来保存雕刻结果。当指定了output目录时,必须按下C键开始。文件恢复过程将是这样的:

图 6.27 – PhotoRec 雕刻过程
雕刻过程需要一些时间,所以请耐心等待。最终,所有恢复的文件将出现在您选择的目录中,如下图所示:

图 6.28 – 雕刻结果
正如前面的截图所示,我们能够恢复大量的动态链接库(DLL)文件,以及一些文本和可执行文件。现在我们可以检查是否有包含我们之前检查过的 IP 地址的文件。我们可以使用 PowerShell 和Select-String命令,如下图所示:

图 6.29 – Select-String 结果
请注意我们检测到 IP 地址的文件的上下文和扩展名。该内容类似于防病毒解决方案用来查找恶意软件的签名。这是一个相当常见的情况,所以要小心。在这种情况下,该文件更可能是合法的;然而,仍然没有什么可以阻止我们检查其他文件是否含有恶意软件。例如,以下是检查其中一个恢复的库文件的结果:

图 6.30 – 恶意 DLL 检测
几个厂商已将我们的文件识别为恶意文件。这不能被忽视,因此可以对恢复的 DLL 文件进行更深入的分析。
正如你所看到的,分页文件也是一个很好的数据来源。你可能会找到不仅是有趣的 IP 地址、域名、部分电子邮件或 Shell 命令,甚至是完整的文件。所有这些数据将帮助你补充拼图中的缺失部分,完整事件的全貌。
现在,到了查看我们最新的替代来源——崩溃转储的时候。
分析崩溃转储
当系统进入不稳定状态时——例如,因无法正确处理的异常——会发生 Windows 崩溃。这是因为内核驱动程序或其他在内核级别运行的代码存在 bug。在这种情况下,Windows 会尝试保存与崩溃相关的信息,并可以用于调试。由于系统在崩溃期间处于不稳定状态,数据首先会写入分页文件,然后在下一次启动时转移到适当的转储文件中。根据系统配置,可以创建不同的崩溃转储。以下截图显示了 Windows 10 提供的转储格式:

图 6.31 – Windows 10 中的崩溃转储格式
让我们更仔细地看看这些格式,如下所示:
-
小型内存转储:这些文件在 32 位和 64 位系统中分别为 64 KB 和 128 KB。它们包含正在运行的进程、加载的驱动程序和错误检查信息。
-
内核内存转储:这些文件仅包含内核模式中的内存页面。因此,它们包含有关内核使用的内存的信息。通常,这种转储文件的大小大约为系统物理内存的三分之一。
-
完整内存转储:这些是最大的内核模式转储。它们包含崩溃时的物理内存的完整转储。未映射的内存不包括在内。
-
自动内存转储:此转储类似于内核内存转储。主要区别在于信息的存储方式。对于自动内存转储,Windows 会设置系统分页文件的大小。从 Windows 8 开始,这是创建崩溃转储的默认方法。
-
活动内存转储:此转储是在 Windows 10 中引入的,类似于完整内存转储,包含来自用户模式和内核模式的活动内存。然而,不太可能与主机计算机故障排除相关的页面将被过滤掉。
您可能会根据创建的转储类型获取不同数量的信息。要检查特定主机上创建了哪些崩溃转储,可以检查实时系统上的设置。为此,请转到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CrashControl 注册表键。要从法医映像中检索此数据,可以参考 SYSTEM 注册表文件,如下图所示:

图 6.32 – CrashControl 注册表键
CrashDumpEnabled 值定义了要创建的转储类型。在 Windows 10 上,以下值是可能的:
-
0:无 -
1:完整或活动内存转储 -
2:内核内存转储 -
3:小型内存转储 -
7:自动内存转储
请注意,在此处,您还可以找到创建崩溃转储的路径。默认情况下,这是 %SystemRoot%\MEMORY.DMP 文件。
除了系统崩溃外,某些特定应用程序发生问题并且系统保持稳定的情况也可能发生。在这种情况下,会创建包含错误代码、应用程序和主机详细信息的迷你崩溃转储。这些转储由 C:\ProgramData\Microsoft\Windows\WER 生成。WER 还可以配置为创建用户模式进程的完整内存转储。为此,在 HKLM\Software\Microsoft\Windows\Windows error reporting 注册表项中创建一个 LocalDumps 键,并设置 DumpType 的值为 DWORD = 00000002。通过此设置,创建的用户进程转储将存储在出现错误的用户的 %LocalAppData%\Crashdumps 文件夹中,而系统进程的转储将存储在 C:\Windows\System32\config\systemprofile\AppData\Local\CrashDumps\ 文件夹中。
进程崩溃转储的分析在事件响应中尤其重要,因为恶意软件利用应用程序漏洞后,通常会导致该应用程序崩溃。分析应用程序崩溃转储可以告诉我们攻击者在初始访问中使用了哪些技术。
前面描述的所有文件都是系统在不同崩溃过程中创建的。你可以在取证镜像中搜索这些文件,并按前面描述的方式提取它们,就像休眠文件一样。
如果你正在处理一个实时系统,在必要时你可以自己创建这些文件。
崩溃转储创建
在开始创建崩溃转储之前,你需要确保已启用其创建功能。别忘了选择你想要的转储类型。你可以通过进入我的电脑 -> 系统和安全 -> 系统 -> 高级设置 -> 启动和恢复来完成这一步。准备好后,你就可以开始创建崩溃转储了。
模拟系统崩溃有不同的方式——例如,使用标准的 Windows 工具或Windows 调试器(WinDbg)。然而,最简单且最可靠的方式仍然是使用来自Sysinternals的NotMyFault工具。要使用此工具,只需从官方网站下载并解压缩存档,docs.microsoft.com/en-us/sysinternals/downloads/notmyfault。在存档中,你将找到适用于 32 位和 64 位系统的可执行文件。
系统崩溃模拟
以管理员身份运行notmyfault.exe。在弹出的窗口中,你将看到与系统崩溃最常见原因对应的选项,如下图所示:

图 6.33 – NotMyFault 主窗口
选择适合你的选项并点击MEMORY.DMP文件,这是一个崩溃转储文件。
对于应用程序转储则是另一回事。创建它们的过程更简单且更灵活,因为你可以使用标准的 Windows 工具,如任务管理器,或者第三方工具。让我们来看一下如何创建进程转储。
进程转储创建
让我们从内置工具开始——更具体地说,是任务管理器。
要转储进程,按Ctrl + Alt + Delete启动任务管理器。在弹出的窗口中,找到可疑进程并右键点击其名称。在弹出的菜单中,选择创建转储文件,如截图所示:

图 6.34 – 使用任务管理器创建进程转储
如果转储文件成功创建,你将看到如下窗口:

图 6.35 – 进程转储结果
在这里,你可以找到你创建的转储文件及其所在位置。正如你所见,这种方法易于使用,但不允许选择转储格式。另一个工具,Process Hacker(processhacker.sourceforge.io/downloads.php)可以以类似的方式使用。你可以在下图中看到该工具的使用场景:

图 6.36 – 使用 Process Hacker 创建进程转储
如果你想能够创建不同类型的进程转储,Sysinternals 还提供了另一个工具,叫做 ProcDump。顾名思义,这个工具专门用于创建进程转储。与 NotMyFault 一样,它可以从官方网站下载:docs.microsoft.com/en-us/sysinternals/downloads/procdump。这个工具支持下图所示的转储类型:

图 6.37 – ProcDump 支持的格式
正如你可能已经注意到的,你需要使用 PowerShell 来运行该工具。你可以通过任务管理器的 详细信息 标签页中的 PID 来指定要转储的进程,如下图所示:

图 6.38 – 识别 PID
要创建包含进程、线程、模块、句柄、地址空间和堆栈信息的小型转储,你需要使用 -mm 选项,而要创建完整转储,则使用 -ma 选项。效果如下所示:

图 6.39 – 小型转储和完整转储的创建
这些是你可以用来创建各种转储的工具。现在,我们来谈谈如何分析这些转储。
分析崩溃转储
由于系统崩溃和应用程序崩溃会创建不同的转储,因此一些分析方法会有所不同。让我们从分析系统崩溃时创建的转储开始。
系统崩溃转储
分析系统崩溃转储最直接的方法是使用 WinDbg。这个工具专为调试设计,不仅可以分析崩溃转储,还能帮助你找出崩溃原因。使用以下链接下载该工具:docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-tools。找到 从 Microsoft Store 下载 WinDbg Preview 选项,并点击 WinDbg Preview 链接。点击 GET,然后你将被重定向到 Windows Store。再次点击 GET 进行安装。
安装完成后,你可以启动 WinDbg。进入 文件 菜单,选择 打开转储文件,如下图所示:

图 6.40 – WinDbg 文件菜单
选择你的崩溃转储文件,加载完成后,使用命令行运行!analyze -v命令,如下所示的截图所示:

图 6.41 – WinDbg !analyze -v 命令
此命令允许你显示有关崩溃原因的详细信息,如下所示:

图 6.42 – WinDbg Bugcheck 分析
在这里,你可以找到例如有缺陷的驱动程序信息、异常错误和代码、故障 IP、失败 ID 哈希字符串等数据。
另一个可以进行类似分析的工具是BlueScreenView,由NirSoft公司开发 (www.nirsoft.net/utils/blue_screen_view.html),该工具在下方的截图中展示:

图 6.43 – NirSoft BlueScreenView
请记住,这个工具在处理实时系统上的小型转储时效果最佳,因此不适合用于事后分析。
还有另一种解决方案可以帮助你进行事后分析:SuperDump (github.com/Dynatrace/superdump)。它的主要优势在于可以自动化分析过程,并以图形报告的形式提供所有数据。该工具在下面的截图中展示:

图 6.44 – SuperDump
SuperDump 是一个自动化崩溃转储分析服务,提供 Web 界面以及REST(表现性状态转移)接口来上传 Windows 崩溃转储。此外,它还允许你分析 Linux 核心转储。不过,要运行该工具,你需要安装 Docker。
现在,你已经拥有了几种用于系统崩溃转储分析的工具。你可以选择最适合你操作的工具。接下来我们将进入更有趣的内容:进程转储分析。
进程转储分析
进程转储分析是调查单个可疑进程的绝佳方式,而无需创建完整的内存转储。此技术在事件响应过程中常常被使用。
调试器自然可以用于分析进程转储,但也可以应用更经典的方法——例如,字符串搜索或基于 YARA 规则的搜索。在这里,使用bulk_extractor进行分析也是可行的。
让我们考虑一个关于可疑进程explorer.exe的转储分析示例。我们从Strings工具开始。我们将使用标准命令,如下所示:
PS D:\> .\strings64.exe .\explorer.exe_210813_000718.dmp > D:\explorer.txt
生成的文本文件可以通过关键字进行搜索。在我们的案例中,通过搜索cmd关键字,我们找到了恶意软件执行的命令,如下所示的截图所示:

图 6.45 – Strings 输出中的恶意 cmd 命令
bulk_extractor 也会非常有用。我们可以通过以下命令找到恶意软件使用的 IP 地址和域名:
PS D:\> .\bulk_extractor.exe -o D:\output\ .\explorer.exe_210813_000718.dmp
扫描结果如下所示:

图 6.46 – bulk_extractor 域名直方图
检查这些 IP 地址后发现,许多与恶意文件相关,如下所示:

图 6.47 – 来自 bulk_extractor 输出的 IP 地址
最后,我们回到 Strings 工具的结果。搜索关键字 exe 也得到了极其有用的信息,如下所示:

图 6.48 – 检测恶意文件
在这种情况下,我们可以看到恶意软件使用的目录名称,以及可执行文件和库的名称。使用新的关键字让我们发现了更多与恶意活动相关的数据,如下所示:

图 6.49 – yrpoykg 关键字搜索
如你所见,一些分析技术对整个内存转储和单个进程的内存转储都非常有效。
总结
分析 Windows 内存转储是一个耗时的过程,但可以产生非常宝贵的结果。除了检查完整的转储外,你还不应忽视其他来源,它们在法医调查和事件响应中也能提供很大的帮助。
替代来源包括休眠文件、页面文件和交换文件,以及崩溃转储和进程内存转储。部分文件,如页面文件和交换文件,是默认启用并在操作系统运行时自动创建的。其他文件则在系统进入特定状态时创建——例如,当系统进入休眠模式时,会创建休眠文件。后者的崩溃转储在系统崩溃或应用程序崩溃时生成,但你也可以人为触发这些状态。除此之外,还有一些特殊工具,可以在不直接影响进程状态的情况下,创建独立的进程转储,例如进程内存转储。
对于替代来源的分析,可以使用调试器等特殊工具,或是允许你通过字符串、正则表达式、YARA 规则和签名搜索的通用工具。
在这一点上,我们完成了对 Windows 内存的分析。尽管这个系统多年来一直是桌面操作系统市场的领导者,但其他系统如 macOS 和 Linux 正逐年变得越来越受欢迎。现在是时候谈论它们的分析了。在接下来的部分中,我们将详细讲解如何创建 Linux 内存转储,并继续进行其分析。像往常一样,我们将介绍 Linux 数字取证调查中使用的关键技术和工具,并附上我们实践中的示例。下部分见!
第三章:Linux 取证分析
本章将重点讨论 Linux 内存获取与分析的相关内容。将详细介绍从 Linux 取证角度跟踪用户操作、以及检测和分析恶意软件的过程。
本书本章包含以下内容:
-
第七章,Linux 内存获取
-
第八章,用户活动重建
-
第九章,恶意活动检测
第七章:Linux 内存获取
尽管 Windows 是最常见的桌面操作系统,但 Linux 系统的角色不容忽视。由于其灵活性,基于 Linux 的操作系统可以安装在各种硬件上:个人电脑、平板、笔记本、智能手机和服务器。尤其在企业环境中,后者的应用尤为重要。
运行 Linux 操作系统的服务器是基础设施的重要组成部分,因为它们常常作为网页、邮件、应用程序、数据库和文件服务器的基础。因此,攻击者每年对这些主机的兴趣与日俱增。涉及 Linux 系统的攻击数量每年稳步增长。越来越多的团体,无论是国家支持的还是出于财务动机的团体,都在其武器库中拥有基于 Linux 的工具和恶意软件。例如,臭名昭著的 Fancy Bear APT 曾被美国国家安全局和联邦调查局劝说使用一种先进的 Linux rootkit,名为Drovorub。另一个很好的例子是多个勒索病毒运营商——所有主要的勒索病毒即服务程序现在都为其加盟商提供 Linux 版本。
所有这些都引出了掌握分析基于 Linux 的系统所需工具和技术的必要性。这将是本书这一部分的主要讨论内容。
就像之前做的一样,收集所需的数据至关重要。在我们的案例中,这涉及到创建内存转储。这将是我们开始讨论这一主题的地方。
本章将涵盖以下主题:
-
理解 Linux 内存获取问题
-
准备 Linux 内存获取
-
使用 LiME 获取内存
-
使用 AVML 获取内存
-
创建 Volatility 配置文件
理解 Linux 内存获取问题
在第二章《获取过程》中,我们讨论了通用的内存转储问题,这些问题在基于 Linux 的系统中也同样适用。然而,创建 Linux 内存转储的过程也有一些特有的问题,这些问题是这些系统特有的。这些就是我们将重点讨论的问题。
专业人员在进行内存转储时遇到的主要难题是分发版的数量。由于 Linux 内核是开源的,并且根据 GNU 通用公共许可证进行分发,它迅速在社区中获得了普及,成为了许多分发版的基础,每个分发版都有其自己的特点。自然,这对内存提取过程产生了影响。
在 Linux 2.6 之前的较早版本内核中,可以通过 /dev/mem 和 /dev/kmem 设备访问内存。/dev/mem 接口允许程序以 root 权限访问物理内存进行读写操作,而 /dev/kmem 则允许访问内核的虚拟地址空间。因此,要创建一个原始内存转储,仅需使用简单的 cat 或 dd 工具读取 /dev/mem 并将输出重定向到一个单独的文件中。这种方法无疑非常方便,但也带来了明显的安全问题。例如,由于从物理偏移量 0 开始的非顺序内存映射,缺乏经验的技术人员可能会直接访问敏感的内存区域,导致系统不稳定、内存损坏或系统崩溃。
在较新版本的 Linux 内核中,之前描述的接口已被禁用。现在,物理内存需要通过加载一个特殊的内核模块来访问。最大的挑战在于,必须在目标系统或具有匹配发行版和内核版本的系统上构建此内核模块,才能正常工作。显然,不建议在目标系统上构建模块,因为它需要许多依赖项,而安装这些依赖项可能会覆盖重要数据。因此,如果使用需要加载内核模块的工具,最好在测试环境中构建这些模块。
有许多不同开发者提供的工具可以用于内存提取。在本章中,我们将集中介绍最方便有效的 Linux 内存转储工具,但首先,让我们来看看准备过程。
准备 Linux 内存获取
由于一些常用的 Linux 内存提取工具需要加载内核模块,因此需要在与真实环境相似的环境中构建该模块。为此,你可以在准备好的虚拟机上构建模块。你可以使用 VMWare、VirtualBox 或其他类似的解决方案创建这样一台虚拟机。最重要的是,在虚拟机上安装与目标主机相同的操作系统发行版和内核版本。因此,准备虚拟环境的第一步是确定目标主机的发行版和确切的内核版本。要确定发行版,请在目标主机的终端中运行以下命令:
$ cat /etc/*-release
要获取确切的内核版本,请运行以下命令:
$ uname -r
你应该得到以下输出:

图 7.1 – 目标发行版和内核版本
我们现在知道目标主机上安装的是 Ubuntu 21.04,内核版本是 5.11.0-34-generic。这些信息可以用于创建虚拟机。由于大多数发行版都是免费提供的,你应该不会遇到找不到合适版本的问题。内核版本也是如此。或者,如果你已经有了一个带有正确发行版和更新内核的虚拟机,也可以选择进行内核降级。
你还需要准备可移动存储介质以便转储内存。我们已经在第三章中讲解过这个过程,Windows 内存获取,所以这部分我们就不再详细讲解。如果你打算通过网络捕获内存转储,你需要准备一个网络共享,并确保目标主机能够访问。在本章中,我们将同时探讨这两种捕获转储的方法。与此同时,我们将开始讨论具体的工具。
使用 LiME 获取内存
我们将首先介绍的工具是Linux 内存提取器,或称LiME。LiME 是一个可加载的内核模块,使得从 Linux 及基于 Linux 的系统(包括 Android)中提取内存成为可能。这个工具的主要优点是它对进程的占用非常小,并且可以计算转储内存的哈希值。LiME 还能够通过网络创建转储。这个工具可以在以下 GitHub 仓库中找到:github.com/504ensicsLabs/LiME。以下是 LiME 的截图:

图 7.2 – LiME GitHub 仓库
我们从构建内核模块的过程开始。为此,我们将使用与目标主机相同的发行版和内核版本的虚拟机——分别是 Ubuntu 21.04 和 5.11.0-34-generic。
由于我们正在使用 Linux,我们将通过终端进行所有操作。首先,我们需要安装 LiME 及所有必需的包。为此,请使用以下命令:
sudo apt-get install -y linux-headers-$(uname -r) build-essential make gcc lime-forensics-dkms
命令的执行过程如下所示:

图 7.3 – 包安装
一旦这个过程完成,我们就可以进入下一步:编译。为此,使用 cd 进入 lime 目录并运行 make,如下所示:

图 7.4 – 内核模块创建
make 是一个工具,用于自动化将文件从一种形式转换为另一种形式的过程。转换规则本身是在一个名为 Makefile 的脚本中定义的,该脚本位于工作目录的根目录——在我们的例子中是 /usr/src/lime-forensics-1.9.1-2。
一旦 make 执行完毕,我们将得到一个名为 lime-5.11.0-34-generic.ko 的内核模块。我们可以将其复制到可移动存储介质或网络共享上,并用它来转储目标主机上的内存。
让我们来看一下通过网络创建转储的过程。首先,我们需要使内核模块文件在目标主机上可用。这可以通过将其放置在网络共享中,或使用scp将其复制到目标主机来完成,scp是一个允许在两个位置之间(包括远程位置)安全地复制文件和目录的工具。当模块可用时,你可以使用insmod来加载内核模块。此操作需要通过路径参数指定输出文件的位置和名称,并且需要在格式参数中指定文件格式——例如raw、lime等。由于我们决定通过网络创建转储,因此我们将通过path参数传递要使用的协议和将从中发送输出的端口:
$ sudo insmod ./lime-5.11.0-34-generic.ko "path=tcp:4444 format=lime"
该命令将加载内核模块,创建内存转储,并将其发送到4444端口。请注意文件的格式。如果你希望所创建的内存转储能够被 Volatility 识别,最好以lime格式创建。
然后,你需要在调查员的主机上运行netcat。Netcat或nc是一个命令行工具,能够通过 TCP 或 UDP 协议读取和写入网络连接上的数据。你还需要将输出重定向到一个文件。可以按以下方式进行:
$ nc 192.168.3.132 4444 > mem.lime
在这种情况下,netcat将从192.168.3.132 IP 地址接收数据并写入mem.lime文件。最后,可以使用以下命令卸载内核模块:
$ sudo rmmod lime
结果生成的mem.lime文件可以用于分析,但我们稍后再详细讲解。现在,让我们看看另一个用于创建内存转储的工具。
使用 AVML 获取内存
AVML,即获取 Linux 的易失性内存,是微软开发的用户态获取工具。AVML 的主要优点是,它不需要在目标主机上构建,并且支持多种来源:
-
/dev/crash -
/proc/kcore -
/dev/mem
如果在运行 AVML 时没有指定特定的源,该工具将会遍历所有源,寻找有效源并从中收集内存。
这个工具的缺点可能是,它只在有限数量的发行版上进行了测试,因此最好先在虚拟环境中进行检查,然后再使用。
在编写本书时,以下发行版已经过测试:
-
Ubuntu:12.04,14.04,16.04,18.04,18.10,19.04,19.10
-
Centos:6.5,6.6,6.7,6.8,6.9,6.10,7.0,7.1,7.2,7.3,7.4,7.5,7.6
-
RHEL:6.7,6.8,6.9,7.0,7.2,7.3,7.4,7.5,8
-
Debian:8,9
-
Oracle Linux:6.8,6.9,7.3,7.4,7.5,7.6
因此,你需要做的第一件事是下载该工具。为此,打开 GitHub 上的仓库页面:github.com/microsoft/avml,并转到Releases标签页。

图 7.5 – AVML GitHub 仓库
找到 AVML,下载它,并将其放到可移动媒体或网络共享中,这样你就可以在目标主机上运行它。这次我们将使用可移动媒体。在运行之前,你需要使用chmod命令使文件可执行,chmod命令可以让你更改文件和目录的权限:
$ sudo chmod 755 avml
接着,你可以开始创建内存转储。只需运行 AVML 并指定输出文件的位置和名称。结果将生成以下输出:

图 7.6 – AVML 使用示例
请注意,AVML 不要求构建内核模块。命令完成后,你将获得一个 LiME 格式的内存转储,准备进行分析。然而,注意 Volatility 没有为基于 Linux 的系统提供预构建的配置文件。考虑到这一点,我们还应该讨论如何为 Volatility 创建一个配置文件。
创建 Volatility 配置文件
要分析 Linux 内存转储,你需要创建一个与目标主机配置相对应的 Volatility 配置文件。我们通过一个例子来考虑这个问题。首先,你需要安装zip和dwarfdump包,如下图所示:

图 7.7 – dwarfdump 和 zip 安装
接下来,我们需要下载 Volatility。为此,我们将使用git clone命令,它允许我们从 GitHub 克隆仓库。如果你没有git,需要使用apt安装它:
$ sudo apt-get install git
$ git clone https://github.com/volatilityfoundation/volatility.git
之后,你应该进入volatility/tools/linux目录并运行make命令:
$ cd volatility/tools/linux
$ make
列出的操作如下所示:

图 7.8 – 创建 dwarf 模块
结果,你将得到一个module.dwarf文件。
重要提示
根据你所使用的发行版,执行make可能会导致各种错误,从依赖问题到许可证问题。遗憾的是,没有一种通用的解决方案可以解决所有问题,但在网上查找有关make错误的解决方案可能会有所帮助。
生成的dwarf模块必须与正确版本的System-map合并到一个归档中。可以使用以下命令完成此操作:
$ sudo zip $(lsb_release -i -s)_$(uname -r).zip ./module.dwarf /boot/System.map-$(uname -r)
让我们理解一下这里发生了什么:
-
lsb_release -i -s命令输出当前发行版的名称。 -
uname -r将显示内核版本。
这将把你的归档命名为<distribution>_<kernel>.zip,但你可以按需命名。
该命令的输出可能如下所示:

图 7.9 – 创建 Volatility 配置文件
如你所见,我们最终得到了Ubuntu_4.15.0-117-generic.zip归档文件,这是该主机的 Volatility 配置文件。你可以将这个文件放入配置文件夹,并将该路径作为--plugins选项传递给 Volatility 文件夹,如下图所示:

图 7.10 – 使用自定义 Volatility 配置文件
如你可能已经注意到的,收集 Linux 内存的过程并不简单,需要进行许多不同的操作。然而,在实践中,你经常会遇到安装在虚拟机中的系统。在这种情况下,你只需要创建虚拟机的快照,并简单地处理现有的.vmem文件。然而,这并不能让你免于创建 Volatility 配置文件。另一方面,如果你需要调查一个相当流行的发行版,你可以始终尝试在网上找到现成的配置文件。你可以从官方的 Volatility Foundation 仓库开始:github.com/volatilityfoundation/profiles/tree/master/Linux。
除了其他内容外,还有一些工具可以帮助你自动化之前的步骤。例如,Linux Memory Capturer(github.com/cpuu/lmc)是 Linux Memory Grabber 的一个分支,后者由 Hal Pomeranz 开发。这个工具允许你自动化创建 Linux 内存转储和 Volatility 配置文件的过程。你只需要安装并运行该工具。
由于此工具使用 LiME,你将被要求创建一个内核模块,其中包括模块本身和它生成的内存转储文件,二者都会保存在主机上。然后,你将被提示为 Volatility 创建配置文件。
输出是一个类似这样的文件夹:

图 7.11 – lmc 输出
在这里,你会找到以下内容:
-
hostname-YYYYY-MM-DD_hh.mm.ss-memory.lime:以 LiME 格式保存的内存 -
hostname-YYYYY-MM-DD_hh.mm.ss-profile.zip:Volatility 配置文件 -
hostname-YYYY-MM-DD_hh.mm.ss-bash:/bin/bash的副本 -
volatilityrc:Volatility 配置文件的原型
生成的内核模块可以在/usr/src/lime-forensics找到。你可以使用生成的模块在目标主机上创建内存转储,并使用 Volatility 配置文件进一步分析。
看起来不错吧?然而,目前,该工具使用的是 Python 2.7,这意味着你只能在有限的情况下使用它。此外,使用此类工具并不会解决之前提到的make问题。因此,在使用这些工具之前,最好在与目标机器配置相似的虚拟环境中进行测试。
概述
创建基于 Linux 的系统内存转储是一个繁琐的过程。你没有一款可以一键完成所有需求的工具。然而,存在一些相当高效的解决方案,正确使用时,它们能帮助你获取所需的一切。
不同的工具可能使用不同的方法来访问内存。最常见的方法是加载内核模块;然而,这种方法需要大量的准备工作,因为该模块必须在与目标主机相似的发行版和内核版本的系统上构建。创建 Volatility 配置文件也需要相同的条件,否则进一步分析转储将变得困难。
有几种脚本解决方案可以自动化创建内存转储和 Volatility 配置文件的过程,但这些解决方案通常只适用于有限数量的发行版,因此最好在类似于真实环境的条件下测试它们,然后再使用。
在本章中,我们回顾了允许你创建基于 Linux 系统的内存转储的工具。现在,到了讨论内存转储分析的时刻。这就是我们将在下一章中要做的。
第八章:用户活动重建
在取证调查和事件响应过程中,重建用户活动是从受害者和攻击者主机收集重要数据的关键部分。基于 Linux 的系统在这方面扮演着重要角色,因为攻击者常常使用它们进行活动。这是因为许多不同的网络和漏洞扫描器、Web 应用程序安全测试工具以及后渗透框架都是在 Linux 下实现的。因此,调查攻击者使用的主机能够为我们揭示有关攻击中使用的工具和技术的详细信息。此外,通过检查用户活动,我们可以了解攻击准备的各个阶段、可能的合作伙伴、在不同论坛上的活动等。
基于前面的内容,我们需要考虑以下主题:
-
调查已启动的程序
-
分析 Bash 历史
-
搜索最近的文件
-
从内存中恢复文件系统
-
检查浏览历史
-
调查通信应用程序
-
寻找挂载的设备
-
检测加密容器
技术要求
这次,我们将使用 Linux 和 Windows 系统来操作接下来两章中描述的工具,并执行 Linux 内存取证。在我们的案例中,Volatility 2.6.1 和一些内置实用工具将在 Ubuntu 21.04(Hirsute Hippo)上运行,而像 Bulk Extractor 或 PhotoRec 这样的程序将在 Windows 上运行。
调查已启动的程序
在上一章中,我们已经讨论了为基于 Linux 的系统创建配置文件的过程,因此现在我们将只检查你可用的配置文件。
假设你已经创建了一个配置文件,并将其放置在配置文件文件夹中。别忘了,你需要使用 --plugins 选项传递此文件夹的路径。为了检查你的配置文件是否可用,你可以运行 --info。为了只获取必要的输出,我们使用 grep,这是一种命令行实用工具,允许我们在输入中查找与给定正则表达式匹配的行并打印出来:

图 8.1 – Volatility 中的 Linux 配置文件
如你所见,我们可以使用多个 Ubuntu 配置文件以及一个 Debian 配置文件。类似地,我们还可以看到所有可供这些配置文件使用的插件列表:

图 8.2 – Volatility 中的 Linux 插件
现在我们已经确保我们拥有所需的一切,可以开始分析了。像 Windows 一样,我们将从调查活动进程开始,这将告诉我们用户正在运行哪些程序。
Volatility 为基于 Linux 的系统提供了 pslist 和 pstree 等效插件。这些插件也适用于活动进程列表,并允许我们查看这些信息。我们可以使用 linux_pslist 插件:

图 8.3 – 活跃进程列表
该插件的输出将会相当长。这是因为 Linux 系统使用相同的内核结构来存储进程信息,就像它们存储内核线程信息一样。因此,该插件的输出将包含进程和内核线程。后者可以通过缺少 DTB 来识别。
重要提示
DTB 是用于从进程地址空间读取数据的进程目录表基址的物理偏移量。由于内核线程使用内核地址空间,因此它们没有 DTB。
注意,输出中还有一个 Uid 列,它对应用户 ID。通过这个列,你可以筛选出特定用户的信息。我们来看看由 ID 为 1000 的用户启动的进程。为此,我们只需要使用 grep 工具:

图 8.4 – 特定用户启动的进程
我们现在可以看到,在 Uid 列中所有值为 1000 的行都属于同一用户。我们可以更仔细地查看这些输出:

图 8.5 – 用户进程
在这里,我们已经看到一些熟悉的名字。例如,我们可以推测,ID 为 1000 的用户曾打开了终端、nano、Thunderbird、LibreOffice 等。我们也希望能获取更多关于该用户的信息。
通常,用户信息可以在 /etc/passwd 文件中找到,但如果我们手头只有内存转储,访问该文件可能会有些困难。不过,我们或许可以看到与启动这些进程相关的环境信息。为此,我们可以使用 linux_psenv 插件。让我们运行这个插件并指定一个 ID 为 23639 的 bash 进程:

图 8.6 – 进程环境变量
请注意,用户名出现在该进程的环境变量中。我们现在知道,我们检测到的程序是由 itsupport 用户启动的。
不过,让我们回到正在运行的进程。除了标准的 pslist 和 pstree 插件外,我们还有另一个有趣的插件可用,它允许我们查看正在运行的程序的名称、位置以及启动时传递给它们的参数。这个插件叫做 linux_psaux。让我们来检查一下:

图 8.7 – Volatility linux_psaux
如你所见,我们再次使用了 grep 来获取与特定用户关联的进程信息。现在我们得到了关于正在运行的程序的位置以及传递给它们的参数的所有数据。这些信息为什么有用呢?让我们看看以下图示:

图 8.8 – 命令行中的文件名
在这里,我们不仅可以看到用户运行的程序,还可以看到与之一起打开的文件。例如,现在我们知道用户不仅仅是在运行 Libre Office,而是在运行 calc,这是 Linux 上类似 Excel 的程序,并且打开了 clients.xls 文件。我们还可以看到,nano 被用来处理位于桌面上的 passwords.txt 文本文件。
重要说明
由于 linux_psaux 显示的是启动时的参数,您可能无法从这里获取有关程序打开的所有文件的信息。您可以使用另一种方法来检索这些信息,稍后将讨论。
您可能已经注意到,我们的用户不仅积极使用图形界面程序,还与终端进行交互。这是 Linux 系统用户的常见情况,因此执行命令的分析成为用户活动调查的重要组成部分。
分析 Bash 历史记录
在 Linux 系统中,最常用的 Shell 是 Bash,它是最流行的 Unix Shell 之一。它受欢迎的原因之一是它在绝大多数 Linux 发行版中预装。同时,Bash 功能非常强大,可以交互式地执行许多命令和脚本、操作文件系统、重定向命令的输入和输出等。
通常,如果启用了 Bash 历史记录日志,它会存储在用户的主目录中的 .bash_history 文件里。当然,攻击者可能会对这个文件以及历史记录日志过程进行各种操作,以隐藏他们的痕迹。然而,我们仍然可以尝试从内存中恢复这些信息。Volatility 提供了一个专门的插件 linux_bash 来进行此操作。运行该插件的方式如下:

图 8.9 – Bash 历史记录
如您所见,在我们的例子中,用户首先尝试使用 cat 输出密码文件的内容,然后用 nano 打开它,但显然该文件不在桌面上,因此用户用 touch 命令创建了该文件。随后,进行了网络检查,使用 ping 并通过 apt 安装了 Git。显然,当威胁行为者在主机上操作时,Bash 历史记录分析具有特别的重要性。让我们来看一下以下示例:

图 8.10 – 攻击者主机上的 Bash 历史记录
在这里,我们看到攻击者的主机上安装并运行了后渗透框架 Metasploit,以及网络扫描工具 Nmap。我们还看到了 rockyou.txt 文件,并可以推测这是常用的密码字典之一,用于暴力破解。
因此,检查攻击者主机上的 Bash 历史记录可以揭示有关使用的工具和应用的技术,而受害者主机上的 Bash 则能告诉我们攻击中使用的工具,以及攻击者关注的具体文件或系统。
请注意,这不是我们第一次遇到打开某些文件。让我们更仔细地看看如何获取用户正在使用的文件的信息。
搜索已打开的文档
不幸的是,基于 Linux 的系统没有与 Windows 相同级别的信息记录。尽管如此,仍然可以找到有关特定文件的信息,甚至尝试从内存中恢复其内容。但首先要有条不紊。
您已经知道,可以使用linux_psaux或linux_bash插件查看程序启动时打开的文件。如果您对程序运行时打开的文件感兴趣,可以使用linux_lsof插件,通过-p选项传递您感兴趣的进程的 ID。让我们尝试查找itupport用户的soffice.bin进程打开的xls文件的信息。为了搜索特定类型的文件,我们将使用grep:

图 8.11 – 在 LibreOffice 中打开的文件
输出显示,在我们的情况下,LibreOffice 只连接到一个文件,cliens.xls。了解这个文件的内容也是很好的。Volatility 提供了一种机制来查找最近使用过的文件并导出它们。事实上,基于 Linux 的系统会缓存从磁盘读取和写入的文件数据。Volatility 允许您使用linux_find_file插件列出和恢复这些文件。让我们从列出在内存中缓存的文件开始。为此,应使用-L选项。由于列表相当长,我们建议将其保存到文件中,如图 8.12所示:

图 8.12 – 缓存文件列表
从输出中,您可以看到这里可以找到有关使用的目录和文件的信息,以及它们的inode编号和地址。
重要提示
inode或索引描述符是一种存储有关标准文件、目录或其他文件系统对象的元数据的数据结构,除了数据和名称本身。
或者,如果您想快速检查内存中的文件,可以使用-F选项,后跟您要查找的文件的名称或位置。如果找到文件,您将看到其位置和inode信息。
利用这些信息,我们可以尝试提取找到的任何文件。为此,我们可以使用-i选项,之后应指定所需的inode。在这里,我们还应使用-O选项指定输出文件的路径。文件搜索和提取将如下所示:

图 8.13 – 文件提取
正如你所看到的,我们首先找到了感兴趣的文件,然后使用其inode将数据文件提取到磁盘上。但这并不是inode给我们的所有可能性。让我们深入了解一下。
恢复文件系统
除了检索单个文件外,Volatility 还提供了恢复在创建转储时存储在内存中的文件系统部分的能力。这正是由于存储在inode中的大量元数据而变得可能。可以使用linux_recover_filesystem插件来进行文件系统恢复:
$ vol.py --plugins=profiles -f /mnt/hgfs/flash/ubuntu_11.05.58.lime
--profile=Linuxubuntu_18_04_5_4_0-84-genericx64 linux_recover_filesystem -D /mnt/hgfs/flash/recover_fs/
请注意,这里我们添加了-D选项,指定我们要保存要恢复的文件系统的目录。在我们的情况下,它将保存在recover_fs文件夹中。插件的结果将如下所示:

图 8.14 – 恢复的文件系统
在这里,您可以看到已恢复的标准目录以及一个swapfile,这是 Linux 中与 Windows 的pagefile相当的文件。您可以使用类似的工具,如 strings 或 Bulk Extractor,以类似的方式分析此文件。
一般来说,Linux 发行版中使用的文件系统具有类似的层次结构。根目录是/,然后是/bin/、/boot/和/etc/等标准目录,以及其他目录:

图 8.15 – Linux 目录层次结构
事实上,大多数 Linux 发行版遵循文件系统层次结构标准描述的一般规则。
重要提示
文件系统层次结构标准(FHS)由 Linux 基金会维护。它定义了 Linux 发行版中的目录结构和目录内容。
因此,每个目录都有其自己的目的,并存储特定内容。以下是关键目录的列表:

图 8.16 – 标准目录
因此,使用恢复的文件系统,您可以尝试查找感兴趣的用户文件或处理系统文件,如~/.bash_history和/etc/passwd,或系统日志。在进行取证调查或应对事件时,以下是一些您可能感兴趣的文件:
-
/etc/os-release– 操作系统信息 -
/etc/passwd– 关于用户、其uid、guid、主目录和登录 shell 的信息 -
/etc/group– 关于组及其成员的信息 -
/etc/sudoers– 关于特权分离的信息 -
/var/log/syslog– 来自不同程序和服务的消息,包括内核模式,但不包括认证消息 -
/var/log/auth.log– 认证消息 -
/var/log/error.log– 错误消息 -
/var/log/dmesg– 关于操作系统事件的一般消息 -
/home/<user>/.bash_history– bash 历史记录 -
应用程序日志文件
检查前述文件可以帮助您了解更多关于用户、启动的程序、执行的命令等内容。
重要提示
在从内存中提取文件系统时,Volatility 会尝试保留现有的文件时间戳。然而,ext4 之前的文件系统不存储文件创建信息。因此,linux_recover_filesystem 插件不会复制这些时间戳。
Volatility 还允许提取 tmpfs。可以使用 linux_tmpfs 插件来实现这一目的:

图 8.17 – Linux tmpfs 信息
使用 -L 选项运行它会列出所有可供提取的超级块,并且使用 -S 和 -D 选项,您可以将它们保存到磁盘。
重要提示
Tmpfs 是许多类 Unix 操作系统中的临时文件存储工具,驻留在内存中。在 Linux 中,从版本 2.4 开始支持 tmpfs。它用于存储包含临时数据的目录,这些数据会在系统重启时被删除:/var/lock、/var/run、/tmp 等等。Tmpfs 还可以托管在重启之间存储数据的目录,例如 /var/tmp,或用于特定程序(如浏览器)的缓存目录。
恢复内存中文件的另一种方法是使用已熟悉的 PhotoRec 工具。我们来看一下如何操作。首先,您需要通过 PowerShell 使用以下命令运行 PhotoRec:
PS D:\> .\testdisk-7.2-WIP\photorec_win.exe .\ubuntu_11.05.58.lime
接下来,确认我们是否要处理指定的文件:

图 8.18 – 输入文件确认
在下一个窗口中,选择所需的分区并按 Enter:

图 8.19 – 分区选择
由于基于 Linux 的系统通常使用 ext 文件系统,我们需要为正确的文件雕刻指定该类型:

图 8.20 – 文件系统选择
在下一个窗口中,选择您希望保存恢复文件的目录。在我们的案例中,这是 photorec output 目录:

图 8.21 – 输出目录
在最后一个窗口,按 Shift + C 开始恢复过程:

图 8.22 – 恢复过程
当过程完成时,您将看到恢复的文件总数,并能够在您之前指定的目录中找到这些文件:

图 8.23 – PhotoRec 恢复结果
在这里,您可以搜索您感兴趣的扩展名的文件并进行分析。
如果这种方法也无法提供您想要的结果,您可以直接在进程的内存中搜索内容。这就是我们将在下一部分讨论的内容,我们将以浏览器历史记录调查为例。
检查浏览历史
在基于 Linux 的系统上,与 Windows 一样,大多数流行的浏览器将其数据存储在 SQLite 数据库中。例如,Firefox 将其历史记录存储在位于/home/user/.mozilla/firefox/*.default-release中的places.sqlite文件中,而 Chrome 将其历史记录存储在位于/home/user/.config/google-chrome/Default中的history文件中。如果您在文件系统恢复过程中成功检索到这些文件,那就太好了。但当然,情况并非总是如此。如果您没有标准的历史记录文件,您将不得不在进程内存中搜索有关访问资源的信息。在某种程度上,这种方法甚至更加灵活,因为它允许您获取有关访问的网站的数据,而不受使用的浏览器和历史记录存储格式的限制。
访问单个进程内存的过程不像在 Windows 中那样直接。举个例子,让我们再次看看在我们的主机上运行的进程列表:

图 8.24 – Firefox 在活动进程列表中
这是具有12909 ID 的 Firefox 进程。在 Kernel 版本 3.6 之前,可以使用linux_route_cache插件检索通过浏览器访问的站点的信息,但在更新版本中,路由缓存被禁用,因此我们将拆分一个更通用的方法来查找我们感兴趣的信息。更具体地说,我们将尝试查看我们的 Firefox 进程的内存。
与 Windows 不同,我们无法导出整个进程内存。在运行时加载器将所有需要的东西(如可执行文件、共享库、堆栈、堆等)映射到进程地址空间的不同区域。我们可以使用linux_dump_map插件提取这些映射:

图 8.25 – Firefox 内存
如您所见,使用此插件时,每个映射都保存到单独的文件中。但我们仍然可以使用strings等工具来搜索这些信息。为了避免逐个处理每个文件,我们可以使用以下简单脚本:
for file in <dir>
do
strings "$file" >> <output>
done
在我们的情况下,它将如下所示:

图 8.26 – 运行多个文件上的字符串脚本
这将为/mnt/hgfs/flash/firefox中的每个文件运行strings,并将结果添加到firefox_strings.txt中:

图 8.27 – 字符串输出
通过正则表达式搜索,很容易找到我们访问的 URL 和用户的搜索查询。
另一种查找这些信息的方法是使用已经熟悉的 Bulk Extractor。我们将使用 Windows 来运行它,但首先我们将把所有文件合并成一个,以便 Bulk Extractor 可以处理它们。为此,我们将使用一个 PowerShell 脚本:
> Get-ChildItem -Path D:\firefox -File -Recurse | ForEach-Object -Process {Get-Content -Path $_.FullName | Out-File -FilePath D:\firefox-result.vma -Append}
该脚本将 firefox 目录中每个文件的内容添加到 firefox-result.vma 共享文件中。当收到共享文件后,我们可以开始解析。我们使用常规选项:
-
-o– 指定输出文件夹 -
-x– 禁用所有插件 -
-e– 启用电子邮件扫描器以搜索 URL
生成的启动界面如下所示:

图 8.28 – Bulk Extractor 执行
当解析完成后,你可以在输出文件夹中查找结果。例如,在 url_histogram.txt 文件中,我们可以提取出感兴趣的链接:

图 8.29 – 解析结果
请注意,即便是像 DuckDuckGo 这样的搜索引擎信息,也能通过内存分析被捕获,尽管它非常注重用户的匿名性和隐私。
这种类型的分析可以应用于任何进程。具体来说,你可以对与通信相关的应用程序进行进程内存分析,以查找你感兴趣的数据——对话、发布内容等等。这正是我们将要讨论的内容。
调查通信应用
除了各种浏览器,基于 Linux 的桌面操作系统还支持大量通信应用程序——即时通讯工具、邮件客户端、聊天室等。自然,这些应用程序所包含的信息可能对我们有用,特别是当它们是由攻击者托管时。
如前所述,分析这些应用程序与分析浏览器的方式不会有太大不同,因为我们将处理的是进程内存。让我们来看一个例子。我们已经看到目标主机上有一个 ID 为 51825 的 Thunderbird 应用。现在我们来转储它的内存,就像之前我们对 Firefox 所做的那样:

图 8.30 – Thunderbird 内存
我们现在可以使用之前的脚本从转储的文件中提取所有可读的行:
$ for file in /mnt/hgfs/flash/thunderbird/*; do strings "$file" >> /mnt/hgfs/flash/thunderbird_strings.txt; done
一旦执行,我们将得到一个大的文本文件。可以手动浏览,或通过关键词或正则表达式进行搜索。无论哪种方式,你都能够找到例如来自社交网络和服务的不同通知,这将让你了解用户有哪些账户和服务,他们感兴趣的内容是:

图 8.31 – 来自社交网络的电子邮件
当然,你也可以找到正常对话的部分,附件名称,发件人地址等:

图 8.32 – 对话部分
通过这种简单的方法,你可以发现很多有关用户的有趣信息。但是现在,让我们继续。我们下一个讨论的话题是已挂载的设备。
查找已挂载的设备
在 Linux 操作系统上,用户有能力挂载设备和特定的文件系统。分析这些信息可以帮助我们识别不仅是挂载到主机的单个设备和文件系统,还可以恢复它们挂载的相对时间线。
Volatility 的 linux_mount 插件可以用于查找有关已连接设备和文件系统的信息:

图 8.33 – 挂载的文件系统
正如你从截图中看到的,这个插件显示了所有挂载的设备和文件系统的信息,包括它们的位置、挂载点、类型和访问权限。细心的读者可能已经注意到,我们也谈到了时间线,但这里缺少这些信息。那么,我们该怎么办呢?
在这种情况下,内核调试缓冲区将帮助我们。内核调试缓冲区包含有关已连接 USB 设备及其序列号、混杂模式下的网络活动以及事件时间线的信息。要访问此缓冲区,我们可以使用 Volatility 的 linux_dmesg 插件。为了方便起见,插件的输出被重定向到一个文本文件中:

图 8.34 – Volatility linux_dmesg 输出
如果你仍然想尝试至少计算出大致的连接时间,可以执行以下计算:
- 在 图 8.34 中,你可以看到 SanDisk Cruzer Glide 3.0 USB 设备已连接到所检查的主机。这里,你可以看到它连接的详细信息,例如没有写保护。你在左侧看到的时间戳是相对时间戳,能够帮助你分析事件的顺序,但解释这些时间戳时有一个问题。这些内核时间戳是从各个 CPU 保持的正常运行时间值中派生的。随着时间的推移,这个值与实时时钟之间会发生偏差,因此从内存转储中可靠地重建事件的时间是有问题的。

图 8.35 – Systemd 启动时间
- 我们看到
systemd进程的启动时间为2021-10-02 17:05:54UTC。我们需要将这个时间转换为秒。任何纪元转换器都可以为我们完成此操作。我们将使用在线转换器www.unixtimestamp.com:

图 8.36 – 启动时间转换
-
这导致了一个值为
1633442754秒的结果。dmesg中显示的值是纳秒,因此必须将其转换为秒。我们 USB 设备的连接时间戳是4824232947404.4824纳秒,四舍五入后为4824秒。这个值会加到你之前计算的 Unix 时间戳上。最终得到的时间戳为1633447578秒。 -
我们的最后一步是将得到的时间戳转换为可读格式。为此,我们可以再次使用转换器:

图 8.37 – Unix 时间戳转换
现在,我们知道 USB 设备连接的大致时间是 2021 年 10 月 5 日 15:26:18。
自然,如果我们可以访问一个实时主机,特定事件的定时任务会更容易。不过,请记住,在写入磁盘后,dmesg 日志可能会被攻击者篡改,您感兴趣的事件可能根本不存在。您仍然可以使用交叉检查来检测这些篡改。
为了以可读的格式输出 dmesg 时间戳,许多 Linux 发行版引入了 -T 选项。其使用方法如下。我们运行 dmesg -T 命令,并获得 dmesg 记录的事件的准确时间:

图 8.38 – 实时主机上的 dmesg 输出
命令输出显示,所涉及的 USB 设备连接发生在 2021 年 10 月 5 日 8:25:13(主机的本地时间)。主机所在的时区为 PDT,因此连接时间为 15:25:13 UTC。正如您所看到的,我们计算出的时间戳偏差相对较小,因此在无法访问实时主机的情况下,可以使用上述计算时间戳的方法。
我们需要考虑的最后一件事是加密容器的检测,接下来我们将讨论这一内容。
检测加密容器
在 Linux 系统上调查用户活动时,一个重要的步骤是寻找加密容器,尤其是在调查潜在威胁行为者使用的主机时。事实上,为了自身的安全,他们可以将与攻击准备、开发的恶意工具或被窃取的信息相关的重要数据放入加密容器中。
基于 Linux 的系统有多种加密选项,从 dm-Crypt 到更标准的 TrueCrypt 和 VeraCrypt。实际上,检测加密容器并恢复加密密钥的过程几乎与 Windows 中的过程相同。因此,我们只讨论主要的要点。
首先,您仍然可以通过分析正在运行的进程来检测加密容器,因为如果系统上打开了加密容器,您仍然可以在进程列表中找到相应的进程。
其次,对于最流行的 TrueCrypt 解决方案,Volatility 有一个单独的插件,用于恢复缓存的密码短语 – linux_truecrypt_passphrase。
第三,您始终可以使用 Bulk Extractor AES 扫描器来搜索可能用于加密的 AES 密钥。这与 Windows 中的情况相同:

图 8.39 – 使用 Bulk Extractor 搜索 AES 密钥
输出是相同的 aes_keys 文件,其中包含所有由 Bulk Extractor 提取的 AES 密钥:

图 8.40 – 找到的 AES 密钥
了解系统上运行的加密容器,及其使用的 AES 算法和密钥长度后,你可以尝试从现有数据中恢复主密钥。
总结
无论调查的是哪种操作系统,用户活动分析都起着重要作用,因为它可以重建事件发生的背景,并揭示用户采取的行动的关键信息。另一方面,Linux 操作系统常常被攻击者使用,因此在这种系统上调查用户活动具有特殊意义。
由于 Linux 系统的设计方式,调查它们不像 Windows 那样简单。然而,我们仍然可以获得关于运行中的程序、打开的文档、连接的设备、使用的加密容器等数据。
在分析 Linux 上用户活动时,一个重要的辅助工具是检查进程内存,这需要几个步骤来完成。尽管提取映射及其进一步处理相对较难,但进程内存可能包含有价值的数据——访问过的链接、对话、发布内容、电子邮件地址、文件名等。
因此,我们已经涵盖了分析用户活动的一般方法。现在是时候讨论一些恶意内容了。这将是我们在下一章讨论的内容。
第九章:恶意活动检测
在大多数情况下,内存取证调查的主要目标是寻找恶意活动。根据最近 TrendMicro (www.trendmicro.com/vinfo/us/security/news/cybercrime-and-digital-threats/a-look-at-linux-threats-risks-and-recommendations) 和 Group-IB (www.group-ib.com/media/ransomware-empire-2021/, blog.group-ib.com/blackmatter) 的研究,针对基于 Linux 的系统的攻击正在上升,许多威胁行为者已将专门针对 Linux 系统的软件加入到他们的武器库中。例如,勒索软件操作员如 BlackMatter、RansomExx 和 Hive 都已将相应版本加入到他们的武器库中。此外,后期利用框架和个别脚本也被用来攻击基于 Linux 的系统。同时,漏洞利用和安全配置错误的使用仍然是最广泛的初步访问技术,尤其是当我们谈论到 web 应用程序时。
我们将要讨论的主要活动几乎是相同的——网络连接、注入到进程中以及访问非典型资源。这是我们将重点关注的内容,但这次我们会尝试通过具体示例来细分不同的分析技术。
在本章中,我们将讨论以下主题:
-
调查网络活动
-
分析恶意活动
-
检查内核对象
调查网络活动
由于大多数恶意软件需要与命令和控制服务器通信、下载附加模块或发送一些数据,因此网络连接的出现是不可避免的。然而,在调查网络连接之前,了解我们的主机上使用了哪些网络接口及其配置方式是个好主意。为此,我们可以使用 Volatility 的 linux_ifconfig 插件,该插件以如下方式提供所有必要的信息:

图 9.1 – 网络接口信息
在输出中,我们可以看到调查的主机上使用了三个接口:
-
lo– 一个回环接口,标准 IP 地址为127.0.0.1 -
ens33– 一个网络接口,IP 地址为192.168.168.144 -
ens38– 一个网络接口,IP 地址为192.168.3.133
现在我们可以开始调查活跃的网络连接。为此,Volatility 提供了 linux_netstat 插件,可以按以下方式运行:

图 9.2 – Volatility linux_netstat 插件
如您所见,在这种情况下,我们也将获得相当大量的输出,并且它不仅仅与我们直接感兴趣的网络连接相关,因此最好将输出重定向到文本文件中:

图 9.3 – 活跃的网络连接
在这种情况下,我们看到由 Firefox 浏览器建立的连接,以及由192.168.3.132 IP 地址建立的多个连接,这些连接通过端口22建立,这通常用于SSH。很可能这就是受害者的主机,它通过SSH连接。
另一种检查网络活动的方法是使用 Bulk Extractor,因为它允许我们从内存转储中提取剩余的网络流量。在这种情况下,我们使用网络扫描器,如图所示:

图 9.4 – Bulk Extractor 网络扫描器
输出将包含packets.pcap文件,这是网络流量的转储文件。这个文件可以通过Wireshark打开,Wireshark 是最广泛使用的网络协议分析工具之一。要获取此工具,只需访问官方网站(www.wireshark.org/),点击下载图标,并选择适合您系统的安装版本。
安装后,您可以运行 Wireshark 并简单地将packets.pcap文件拖放到其中:

图 9.5 – 使用 Wireshark 打开的网络流量转储
在这里,您可以查看端点统计信息并找出连接到哪些 IP 地址。为此,请打开统计标签并搜索端点:

图 9.6 – 端点
同样,您可以查看所使用协议的统计信息:

图 9.7 – 协议层次结构
我们可以检查单独的数据包或尝试提取传输的对象,也可以配置过滤器并检查与单个 IP 地址的通信。例如,在我们的案例中,您可以通过使用简单的ip.addr==192.168.3.133 && ssh过滤器来检查是否与特定的 IP 地址建立了SSH连接:

图 9.8 – Wireshark 过滤器用于 SSH
在图中,我们看到大量数据包在我们的 IP 和192.168.3.132 IP 之间传输。这种通信自然会引起我们的注意。
这里是另一个例子,说明如何通过分析内存转储中的网络连接或网络流量来获得有用信息:

图 9.9 – Meterpreter 活动
在这里,我们可以看到端口4444的活跃使用。记得在第五章,使用 Windows 内存取证进行恶意软件检测与分析中,我们提到过一些端口是不同软件默认使用的吗?这正是这种情况,端口4444是 Meterpreter 反向 shell 默认使用的端口。所以,我们从一次流量分析中就可以判断,被检查的主机上有与 Meterpreter 相关的进程。
我们再看一个例子:

图 9.10 – Nginx 活动
在 linux_netstat 的输出中,我们可以看到被调查的主机作为 Web 服务器使用,因为在端口 80 上,nginx 进程正在监听:

图 9.11 – SSH 连接
此外,我们还看到几个不同 IP 地址的 SSH 连接。在这种情况下,我们可以推断其中一个 IP 地址可能是攻击者使用的。
由于插件的输出包含了发起连接的进程信息,自然,迟早我们会开始调查这些进程。
在所有这些例子中,我们看到了潜在恶意活动的痕迹。现在,让我们来讨论如何分析这种活动。
分析恶意活动
让我们仔细看看最后一个例子。我们看到有几个 SSH 连接。我们可以分析可能与之相关的进程。为此,我们将使用 linux_pstree 插件并添加 sshd 进程标识符 – 29897 和 23251:

图 9.12 – Volatility linux_pstree
在图 9.12中,我们看到 sshd 的子进程是 bash 和 sudo,这意味着使用了提升的权限。在这种情况下,我们可以搜索 bash 历史记录,也可以转储并分析这些进程的内存。
我们从 bash 历史记录开始。为此,我们将使用linux_bash插件:

图 9.13 – Bash 历史记录
在这里,我们可以看到有人在使用 MySQL 和 WordPress,并且看到与 site-info.php 文件的交互,以及与 bash 进程(PID 为 30112)关联的 nyan-cat.gif 下载。
我们可以检查在这种情况下哪个用户运行了 bash。为此,我们将使用已知的 linux_psenv Volatility 插件:

图 9.14 – Bash 进程的环境
该插件的输出使我们能够确定此活动是通过来自 192.168.110.40 IP 地址的 SSH 连接由用户 admin 执行的。我们可以搜索有关此用户的信息。在前一章中,我们已经提到过这些信息可以在 /etc/passwd 文件中找到,因此让我们使用 linux_recover_filesystem 插件并尝试从内存中恢复文件系统。为此,我们将使用以下命令:
$ vol.py --plugins=profiles -f /mnt/hgfs/flash/ubuntu-server.vmem --profile=Linuxubuntu-server_17_47_52-profilex64 linux_recover_filesystem -D /mnt/hgfs/flash/recovered/
在我们的案例中,恢复的文件系统将被放置在恢复文件夹中:

图 9.15 – 恢复的文件夹内容
如图所示,/etc 目录未能恢复;不过,我们有 /var/log 目录,在那里可以找到 auth.log 文件:

图 9.16 – 恢复的 auth.log 文件
该文件记录了所有认证尝试,我们可以找到以下内容:

图 9.17 – auth.log 文件内容
请注意,从这里我们得知 admin 用户是在攻击时创建的,我们还获得了创建的具体时间戳。之后,我们还可以看到此用户的多次登录以及其使用 root 权限,正是通过该权限下载了我们的图片。我们还看到该图片被上传到 /var/www/wordpress。幸运的是,linux_recover_filesystem 插件能够部分恢复此文件夹:

图 9.18 – 恢复的 WordPress 文件夹
在这里,我们可以看到我们的图片。因此,我们需要找出它在这里扮演的角色,以及攻击者是如何访问系统的。
让我们将从内存转储中提取的网络流量转储添加到我们的调查中。为了提取流量,我们运行 Bulk Extractor:

图 9.19 – 网络流量提取
现在,我们在 Wireshark 中打开 packets.pcap 文件。检查数据包时,您可能会遇到以下内容:

图 9.20 – Wireshark 数据包分析
我们看到一个带有有趣参数的 GET 请求。正如你所看到的,这里列出的用户代理是 WPScan v.3.8.7。这意味着此请求是使用 WPScan 工具发出的,WPScan 用于搜索 WordPress 内容管理系统中的漏洞。类似的信息应该记录在 nginx 访问日志中。这个日志也通过 linux_recover_filesystem 恢复,并可以在 /var/log/nginx 中找到:

图 9.21 – 恢复的访问日志
在 access.log 中,我们可以看到来自一个我们已经知道的 IP 地址,由 WPScan 发出的大量请求。如果我们进一步查看,还能看到以下内容:

图 9.22 – 评论帖子
扫描完成后,发送了一个POST请求,并带有评论;可能是利用了与评论发送相关的漏洞来实现初始访问。
在继续分析时,我们可以尝试使用 Wireshark 的导出对象功能提取在网络会话期间传输的对象:

图 9.23 – Wireshark 中的对象导出
正如你在前面的图中看到的,在我们的例子中,发现了几个我们可以尝试提取的对象。包括一些评论。让我们检查一下:

图 9.24 – 导出的评论
正如我们所看到的,一位用户在博客上留言,并附上了访问相同192.168.110.40 IP 地址的链接。你还可以在流量转储中看到,尝试打开该链接后不久,开始出现相同的SSH连接。
如果从 WordPress 的角度考虑,用户发送的评论必须保存在数据库中。因此,你可以在 MySQL 日志中或该进程的内存中查找相关信息。从进程列表中,我们可以看到与 mysql 守护进程相关的 mysqld 进程的标识符是29602:

图 9.25 – mysqld 的进程 ID
现在,我们可以使用linux_dump_map插件转储此进程的映射:

图 9.26 – Volatility linux_dump_map
现在,轮到strings工具了:
$ for file in /mnt/hgfs/flash/mysql/*; do strings "$file" >> /mnt/hgfs/flash/mysql_strings.txt; done
现在,我们可以探索strings输出,并寻找关于我们评论的信息:

图 9.27 – mysqld 进程内存中的评论
万事俱备!在这里,我们不仅看到了发送的评论,还看到了实际使用的有效载荷。现在,我们可以确定攻击者是利用漏洞进行初始访问的。这解决了一个谜团。
在图 9.27中,我们还可以注意到与页脚中的site-info.php文件的交互。由于我们已经成功提取了 WordPress 文件夹及其文件系统,让我们找到这个文件:

图 9.28 – 与 WordPress 相关的文件
该文件的内容如下:

图 9.29 – site-info.php 文件的内容
根据获得的所有信息,我们可以得出结论,在攻击者访问主机后,他们修改了站点的源代码,使得现在当用户访问被破坏的资源时,他们会看到一张图片,而不是博客。
让我们以类似的方式考虑我们之前提到的 Meterpreter 示例。这是一个值得特别关注的例子,因为这种类型的有效载荷最常出现在参与事件的基于 Linux 的系统上。所以,我们有信息表明某些连接是通过端口4444建立的。让我们尝试找出与 Meterpreter 相关的进程。这里最合乎逻辑的做法是检查网络连接,寻找我们知道的端口和地址的连接,然后寻找建立连接的进程。然而,你可能会遇到没有网络连接信息或者没有你寻找的具体连接信息的情况。在这种情况下,你可以使用 YARA 规则与 linux_yarascan 插件,尝试在进程的内存中找到包含我们的 IP 地址的进程。此外,进程注入通常与 Meterpreter 有关,因为攻击者需要以某种方式将有效载荷加载到内存中。在这种情况下,Volatility 提供了 linux_malfind 插件,这是 Windows 插件的类似物。让我们运行它:

图 9.30 – Volatility linux_malfind
在插件的输出中,我们可以找到类似的内容。我们有一个 rules_for_emplo 进程,关联着位于 it-sec 用户下载目录中的 rules_for_employees 文件。那里的注入文件以 ELF 开头,因此我们正在处理一个可执行的文件。
重要提示
可执行和可链接格式(ELF)是一种二进制文件格式,广泛应用于许多现代类 UNIX 操作系统,如 Ubuntu、FreeBSD、Linux 和 Solaris。
首先,我们可以尝试分析 rules_for_emplo 进程。为此,我们可以使用 linux_procdump 插件提取可执行文件本身:

图 9.31 – 可执行文件提取
提取后,我们可以计算可执行文件的哈希值,并在网络威胁情报平台中检查,或者尝试在受控环境中运行文件,了解它的功能。当然,如果你具备逆向工程技能或有专门的恶意软件分析团队,他们也是不错的选择。另一种方法是使用 linux_dump_map 插件提取该进程的内存:

图 9.32 – 进程内存提取
然后,我们可以再次使用我们的脚本获取可读的字符串:
for file in /mnt/hgfs/flash/rules_for_employees/*; do strings "$file" >> /mnt/hgfs/flash/rules_strings.txt; done
结果将是如下所示:

图 9.33 – 规则 _for_emplo 进程内的 IP 地址
从我们进程提取的内存字符串中,我们可以找到 192.168.168.144 IP 地址,这个地址与我们看到的多个连接有关,还有 tcp://192.168.168.153:4444 字符串。由此,我们可以推测使用了 reverse_tcp。
让我们深入看看 rules_for_emplo 进程启动后发生了什么。我们将使用 linux_pstree 插件获取活动进程列表,并显示它们的父子关系:

图 9.34 – rules_for_emplo 的子进程
在这里,我们看到了 rules_for_emplo 进程,它启动了多个 shell,包括具有提升权限的 shell、Python 和 systemctl。让我们看看这些进程是如何启动的。为此,我们将使用 linux_psaux 插件:

图 9.35 – 子进程的启动参数
在这里,我们看到 Python 被用来启动一个 tty shell,并获得 sudo 权限。要理解这里发生了什么,我们可以使用 linux_bash 插件查看执行了哪些命令:

图 9.36 – Bash 历史
从这个插件的输出中,我们可以看到攻击者试图安装一个 cron 作业以实现持久性,而 systemctl 被用来重新加载 cron 服务并检查其状态。我们还注意到 /tmp 目录被用作创建和存储临时文件的工作目录。我们希望知道最终创建了什么 cron 作业。在基于 Linux 的系统中,这种活动应该记录在 /var/log/cron.log 文件中,从中可以获取关于创建的作业的信息。
顺便提一下,如果你对某个进程使用的资源感兴趣,你仍然可以使用 linux_lsof 插件。关键在于,Linux 的哲学是“一切皆文件”。也就是说,如果进程使用了文本文件、套接字或管道,所有这些内容都可以在 linux_lsof 的输出中找到。例如,如果我们对 rules_for_emplo 及其所有派生的进程运行 linux_lsof 并将输出重定向到一个文本文件中,我们将看到以下内容:

图 9.37 – Volatility linux_lsof 输出
在这里,我们看到以下资源的描述符:
-
/dev/null是一个特殊文件,通常被称为 空设备。无论写入多少信息,写入都总是成功的,而读取则相当于读取文件的末尾。 -
/dev/ptmx是一个字符文件,用于创建伪终端主从对。 -
/dev/pts是由 Linux 内核动态创建的特殊目录。/dev/pts中的条目对应于伪终端(伪 TTY 或 PTY)。 -
/dev/tty代表当前进程的控制终端。
如你所见,一般来说,在基于 Linux 的系统上进行初步的恶意活动检测和分析过程,与 Windows 上的过程没有太大区别。我们主要关注寻找可疑的连接、具有奇怪名称的进程、非典型的子进程或行为,之后我们根据这些发现逐步解开链条。然而,也存在一些特殊情况。例如,rootkit 以前常用于对 Linux 的攻击。
历史上,rootkit 这个术语曾用于指可加载的内核模块,攻击者在获得 root 权限后立即安装这些模块。Rootkit 使攻击者能够在被攻破的系统中获得持久性,并通过隐藏文件、进程和 rootkit 本身的存在来掩盖活动。尽管 rootkit 现在几乎不存在了,但我们认为有必要讨论一些主要的分析技术,帮助你检测内核对象及其相关接口的操作。
检查内核对象
首先,rootkit 是已加载的内核模块。因此,我们需要检测已加载模块的方法。在这种情况下,Volatility 提供了一些非常实用的插件:linux_lsmod,它列举内核模块,以及 linux_hidden_modules,它通过内存切割找到隐藏的内核模块。
第一个插件通过遍历 modules 变量中存储的全局列表来列举内核模块。输出结果如下所示:

图 9.38 – 加载的内核模块列表
在这里,我们可以看到已加载模块的名称及其大小。请注意,如果使用需要加载内核模块进行转储的工具,加载的模块也会出现在此列表中。例如,在我们的案例中,第一行中可以看到 lime 模块。
linux_hidden_modules 插件扫描内存中的模块结构实例,并将结果与 linux_lsmod 报告的模块列表进行比较。它的效果如下:

图 9.39 – 隐藏的内核模块列表
如我们所见,在我们的案例中有两个隐藏的模块。为了分析它们,我们可以尝试使用 Volatility 的 linux_moddump 插件提取它们。为此,我们需要使用 -b 选项设置基地址,并使用 -D 选项设置保存结果的目录。例如,如果我们想尝试提取 RG24XR24AR24 模块,我们需要运行以下命令:
$ vol.py --plugins=profiles -f /mnt/hgfs/flash/it-sec.lime --profile=Linuxubuntu_it-secx64 linux_moddump -b 0xffffffffc0521970 -D /mnt/hgfs/flash/
当然,rootkit 不一定总是试图隐藏其模块;相反,它们可能会使用伪装,并试图看起来像合法的模块。在这种情况下,为了找到 rootkit,可以提取通过 linux_lsmod 找到的所有模块,并将它们与合法的模块进行比较。
另一个重要的观点是,rootkit 经常使用钩子来执行其活动。
重要提示
钩子(Hooking)是通过拦截在组件之间传递的函数调用、消息或事件来修改或增强操作系统、应用程序或其他软件组件行为的过程。
钩子技术有很多种,但最常见的是 IDT 钩子和系统调用钩子(syscall hooks)。
重要提示
中断描述符表(IDT)存储指向中断服务例程的指针。当发生中断时,处理器停止当前活动并调用中断服务例程来处理该中断。此类中断可能由按钮按下、鼠标移动或其他事件触发。
syscall 函数允许直接进行此类调用,而 Linux 系统调用表本身就是该操作系统 API 的一部分。
Volatility 提供了 linux_check_idt 和 linux_check_syscall 插件来检测 IDT 和系统调用钩子。
第一个插件的运行方式如下:

图 9.40 – IDT 钩子
在我们的案例中,没有检测到 IDT 钩子,因为我们会在输出中看到 HOOKED 这个词。
第二个插件的运行方式与第一个相同:

图 9.41 – 系统调用钩子
在这里,情况更为复杂。我们看到很多系统调用钩子,但遗憾的是没有关于这些钩子的额外信息,所以我们需要手动分析它们。
除此之外,Volatility 还提供了几个插件,用于分析其他类型的钩子:
-
linux_apihooks– 检查用户空间 API 钩子 -
linux_check_evt_arm– 检查异常向量表,查找系统调用表钩子 -
linux_check_inline_kernel– 检查内联内核钩子 -
linux_check_tty– 检查 tty 设备中的钩子
在某些情况下,根套件(rootkits)也可以与不同的文件进行交互。Volatility 允许我们通过 linux_kernel_opened_files 插件找到从内核内部打开的文件,并通过 linux_check_fop 插件检查文件操作结构是否存在根套件修改。
这就是我们如何进行初步的内核对象检查并搜索根套件。但是,再次说明,在写这本书时,根套件几乎已经过时。它们已被后期利用框架和专用恶意软件取代。
总结
用于检测和分析 Linux 系统上恶意活动的技术与用于 Windows 操作系统的技术类似。我们集中在调查活跃的网络连接和进程行为中的各种异常。然而,这种活动的分析通常归结为检查网络流量转储(也可以从内存中提取)、调查单个进程的内存,或检查内存中的文件系统。在大多数情况下,正是这三个元素帮助我们找到必要的证据并重建威胁行为者的行动。
毫无疑问,了解文件系统结构、主要文件的位置和内容在调查基于 Linux 的系统中起着重要作用。因此,了解被调查系统上使用的软件,以及知道它的日志和配置文件存储在哪里,将使你能够轻松找到所需的信息并补充事件中的缺失细节。
这就结束了我们对基于 Linux 系统内存的研究。我们在这段艰难但迷人的旅程中的最后一站将专注于 macOS。我们将讨论如何从 macOS 获取内存转储并实际进行调查。所以,我们迫不及待地想在下一部分见到你。
第四部分:macOS 取证分析
第四部分将重点讨论 macOS 内存获取与分析的关键点。此外,还将探讨获取重建用户行为和检测恶意活动所需信息的方法。
本书本节包括以下章节:
-
第十章,MacOS 内存获取
-
第十一章,通过 macOS 内存取证进行恶意软件检测与分析
第十章:macOS 内存获取
本书的最后一部分专注于一个重要话题——运行 macOS 系统的内存调查。在国际桌面操作系统市场中,macOS 当之无愧地排名第二。尽管苹果设备最初被认为是个人使用的独立设备,但每年越来越多的用户将其用于工作目的。最近,macOS 在工作中的使用达到了新高度,这个操作系统开始在企业范围内使用(尽管这种做法目前在美国更为普遍)。到 2021 年,Macintosh 在美国企业的市场份额已达 23%:www.computerworld.com/article/3604601/macs-reach-23-share-in-us-enterprises-idc-confirms.html。
随着 macOS 用户数量的增加以及企业的采用,威胁行为者对该操作系统的兴趣也在上升。近年来,针对 macOS 的攻击数量显著增长。出现了专门针对该操作系统的攻击工具,这意味着是时候扩展我们的工具库,增加用于 macOS 调查的技术和工具了。但在我们分析数据之前,必须先收集它。这就是为什么,我们一如既往地从 macOS 内存获取技术概述开始。
将涵盖以下主题:
-
理解 macOS 内存获取问题
-
准备进行 macOS 内存获取
-
使用
osxpmem获取内存 -
创建 Volatility 配置文件
理解 macOS 内存获取问题
在前几章中,我们讨论了硬件和软件方法的内存提取。对于 OS X 和 macOS,这些方法同样适用,但有几个极为重要的事项需要考虑。我们从基于硬件的解决方案开始。
回顾一下,基于硬件的获取工具依赖于直接内存访问,并使用诸如 FireWire 或 Thunderbolt 等技术。目前,几乎所有的 Macintosh 都配备了 FireWire 或 Thunderbolt 端口,在这种情况下获取内存内容不需要管理员密码和解锁计算机。然而,显然事情不会那么简单。首先,这项技术仅允许获取前 4 GB 的内存,而这不足以彻底检查具有超过 4 GB 内存的系统。其次,自 2013 年以来,启用了 Intel 虚拟化技术(VT-d)用于定向输入/输出。这项技术充当重映射器,有效地阻止了直接内存访问请求。另一个问题是,如果启用了 FileVault,OS X 和更新版本的 macOS 会在计算机锁定时自动关闭直接内存访问。结果是,使用软件解决方案仍然是优先选择。
软件获取工具,像其他操作系统一样,必须在解锁系统上的用户界面中运行。然而,针对 OS X 和 macOS 的此类工具并不多,尤其是那些能在最新操作系统版本上正常运行的工具。在 OS X 10.6 版本之前,物理内存可以通过 /dev/mem 设备文件或 /dev/kmem 访问,后者指向内核的虚拟地址空间。如果这些设备文件可用,则可以使用 dd 工具通过设备文件读取内存内容。然而,在操作系统的最新版本中,这种方法已不再可行,需要使用专门的获取工具。由于内存保护防止普通用户直接访问内存,大多数内存获取工具依赖于加载 BSD 内核扩展,简称 kext,它允许对物理内存进行只读访问。一旦 kext 加载到内核中,就可以通过 /dev/pmem/ 设备文件读取物理内存。然而,要将 kext 加载到内核中,需要管理员权限和一些小的安全配置更改。接下来,我们来看看运行工具之前需要采取的所有步骤。
准备 macOS 内存获取
macOS 内存获取工具并不多,而且它们仅支持特定版本的操作系统。因此,在选择和测试合适的工具之前,我们需要先了解计划使用的操作系统版本。要查看安装的 macOS 版本,请点击屏幕左上角的苹果菜单图标,然后选择 关于本机:

图 10.1 – 关于本机
在弹出的窗口中,您将看到操作系统的版本;在我们的例子中,它是 macOS Big Sur 版本 11.6。通过操作系统版本的信息,您可以找到支持从该操作系统进行内存转储的工具。
截至写作时,以下工具是公开可用的:
-
osxpmem– 支持 OS X Mountain Lion (10.8)、OS X Mavericks (10.9)、OS X Yosemite (10.10)、OS X El Capitan (10.11)、macOS Sierra (10.11)、macOS High Sierra (10.13)、macOS Mojave (10.14) 和 macOS Catalina (10.15) 的 64 位版本。 -
MandiantMemoryzeforMac– 支持 Mac OS X Snow Leopard (10.6) 32/64 位、Mac OS X Lion (10.7) 32/64 位和 OS X Mountain Lion (10.8) 64 位。
尽管这些工具覆盖了相当广泛的操作系统,但它们无法获取最新 macOS 版本的内存转储。除了这些工具,还有一些专有解决方案,如 Cellebrite Digital Collector、SUMURI RECON ITR 或 Volexity Surge Collect,它们试图更新其产品并添加对新版 macOS 的支持。例如,SUMURI 最近宣布 RECON 现在支持 macOS Monterey,而 Volexity 则为 Surge 增加了对 M1 系列新 Mac 的支持。
重要提示
别忘了,为了与目标主机配合工作,你需要准备可移动介质或网络共享,存放所有必要的工具和文件,以及生成的内存转储。
一旦选择了合适的工具,你就可以开始测试它了。为此,你需要一台虚拟机,其配置应与目标主机类似。与 Windows 和 Linux 不同,macOS 并不容易作为客户系统安装。事实上,要创建一个 macOS 虚拟机,你需要通过修改配置文件来做一些小技巧。幸运的是,部署指南并不难找到。例如,这里有一份关于如何在 Windows 上使用 VirtualBox 和 VMware 部署 macOS 虚拟机的不错指南:www.makeuseof.com/tag/macos-windows-10-virtual-machine/。
创建虚拟机后,你可以继续测试工具。由于 macOS 在启动第三方文件方面比 Windows 和 Linux 有更好的保护,我们将不得不使用一些技巧,稍后会详细介绍。
使用 osxpmem 获取内存
这次,我们只讨论一种创建内存转储的工具——osxpmem。选择这个工具是因为它是免费分发的,并且支持最多的 OS X 和 macOS 版本。
你可以从官方 GitHub 仓库下载此工具:github.com/Velocidex/c-aff4/releases。在osxpmem中,截至目前,这是版本 3.2:

图 10.2 – 最新版本与 osxpmem
下载osxpmem归档并解压。在其中,你将找到osxpmem.app,这是我们用来创建内存转储的工具。该工具是一个命令行工具,需要通过终端运行。首先,我们需要打开终端并进入osxpmem.app。在这个位置,我们需要使用kextutil加载kext,如下所示:

图 10.3 – MacPmem.kext 加载
使用像osxpmem这样的工具的主要困难是 macOS 的安全策略。因此,如果我们在没有额外步骤的情况下尝试运行该工具,首先会出现一系列文件所有者/权限不正确的错误,其次会显示一条软件被阻止的消息。
为了解决第一个问题,我们需要更改文件的所有者和权限。为此,在终端中运行chown和chmod命令。要检查所做的更改,可以使用ls -lah命令,结果如下所示:

图 10.4 – 更改所有者和权限
为了解决第二个问题,打开设置并进入安全性与隐私。在这里的常规标签中,我们会看到有关阻止程序的信息:

图 10.5 – 安全性与隐私常规选项卡
为了解锁我们的程序,我们需要点击底部的锁,并同意解锁它。
此外,你可能需要禁用系统完整性保护。为此,请在终端中运行以下命令:
csrutil disable
在较新版本中——例如,在 macOS Catalina 中——你可能需要执行更多全局操作,因为只有在恢复模式下才能禁用系统完整性保护。
重要提示
自然地,在恢复模式下更改配置时,我们需要重启主机,这意味着大部分数据将丢失。然而,在处理持久性恶意软件或一个反向 shell 监听某个端口并等待攻击者连接的情况下,重启后获取的内存转储分析仍然能为我们提供有用的信息。
要禁用系统完整性保护,进入恢复模式。为此,重新启动系统并按下command + R(如果你使用虚拟机并且主机操作系统是 Windows,则按Win + R)。这将使你进入正确的模式。在出现的窗口中,选择实用工具和终端:

图 10.6 – 恢复模式
在终端中,我们需要运行之前提到的命令:

图 10.7 – 禁用系统完整性保护
如你所见,你需要再次重启系统才能成功应用更改。重启后,你可以打开主终端并再次加载kext。这应该不会有错误。
加载kext后,你需要运行一个命令来收集内存转储。命令将如下所示:
sudo osxpmem.app/osxpmem --format raw -o mem.raw
--format选项用于指定内存转储的格式,而-o选项则用于指定输出文件的路径。
你将得到一个包含原始内存转储的mem.raw文件。在我们的案例中,执行上述步骤看起来像这样:

图 10.8 – 内存获取
如果你运行ls -lah,你将看到生成的文件:

图 10.9 – 已创建的内存转储
之后,你可以使用以下命令卸载内核扩展:
$ sudo osxpmem.app/osxpmem -u
这样,我们可以获得内存转储,但这只是旅程的开始。为了能够使用 Volatility 处理这个文件,我们需要创建一个合适的配置文件。这将在下一节中讨论。
创建 Volatility 配置文件
要创建一个 macOS 配置文件,我们需要安装一些额外的工具。首先,我们需要安装 Brew 包管理器,可以通过访问官方网站的说明进行安装:docs.brew.sh/Installation。
基本上,你需要做的就是运行主页上的命令:
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
我们需要使用 Brew 管理器来安装我们已经知道的dwarfdump,所以一旦安装了brew,可以在终端中运行以下命令:
$ brew install dwarf
最后需要下载的是KernelDebugKit。为此,请使用此链接:developer.apple.com/download/all/?q=debug。请注意,为了访问该链接,你需要一个 Apple ID,你可以通过点击Create yours now链接来创建。输入你的 ID 后,你将看到下载页面:

图 10.10 – Apple 开发者下载页面
在此页面上,你需要找到与你的操作系统版本对应的 KDK。例如,屏幕截图中显示的KDK 12.1对应的是最新的 macOS Monterey。下载 KDK 后,你需要安装它。此过程可以通过标准方式完成,双击将挂载文件并打开安装程序,安装程序将引导你完成安装过程。
你可以使用ls命令验证一切是否已安装,因为安装后,你的 KDK 版本应该出现在/Library/Developer/KDKs中。
如果 KDK 已存在,你可以开始从内核获取调试信息。为此,我们使用dwarfdump,它应该使用以下参数:
-
-arch:架构 – 我们为 32 位系统指定i386,为 64 位系统指定x86_64 -
-i:指向 KDK 中kernel.dSYM文件的路径
我们还需要将输出重定向到一个以dwarfdump为扩展名的文件。
因此,如果我们使用 64 位 macOS Mojave,命令将如下所示:
$ dwarfdump -arch x86_64 -i /Library/Developer/KDKs/KDK_10.14.6_18G2016.kdk/System/Library/Kernels/kernel.dSYM > 10.14.6_x64.dwarfdump
在我们的案例中,前面的步骤如下所示:

图 10.11 – 从内核获取 dwarf 调试信息
结果,我们得到了10.14.6_x64.dwarfdump文件,将其放入dwarf目录。接下来,我们将需要 Volatility。在终端中,进入volatility/tools/mac并执行convert.py脚本,将创建的dwarfdump路径和输出文件路径作为参数传递。在我们的案例中,命令如下所示:
$ python convert.py 10.14.6_x64.dwarfdump converted_10.14.6_x64.dwarfdump
这将生成一个 Linux 风格的输出,可以被 Volatility 读取。之后,我们需要从转换后的文件中创建类型:
$ python convert.py converted_10.14.6_x64.dwarfdump > 10.14.6_x64.vtypes
接下来,我们需要使用dsymutil生成符号信息:
$ dsymutil -s -arch x86_64 /Library/Developer/KDKs/KDK_10.14.6_18G2016.kdk/System/Library/Kernels/kernel > 10.14.6_x64.symbol.dsymutil
再次,我们传递使用的架构信息和 KDK 中的内核文件路径作为参数。输出被重定向到一个以.dsymutil为扩展名的文件。
我们的最后一步是创建一个包含.dsymutil和.vtypes文件的 ZIP 文件。为此,我们可以使用以下命令:
$ zip 10.14.6_x64.zip 10.14.6_x64.symbol.dsymutil 10.14.6_x64.vtypes
最后,你将获得你的配置文件。要使用新创建的配置文件,只需将其放入volatility/plugins/overlays/mac目录中。
重要提示
convert.py 脚本在 High Sierra 之前的版本中运行良好。对于较新的版本,可能会遇到一些问题,因为 dwarf 的结构发生了一些变化。为了解决这个问题,你需要修改 convert.py 脚本。
创建 macOS 配置文件并不是一件容易的事。不过,如果你需要分析一个包括 High Sierra 在内的 macOS 版本,你可以使用 GitHub 上现成的配置文件:github.com/volatilityfoundation/profiles/tree/master/Mac。相比之下,如果使用 Volexity Surge Collect 等专有解决方案,你将能获取到甚至最新版本 macOS 的配置文件。如果目标主机运行的是 Intel 处理器,那么可以直接使用 Volexity 提供的配置文件来配合 Volatility 进行分析。对于 M1 处理器,情况稍有不同。由于这是一个 ARM 架构芯片,必须在 Volatility 命令行中传入一些额外的参数。这些参数即是 Surge Collect 创建的 meta.json 文件。在这种情况下,当你运行 Volatility 时,除了标准选项和配置文件外,还需要添加以下内容:
-
--shift – value,对应meta.json中的KaslrSlide参数 -
--dtb – value,对应meta.json中的dtb参数
因此,运行 Volatility 的命令应该是这样的:
$ ./vol.py -f <path to memory dump> --profile=<profile>
--shift=< KaslrSlide value> --dtb=<dtb value> <plugin>
另一个重要的事项是,要在 Volatility 中分析来自 M1 Mac 的内存转储,需要 ARM64 支持。在这种情况下,你可以使用 Volatility 的分支版本:github.com/tsahee/volatility/tree/arm64。
总结
与之前讨论的操作系统相比,macOS 是最难处理的。大多数支持在新版本 macOS 上创建内存转储的工具都是付费的,而免费工具仅支持创建到 Catalina 版本的内存转储。
另一个困难是启动工具本身。由于 macOS 的安全功能,需要更改一些设置才能运行来自第三方来源的程序。尤其是对于使用 kext 加载的工具,情况尤为如此。
另一个难点是为新版本的 macOS 创建 Volatility 配置文件。这是因为创建配置文件需要将 dwarf 文件转换为 Volatility 可识别的格式,而 Volatility 开发者提供的脚本和官方 GitHub 仓库中的脚本并不适用于最新版本的 macOS。
鉴于创建适合分析的 macOS 内存转储过程中可能遇到的种种困难,在开始这个过程之前,我们建议你评估一下情况,权衡利弊,仔细考虑是否有必要创建内存转储。
在本章中,我们已经介绍了在 macOS 系统上创建内存转储的过程。接下来的主题同样令人着迷——分析获得的内存转储。
第十一章:利用 macOS 内存取证进行恶意软件检测与分析
之前,针对 macOS 的攻击以及针对该操作系统特定恶意软件的开发,通常是偶发事件,并且常常局限于琐碎的广告软件。在 2020 到 2021 年期间,macOS 面临的主要威胁仍然是广告软件 Shlayer(redcanary.com/threat-detection-report/threats/shlayer/),但我们越来越多地看到背后有先进威胁行为者的定向攻击。一个典型例子是 APT32 或 OceanLotus,这是一个与越南相关的组织,曾通过恶意的 Microsoft Word 文档向 macOS 用户传播后门。
macOS 在企业环境中日益流行,促使了各种 macOS 后渗透工具的出现:MacShellSwift、MacC2、PoshC2 和 Empire 后渗透框架。此外,针对 macOS 的 恶意软件即服务(www.computerworld.com/article/3626431/scary-malware-as-a-service-mac-attack-discovered.html)已经出现在暗网论坛上。
不足为奇的是,搭载 M1 芯片的新设备也没有逃脱网络犯罪分子的关注。因此,Red Canary 的专家最近发现了一种新的恶意软件 Silver Sparrow,专门攻击配备新 M1 处理器的 Mac(www.macworld.co.uk/news/new-malware-m1-mac-3801981/)。
所有这些新闻告诉我们一件事:我们需要了解工具并掌握 macOS 分析技术。这正是本章将要重点讨论的内容。
以下是将要覆盖的主题:
-
使用 Volatility 学习 macOS 分析的特点
-
调查网络连接
-
分析进程和进程内存
-
恢复文件系统
-
获取用户应用程序数据
-
寻找恶意活动
使用 Volatility 学习 macOS 分析的特点
在上一章中,我们讨论了在 macOS 上创建内存转储和相应配置文件时可能遇到的困难。然而,这并非全部。如您所知,Volatility 依赖于内核调试工具包(Kernel Debug Kit,KDK)来创建 macOS 配置文件,以获取解析所需的所有数据。此数据对工具的性能至关重要,因为使用的数据结构和算法会随着内核版本的不同而变化。同时,Apple 不再在 KDK 中包含所有类型信息,这导致许多插件在执行时出现错误。另一个问题是,某些 Volatility 插件使用了 Intel 特定的数据。因此,适用于从 Intel 主机提取的内存转储的插件可能无法与从 M1 主机提取的转储一起使用。接下来,我们将使用适用于 Intel 和 M1 的插件(如果可能的话),在不适用的情况下,我们将尽力说明所有细节。此外,由于分析方法本身和在 macOS 内存转储中寻找异常的过程与 Windows 和 Linux 没有显著差异,这次我们将重点讨论获取特定信息的工具和方法,而不是具体的调查方法。
技术要求
为了分析 macOS 内存转储,我们将同时使用 Linux 和 Windows 系统。我们仍然会在 Ubuntu 21.04(Hirsute)上运行 Volatility 2.6.1,并且像 Bulk Extractor 这样的程序将运行在 Windows 上。在示例中,我们将使用来自 macOS Sierra 10.12.6 的内存转储,但所有描述的操作也可以应用于更新版本的 macOS。
调查网络连接
网络活动分析帮助我们确定哪些进程正在建立网络连接,以及使用了哪些 IP 地址和端口。由于大多数恶意软件和后期利用工具都会建立网络连接,因此调查网络活动是我们的首要任务之一。在 macOS 的情况下,Volatility 提供了多个插件来检查网络接口、活动网络连接以及路由表的内容。
我们可以使用mac_ifconfig插件获取有关被调查主机网络接口配置的信息:

图 11.1 – Volatility mac_ifconfig 输出
如图所示,该插件提供了有关接口名称、分配的 IP 和 MAC 地址,以及设置的混杂模式的信息。
重要提示
混杂模式是一种网络接口控制器模式,它强制控制器将所有传入的流量传递给 CPU,而不仅仅是传递控制器被编程接收的帧。
在我们的例子中,我们看到以下接口:
-
lo0– 回环接口 -
gif0– 软件网络接口 -
stf0– 6to4 隧道接口 -
en0– 带有 IPv4 和 IPv6 地址的以太网 -
utun0– VPN 和“回到我的 Mac”接口
你可以使用 mac_netstat 和 mac_network_conns 插件来获取关于网络连接的信息。第一个插件将显示关于活动连接和开放套接字的信息:

图 11.2 – Volatility mac_netstat 输出
同时,mac_network_conns 插件仅提供网络连接的信息:

图 11.3 – Volatility mac_network_conns 输出
除了网络连接分析,Volatility 还提供了研究路由表的功能。mac_route 插件适用于此:

图 11.4 – Volatility mac_route 输出
在这个插件的输出中,我们可以看到源 IP 和目标 IP 地址、接口名称,并且从 OS X 10.7 开始,我们还可以看到发送/接收统计数据和过期/时间差。
另一种检查网络活动的方式是使用 Bulk Extractor 工具和著名的 net 解析器:
> .\bulk_extractor.exe -o .\output\ -x all -e net .\MacSierra_10_12_6_16G23ax64
结果,我们得到一个 packets.pcap 文件,里面包含了来自内存转储的网络捕获数据。为了分析这个文件,我们可以像之前一样,使用 Wireshark:

图 11.5 – 网络捕获分析
通过这种方式,我们可以获取关于 macOS 网络活动的信息。研究网络活动的自然补充是查看活动进程。这就是我们接下来要讨论的内容。
分析进程和进程内存
进程可以被分析,用来寻找异常、识别潜在的恶意进程,以及观察用户活动。与之前一样,Volatility 提供了多个插件用于获取关于进程及其内存的数据。例如,mac_pslist、mac_pstree 和 mac_tasks 插件可以用来获取进程列表。从实际操作的角度来看,mac_tasks 被认为是获取活动进程信息的最可靠来源。与 mac_pslist 不同,mac_tasks 插件枚举任务并搜索进程对象,而不是依赖于可能在 macOS 内存获取过程中被损坏的进程链表。然而,在最新版本的操作系统上测试时,mac_pstree 插件表现得最为高效,能够正确显示针对 Intel 和 M1 芯片的 macOS 结果。
插件的启动方式与 Windows 和 Linux 相同:

图 11.6 – Volatility mac_pstree 输出
除了进程本身的列表,我们当然也对启动这些进程时使用的参数感兴趣。为了获取这些数据,我们可以使用 mac_psaux 插件:

图 11.7 – Volatility mac_psaux 输出
在此插件的输出中,你不仅可以找到参数,还可以找到可执行文件的完整路径。然而,在处理从带有 M1 芯片的 macOS 获取的内存转储时,这个插件可能无法正常工作并导致错误。
除了进程的启动参数外,我们还不能忘记命令行的历史记录。在这种情况下,我们可以使用 mac_bash 插件,它可以检索在 shell 中执行的命令,以及 mac_bash_hash 插件,它显示命令别名的哈希表。另一种获取此类信息的方法是调查与终端应用程序相关的进程内存。我们可以分别使用 mac_procdump 和 mac_memdump 插件提取可执行文件和进程内存进行分析。然而,目前这些插件只能正确提取从具有 Intel 芯片的主机获得的内存转储数据。尽管如此,对于 Intel 和 M1 芯片,我们仍然有机会检查每个进程中分配的内存块、它们的权限以及映射文件的名称。这可以通过 mac_proc_maps 插件来完成:

图 11.8 – Volatility mac_proc_maps 输出
如你在 图 11.8 中所见,在此插件的输出中,我们可以找到进程所使用的文件及其在磁盘上的完整路径。如果需要,我们还可以使用 mac_dump_maps 插件提取这些内存块。如果我们对特定的内存块感兴趣,可以使用 -s 选项指定其起始地址,如下所示:

图 11.9 – Volatility mac_dump_maps 结果
如你所见,第一个 Siri 进程内存块的内容已成功提取,并且可以通过其他工具单独进行分析。通过这种方式,我们可以尝试提取可执行文件、库和其他文件。然而,还有一种分析和提取与进程相关文件的方法。让我们来讨论一下。
恢复文件系统
处理 macOS 内存中文件系统的方法也并非独特。首先,我们可以使用 mac_lsof 插件检查进程的打开文件描述符。它的启动和输出格式与 Linux 对应的插件没有区别:

图 11.10 – Volatility mac_lsof 输出
如你所见,我们还可以使用 -p 选项来标识特定进程并查看与之相关的文件。此外,我们还可以收集有关文件缓存中存储的所有文件的信息。mac_list_files 插件将帮助我们完成这项工作:

图 11.11 – Volatility mac_list_files 输出
你可以使用 mac_recover_filesystem 插件来导出文件。当然,Volatility 也有 mac_dump_file 插件,用于导出特定文件,但目前该插件在最新版本的 macOS 上显示出不佳的效果。启动 mac_recover_filesystem 插件的过程仍然保持不变:
$ vol.py --plugins=profiles -f /mnt/hgfs/flash/MacSierra_10_12_6_16G23ax64
--profile=MacSierra_10_12_6_16G23ax64 mac_recover_filesystem
-D /mnt/hgfs/flash/output/
在我们的案例中,输出文件夹的内容如下所示:

图 11.12 – Volatility mac_recover_filesystem 结果
通过这种方式,我们可以从缓存的文件系统中恢复主要位置和各种文件。在这里,你还可以找到与用户的 bash 历史相关的文件:

图 11.13 – 恢复的 bash 历史文件
该插件的缺点是,它目前在从带有 M1 芯片的主机收集的内存转储上无法正常工作。如果你使用的是旧版本的 macOS,你还可以使用 PhotoRec 工具,它支持 HFS+ 文件系统。此选项适用于 High Sierra 之前的版本,因为 macOS 10.13 或更高版本的默认文件系统是 APFS。
如你所见,从 macOS 内存中导出文件并非易事,特别是对于最新版本的操作系统。然而,也有一些积极的方面。其中之一是能够相对容易地从特定用户应用程序中恢复数据。
获取用户应用数据
默认情况下,macOS 用户可以访问 Apple 提供的内建应用程序,如日历、联系人和备忘录。由于这些应用程序的高质量和便捷性,它们赢得了用户的喜爱,也吸引了调查人员的兴趣。Volatility 提供了一套现成的插件,允许你提取上述应用程序中的数据。例如,要从 Calendar.app 中恢复事件,可以使用 mac_calendar 插件。要恢复备忘录中的内容,可以使用 mac_notesapp,而要恢复 Contacts.app 中的联系人,则可以使用 mac_contacts:
$ vol.py --plugins=profiles -f /mnt/hgfs/flash/MacSierra_10_12_6_16G23ax64
--profile=MacSierra_10_12_6_16G23ax64 mac_contacts
Volatility Foundation Volatility Framework 2.6.1
<edited>
AppleappleAppleapple Apple ?5E
Johnyphish Johny phish Johny
一旦你获得了这些数据,你可以使用正则表达式或 YARA 规则与 mac_yarascan 插件一起尝试找到更多关于该联系人的信息。例如,与该联系人相关的电子邮件地址。
由于我们讨论的是用户活动,我们不应忘记那些更为通用的插件,它们允许我们获取有关用户正在运行的程序或已连接的设备的数据。在第一种情况下,我们使用相同的插件来分析正在运行的进程。同时,如果需要将某个进程与特定用户关联,我们可以使用 mac_list_sessions 插件,它从会话哈希表中枚举会话。该插件的工作方式如下:

图 11.14 – Volatility mac_list_sessions 输出
通过这种方式,我们可以获得进程 ID、进程名称以及关联用户的名称信息。
对于连接的设备,我们可以转向熟悉的 mac_mount 和 mac_dmesg 插件:

图 11.15 – Volatility mac_mount 和 mac_dmesg 插件
正如你在图 11.15中看到的,这些插件与 Linux 系统中同名的插件完全相同。
另一个有趣的插件是 mac_keychaindump,它可以帮助恢复用户数据。顾名思义,这个插件尝试恢复可能存在的钥匙串密钥。随后,如果恢复成功,你可以尝试使用 Chainbreaker2(github.com/n0fate/chainbreaker)获取关于名称、账户、密码,以及钥匙串记录的创建和最后修改的时间戳。然而,值得注意的是,在编写本书时,最后一个正式支持的 macOS 版本是 Catalina。
当然,我们不能忘记分析与浏览器、邮件客户端和即时通讯软件相关的进程,因为它们可能包含大量有用数据,包括访问的 URL、电子邮件地址和对话内容。为了获取这些数据,我们可以分析相关进程的内存,使用 mac_memdump 或 mac_dump_maps 插件,结合关键字、正则表达式或 YARA 规则的搜索。另一方面,我们可以使用Bulk Extractor 工具和邮件解析器来提取 URL 和电子邮件地址:

图 11.16 – Bulk Extractor 邮件解析器
在输出文件夹中,我们关注两个文件——email_histogram.txt 和 url_histogram.txt,它们分别包含从内存转储中提取的所有电子邮件地址和 URL:

图 11.17 – 提取的 URLs
这样,我们可以分析不同的用户数据。我们最后讨论的话题将是如何搜索和调查恶意活动。
搜索恶意活动
在 macOS 中搜索恶意活动基本上归结为我们在前几章中处理的基本元素:寻找可疑的网络连接,寻找进程中的异常,寻找代码注入,寻找使用的钩子技术的痕迹,以及检查 shell 中执行的命令。例如,-f0L 作为命令行参数之一,用于通过 unzip 命令将受保护的归档解压到 /tmp 目录下。同时,在 shell 中运行脚本和命令也可能在更复杂的攻击中被威胁行为者使用,尤其是当他们直接访问主机时。
要查找代码注入,我们可以使用熟悉的mac_malfind插件。然而,请注意,在从 M1 芯片的主机上获取的内存转储上运行该插件可能会导致执行错误:

图 11.18 – Volatility mac_malfind 输出
这种方法对于检测通过ptrace或NSCreateObjectFileImageFromMemory API 进行的注入非常有用。另外,准备好应对大量的误报结果,这些结果需要进行二次检查。
也不要忘记查找恶意库注入进程的痕迹。在这种情况下,mac_proc_maps和mac_dyld_maps插件可能会很有用。如果恶意库试图隐藏自己,可以使用mac_ldrmodules插件,该插件将mac_proc_maps的输出与从libdl获得的库列表进行比较:

图 11.19 – Volatility mac_ldrmodules 输出
如果需要,你还可以使用mac_librarydump插件提取感兴趣的库,该插件能够从进程内存中提取任何可执行文件。
在 macOS 的恶意活动分析中,一个显著的特点是寻找持久性痕迹,因为在这个操作系统中,用于持久性的技术将不同于前面讨论的那些。威胁行为者和恶意软件最常用的技术包括以下 MITRE ATT&CK 子技术:
-
T1547.011:Plist 修改 -
T1547.007:重新打开的应用程序 -
T1547.015:登录项 -
T1543.001:启动代理 -
T1543.004:启动守护进程 -
T1546.004:Unix Shell 配置修改 -
T1053.003:Cron
前两个子技术可用于持久性和特权升级。攻击者可以修改或添加可执行文件的路径,添加命令行参数,并将键/值对插入自动启动位置的属性列表文件(plist)。要查找这些子技术的痕迹,你可以分析~/LaunchAgents和~/Library/Application Support/com.apple.backgroundtaskmanagementagent/backgrounditems.btm位置的plist文件。别忘了检查~/Library/Preferences/com.apple.loginwindow.plist、~/Library/Preferences/ByHost/com.apple.loginwindow.*.plist以及应用程序的Info.plist文件。你可以尝试从缓存的文件系统中提取这些文件,或者直接在主机上检查。
登录项、启动代理和启动守护进程子技术使用类似的方法。你应该检查~/Library/Application Support/com.apple.backgroundtaskmanagementagent/backgrounditems.btm、~/Library/Preferences/com.apple.loginitems.plist以及应用程序的/Contents/Library/Loginltems/,以查找它们的痕迹。你还应该检查/System/Library/LaunchAgents、/Library/LaunchAgents/、/Library/LaunchDaemons/和~/Library/LaunchAgents/中的新plist文件。
Unix Shell 配置修改子技术与运行终端应用程序时修改所使用的文件相关。终端基本上使用zsh,它是自 macOS Catalina 起所有 macOS 版本的默认 shell。请注意,对于传统程序,/etc/bashrc 会在启动时执行。因此,我们应该检查 /etc/profile 和 /etc/profile.d,以及 ~/.bash_profile,以查找该子技术的痕迹。你还可以检查 /etc/shells 文件,其中包含有效 shell 的文件路径列表。
最后一个子技术与我们在第九章中看到的恶意活动检测相似,因此我们在这里不会详细讨论。然而,值得一提的是,T1547.006:内核模块和扩展子技术,它涉及使用 kextload 命令加载恶意的 kext,在早期的 macOS 版本中非常流行。然而,自 macOS Catalina 起,内核扩展已被弃用。尽管如此,Volatility 提供了插件来探索已加载的内核模块和扩展:mac_lsmod 和 mac_lsmod_kext_map:

图 11.20 – Volatility mac_lsmod 输出
你还可以使用 mac_moddump 插件将指定的内核扩展导出到磁盘。此子技术常常被 rootkit 用来保持持久性和提升权限。
通常,与 Linux rootkit 一样,macOS rootkit 现在非常难以找到。然而,即使是这种罕见的情况,我们也有一些插件,可以让我们检测该类型恶意软件使用的不同钩子技术:
-
mac_apihooks– 检查 API 钩子,允许你检测内联钩子及钩子重定位表。 -
mac_check_sysctl– 列出所有sysctl值和处理程序。由于 sysctl 是允许用户空间组件与内核通信的接口,它被不同的 rootkit 广泛使用。Sysctl钩子提供了隐藏 rootkit 数据和创建后门的机会。 -
mac_check_trap_table– 检查是否有钩子影响 trap 表条目。Trap 表是为满足对 OS X 和 macOS BSD 层的请求而实现的。替换 trap 表条目可以用于 rootkit 实现,因此它也引起了威胁行为者和恶意软件的兴趣。 -
mac_notifiers– 检测添加钩子的 rootkit,这些钩子插入 I/O Kit。I/O Kit 是一组不同的工具和 API,提供与硬件设备交互的机会,并可能被 rootkit 滥用。 -
mac_trustedbsd– 列出恶意的trustedbsd策略。TrustedBSD 子系统允许你通过确定哪些进程可以访问哪些资源的策略来控制对系统资源的访问。这些策略通常是 rootkit 的目标之一。
通过搜索上述对象的异常和操作痕迹,我们可以检测到 macOS 上的 rootkit。
总结
分析 macOS 内存转储的过程与分析 Windows 或 Linux 的过程并没有太大区别。然而,有一些细节需要注意。
首先,最新版本 macOS 的 Volatility 配置文件几乎无法获得,目前,唯一相对可靠的获取方式是使用专有的内存转储解决方案,在该方案中,配置文件可以与转储一起自动创建。
其次,并非所有在旧版本 macOS 上运行良好的 Volatility 插件在最新版本的操作系统上都能显示出良好的结果。此外,插件的性能可能取决于目标主机的芯片架构,该主机是从中提取转储的设备。
第三,我们曾用于从 Windows 和 Linux 恢复文件的工具(如 PhotoRec)对于从 macOS High Sierra 开始的 macOS 版本帮助不大,因为它们不支持 APFS 文件系统。
否则,内存转储分析的方法本身保持不变。在分析用户活动时,我们倾向于关注正在运行的应用程序及其包含的动态数据,如 Apple 应用程序(如日历或联系人)、来自钥匙串的数据以及已挂载的设备。为了检测恶意活动,我们专注于检查网络连接,寻找进程中的异常,检测注入的代码和库,以及检测使用的持久性技术。


浙公网安备 33010602011771号