使用 Linux 文件系统取证进行入侵检测

调查 Linux 磁盘映像的“谁、什么、何时、何地、为什么和如何”。
299 位读者喜欢这篇文章。
How to find files in Linux

Lewis Cowles, CC BY-SA 4.0

对 Linux 磁盘映像进行取证分析通常是事件响应的一部分,以确定是否发生了入侵。与 Microsoft Windows 取证相比,Linux 取证是一个不同且引人入胜的世界。在本文中,我将分析来自可能受到威胁的 Linux 系统的磁盘映像,以便确定事件的“谁、什么、何时、何地、为什么和如何”,并创建事件和文件系统时间线。最后,我将从磁盘映像中提取感兴趣的工件。

在本教程中,我们将使用一些新工具和一些旧工具,以创造性的新方式对磁盘映像进行取证分析。

场景

Premiere Fabrication Engineering (PFE) 怀疑公司的主服务器 pfe1 发生了事件或入侵。他们认为该服务器可能卷入了一起事件,并且可能在三月初和三月底之间受到威胁。他们聘请我作为取证检查员来调查服务器是否受到威胁并卷入事件。调查将确定可能的入侵背后的“谁、什么、何时、何地、为什么和如何”。此外,PFE 还要求我为其服务器提供进一步安全措施的建议。

磁盘映像

为了对服务器进行取证分析,我要求 PFE 通过 USB 驱动器向我发送 pfe1 的取证磁盘映像。他们同意并说:“USB 正在邮寄中。” USB 驱动器到达后,我开始检查其内容。为了进行取证分析,我使用运行 SANS SIFT 发行版的虚拟机 (VM)。 SIFT 工作站是一组免费和开源的事件响应和取证工具,旨在在各种设置中执行详细的数字取证检查。 SIFT 具有广泛的取证工具,如果它没有我想要的工具,我可以轻松安装一个,因为它是一个基于 Ubuntu 的发行版。

经过检查,我发现 USB 不包含磁盘映像,而是包含 VMware ESX 主机文件的副本,这些文件是来自 PFE 混合云的 VMDK 文件。这不是我所期望的。我有几个选择:

  1. 我可以联系 PFE,并更明确地说明我希望从他们那里得到什么。在像这样的早期参与中,这样做可能不是最好的选择。
  2. 我可以将 VMDK 文件加载到 VMPlayer 等虚拟化工具中,并将其作为实时 VM 运行,使用其原生 Linux 程序来执行取证分析。至少有三个理由不这样做。首先,当 VMDK 文件作为实时系统运行时,文件和文件内容的时间戳将被更改。其次,由于服务器被认为是受到威胁的,因此必须认为 VMDK 文件系统中的每个文件和程序都受到威胁。第三,使用受威胁系统上的原生程序进行取证分析可能会产生不可预见的后果。
  3. 为了分析 VMDK 文件,我可以使用包含用于访问存储在 VMDK 文件中的数据的工具的 libvmdk-utils 包。
  4. 但是,更好的方法是将 VMDK 文件格式转换为 RAW 格式。这将使在磁盘映像中的文件上运行 SIFT 发行版中的不同工具更容易。

为了从 VMDK 转换为 RAW 格式,我使用 qemu-img 实用程序,该实用程序允许离线创建、转换和修改映像。下图显示了将 VMDK 格式转换为 RAW 格式的命令。

Converting a VMDK file to RAW format

opensource.com

接下来,我需要使用 mmls 实用程序列出磁盘映像中的分区表并获取有关每个分区从何处开始(扇区)的信息。此实用程序显示卷系统中分区的布局,包括分区表和磁盘标签。然后,我使用起始扇区并使用 fsstat 实用程序查询与文件系统关联的详细信息,该实用程序显示与文件系统关联的详细信息。下图显示了 mmlsfsstat 命令的运行。

mmls command output

opensource.com

我从 mmls 输出中学到了几件有趣的事情:Linux 主分区从 2048 扇区开始,大小约为 8 GB。 DOS 分区(可能是引导分区)的大小约为 8 MB。最后,有一个大小约为 8 GB 的交换分区。

fsstat command output

opensource.com

运行 fsstat 会告诉我关于分区的许多有用的信息:文件系统的类型、上次数据写入文件系统的时间、文件系统是否已干净地卸载以及文件系统的挂载位置。

我已经准备好挂载分区并开始分析。为此,我需要在指定的原始映像上读取分区表,并创建检测到的分区段上的设备映射。我可以手动使用 mmlsfsstat 中的信息来完成此操作,或者可以使用 kpartx 来为我完成此操作。

Using kpartx to create loopback devices

opensource.com

我使用选项来创建只读映射 (-r),添加分区映射 (-a),并给出详细的输出 (-v)。 loop0p1/dev/mapper 下的设备文件的名称,我可以使用它来访问分区。要挂载它,我运行

$ mount -o ro -o loop=/dev/mapper/loop0p1 pf1.raw /mnt

请注意,我将分区作为只读 (-o ro) 挂载,以防止意外污染。

挂载磁盘后,我通过创建时间线开始我的取证分析和调查。一些取证检查员不相信创建时间线。相反,一旦他们拥有挂载的分区,他们就会在文件系统中爬行,寻找可能与调查相关的工件。我将这些取证检查员标记为“爬行者”。虽然这是一种取证调查的方式,但它远非可重复,容易出错,并且可能遗漏有价值的证据。

我认为创建时间线是至关重要的一步,因为它包含有关文件修改、访问、更改和创建的有用信息,这些信息以人类可读的格式(称为 MAC(修改、访问、更改)时间证据)显示。此活动有助于确定事件发生的具体时间和顺序。

关于 Linux 文件系统的说明

像 ext2 和 ext3 这样的 Linux 文件系统没有文件创建/诞生时间的时间戳。创建时间戳是在 ext4 中引入的。丹·法默 (Dan Farmer) 和维策·维尼玛 (Wietse Venema) 撰写的书籍 取证发现(第一版)概述了不同的时间戳。

  • 上次修改时间: 对于目录,这是上次添加、重命名或删除条目的时间。对于其他文件类型,这是上次写入文件的时间。
  • 上次访问(读取)时间: 对于目录,这是上次搜索的时间。对于其他文件类型,这是上次读取文件的时间。
  • 上次状态更改: 状态更改的示例包括所有者更改、访问权限更改、硬链接计数更改或任何 MAC 时间的显式更改。
  • 删除时间: ext2 和 ext3 在 dtime 时间戳中记录文件被删除的时间,但并非所有工具都支持它。
  • 创建时间: ext4fs 在 crtime 时间戳中记录文件被创建的时间,但并非所有工具都支持它。

不同的时间戳存储在 inode 中包含的元数据中。 Inode 类似于 Windows 世界中的 MFT 条目号。在 Linux 系统上读取文件元数据的一种方法是首先使用命令 ls -i file 获取 inode 编号,然后对分区设备使用 istat 并指定 inode 编号。这将显示不同的元数据属性,包括时间戳、文件大小、所有者的组和用户 ID、权限以及包含实际数据的块。

创建超级时间线

我的下一步是使用 log2timeline/plaso 创建超级时间线。 Plaso 是一个基于 Python 的 Perl-based log2timeline 工具的重写,最初由 Kristinn Gudjonsson 创建并由其他人增强。使用 log2timeline 制作超级时间线很容易,但解释起来很困难。最新版本的 plaso 引擎可以解析 ext4 以及不同类型的工件,例如 syslog 消息、审计、utmp 等。

为了创建超级时间线,我针对挂载的磁盘文件夹启动 log2timeline 并使用 Linux 解析器。此过程需要一些时间。完成后,我有一个时间线,其中包含 plaso 数据库格式的不同工件,然后可以使用 psort.py 将 plaso 数据库转换为任意数量的不同输出格式。要查看 psort.py 支持的输出格式,请输入 psort -o list。我使用 psort.py 创建了一个 Excel 格式的超级时间线。下图概述了执行此操作的步骤。

Creating a super timeline in. xslx format

opensource.com

(注意:已从图像中删除无关行)

Creating a super timeline in. xslx format

opensource.com

我将超级时间线导入到电子表格程序中,以便更轻松地查看、排序和搜索。虽然您可以在电子表格程序中查看超级时间线,但在 MySQL 或 Elasticsearch 等真实数据库中使用它更容易。我创建了第二个超级时间线,并直接从 psort.py 将其发送到 Elasticsearch 实例。一旦超级时间线被 Elasticsearch 索引,我就可以使用 Kibana 可视化和分析数据。

Creating a super timeline and ingesting it into Elasticsearch

opensource.com

使用 Elasticsearch/Kibana 进行调查

正如法瑞尔士官长所说,“通过准备和纪律,我们是自己命运的主人。” 在分析过程中,保持耐心和细致,避免成为一个“偷窥者”非常重要。 超级时间线分析的一个帮助是了解事件可能发生的时间。 在本例中(双关语),客户表示事件可能发生在三月份。 我仍然考虑客户对时间框架的判断可能不正确。 掌握这些信息后,我开始缩小超级时间线的时间范围,并逐步缩小范围。 我正在寻找与假设的事件日期具有“时间邻近性”的感兴趣的工件。 目标是根据不同的工件重建发生的事情。

为了缩小超级时间线的范围,我使用了我设置的Elasticsearch/Kibana实例。 使用Kibana,我可以设置任意数量的复杂仪表板来显示和关联感兴趣的取证事件,但我希望避免这种复杂程度。 相反,我选择感兴趣的索引进行显示,并创建一个按日期显示的活动条形图。

Activity on pfe1 over time

opensource.com

下一步是展开图表末尾的大条。

Activity on pfe1 during March

opensource.com

3月5日有一个大条。 我展开该条以查看该特定日期的活动。

Activity on pfe1 on 05-Mar

opensource.com

查看超级时间线的日志文件活动,我发现此活动来自软件安装/升级。 在这个活动领域中几乎找不到任何东西。

Log listing from pfe1 on 05-Mar

opensource.com

我回到Kibana查看系统上的最后一组活动,并在日志中找到这些内容。

Last activity on pfe1 before shutdown

opensource.com

系统上的最后一个活动之一是用户john从名为xingyiquan的目录安装了一个程序。 邢意拳是一种与功夫和太极拳类似的中国武术。 用户john从他自己的用户帐户在公司服务器上安装一个武术程序似乎很奇怪。 我使用Kibana的搜索功能在日志文件中查找xingyiquan的其他实例。 我在3月5日、3月9日和3月12日发现了三个围绕字符串xingyiquan的活动周期。

xingyiquan activity on pfe1

opensource.com

接下来,我查看这些日期的日志条目。 我从3月5日开始,发现使用Firefox浏览器和Google搜索引擎搜索名为xingyiquan的rootkit的证据。 Google搜索在packetstormsecurity.com上找到了这种rootkit的存在。 然后,浏览器访问了packetstormsecurity.com,并将一个名为xingyiquan.tar.gz的文件从该站点下载到用户john的下载目录中。

Search and download of xingyiquan.tar.gz

opensource.com

尽管似乎用户john访问了google.com搜索rootkit,然后访问packetstormsecurity.com下载rootkit,但这些日志条目并未指明搜索和下载背后的用户。 我需要进一步调查。

Firefox浏览器将其历史信息保存在用户主目录(即用户john)下的.mozilla目录中的SQLite数据库中,文件名为places.sqlite。 为了查看数据库中的信息,我使用一个名为sqlitebrowser的程序。 这是一个GUI应用程序,允许用户深入到SQLite数据库中并查看其中存储的记录。 我启动了sqlitebrowser,并从用户john主目录下的.mozilla目录导入了places.sqlite。 结果如下所示。

Search and download history of user john

opensource.com

最右边一列的数字是左侧活动的时间戳。 作为一致性测试,我将时间戳1425614413880000转换为人类可读的时间,得到2015年3月5日晚上8:00:13.880。 这与Kibana的2015年3月5日20:00:00.000非常吻合。 我们可以合理地确定用户john搜索了一个名为xingyiquan的rootkit,并将一个名为xingyiquan.tar.gz的文件从packetstormsecurity.com下载到用户john的下载目录中。

使用MySQL进行调查

此时,我决定将超级时间线导入到MySQL数据库中,以获得比Elasticsearch/Kibana单独使用更大的搜索和操作数据的灵活性。

构建xingyiquan rootkit

我将从plaso数据库创建的超级时间线加载到MySQL数据库中。 通过使用Elasticsearch/Kibana,我知道用户john从packetstormsecurity.com将rootkit xingyiquan.tar.gz下载到下载目录。 这是来自MySQL时间线数据库的下载活动证据。

Downloading the xingyiquan.tar.gz rootkit

opensource.com

下载rootkit后不久,tar.gz存档中的源代码被提取出来。

Extracting the rootkit source from the tar.gz archive

opensource.com

在3月9日之前,对rootkit没有任何操作,当时不良行为者使用More程序读取了rootkit的README文件,然后编译并安装了该rootkit。

Building the xingyiquan rootkit

opensource.com

命令历史记录

我将pfe1上所有具有bash命令历史记录的用户的历史记录加载到MySQL数据库的表中。 加载历史记录后,我可以轻松使用如下查询显示它们:

select * from histories order by recno;

要获取特定用户的历史记录,我使用如下查询:

select historyCommand from histories where historyFilename like '%<username>%' order by recno;

我从用户john的bash历史记录中发现了几条有趣的命令。 也就是说,用户john创建了johnn帐户,删除它,再次创建它,将/bin/true复制到/bin/false,为whoopsie和lightdm帐户提供了密码,将/bin/bash复制到/bin/false,编辑了密码和组文件,将用户johnn的主目录从johnn移动到.johnn(使其成为隐藏目录),在使用sed查找如何使用后,使用sed更改了密码文件sed,最后安装了xingyiquan rootkit。

User john's activity

opensource.com

接下来,我查看用户johnn的bash命令历史记录。 它没有显示任何异常活动。

User johnn's activity

opensource.com

注意到用户john将/bin/bash复制到/bin/false,我通过检查这些文件的大小并获取文件的MD5哈希值来测试这是否属实。 如下所示,文件大小和MD5哈希值相同。 因此,文件是相同的。

Checking /bin/bash and /bin/false

opensource.com

调查成功和失败的登录

为了回答“何时”问题的一部分,我将包含登录、注销、系统启动和关闭数据的日志文件加载到MySQL数据库的表中。 使用一个简单的查询,例如:

select * from logins order by start

我发现以下活动

Successful logins to pfe1

opensource.com

从这张图中,我看到用户john从IP地址192.168.56.1登录到pfe1。 五分钟后,用户johnn从同一个IP地址登录到pfe1。 两次用户lightdm的登录在四分钟后和一分钟后,然后用户johnn在不到一分钟后登录。 然后pfe1被重启。

查看不成功的登录,我发现了这个活动

Unsuccessful logins to pfe1

opensource.com

同样,用户lightdm试图从IP地址192.168.56.1登录到pfe1。 鉴于虚假帐户登录到pfe1,我对PFE的建议之一是检查IP地址为192.168.56.1的系统,以查找是否存在被入侵的证据。

调查日志文件

对成功和失败登录的分析提供了关于事件发生时间的宝贵信息。 我将注意力转向调查pfe1上的日志文件,特别是/var/log/auth*中的身份验证和授权活动。 我将pfe1上的所有日志文件加载到MySQL数据库表中,并使用如下查询

select logentry from logs where logfilename like '%auth%' order by recno;

并将其保存到一个文件中。 我用我最喜欢的编辑器打开该文件,并搜索192.168.56.1。 以下是活动的一部分

Account activity on pfe1

opensource.com

这部分显示用户john从IP地址192.168.56.1登录,并创建了johnn帐户,删除了johnn帐户,并再次创建了它。 然后,用户johnn从IP地址192.168.56.1登录到pfe1。 接下来,用户johnn试图使用su命令成为用户whoopsie,但失败了。 然后,用户whoopsie的密码被更改。 用户johnn接下来试图使用su命令成为用户lightdm,这也失败了。 这与图21和图22中显示的活动相关。

我的调查结论

  • 用户john在服务器pfe1上搜索、下载、编译和安装了一个名为xingyiquan的rootkit。 xingyiquan rootkit隐藏进程、文件、目录、进程和网络连接;添加后门;等等。
  • 用户john在pfe1上创建、删除并重新创建了另一个名为johnn的帐户。 用户john将用户johnn的主目录设置为隐藏文件,以模糊该用户帐户的存在。
  • 用户john将文件/bin/true覆盖到/bin/false,然后将/bin/bash覆盖到/bin/false,以方便通常不用于交互式登录的系统帐户的登录。
  • 用户john为系统帐户whoopsie和lightdm创建了密码。 这些帐户通常没有密码。
  • 用户帐户johnn已成功登录,用户johnn未成功尝试成为用户whoopsie和lightdm。
  • 服务器pfe1已被严重入侵。

我对PFE的建议

  • 从原始发行版重建服务器pfe1,并在将其返回服务之前应用系统所有相关的补丁。
  • 设置一个集中式syslog服务器,并让PFE混合云中的所有系统将日志记录到集中式syslog服务器 *和* 本地日志,以整合日志数据并防止篡改系统日志。 使用安全信息和事件管理 (SIEM) 产品来促进安全事件审查和关联。
  • 在所有公司服务器上实施bash命令时间戳。
  • 在所有PFE服务器上启用root帐户的审计日志记录,并将审计日志定向到集中式syslog服务器,在那里可以将其与其他日志信息相关联。
  • 调查IP地址为192.168.56.1的系统是否存在漏洞和妥协,因为它被用作入侵pfe1的支点。

如果您使用了取证方法来分析您的Linux文件系统是否存在漏洞,请在评论中分享您的技巧和建议。


Gary Smith今年将在西北LinuxFest上发言。 请参阅节目亮点注册参加

User profile image.
Gary的职业生涯始于化学家/材料工程师。

7 条评论

文章不错,有逐步分析。 好工作 !

很棒的文章。 我特别喜欢封面图片 ;-)

好文章。

哇...非常好的文章.. 带有详细的分析。 学到了一些东西.. ?? 谢谢你..

用户john如何获得运行useradd的授权,或者用户是否利用已知的漏洞来提升权限?

谢谢 !
您提到了 ElasticSearch/kibana:ELK Stack(带有 Logstash 和 Kibana 的 ElasticSearch)是一个很好的开源解决方案。 现在它提供了用于监控和日志分析的机器学习选项!

很棒的文章!!! 我学到了一些新东西,你再次激发了我对安全的兴趣 ;-)

知识共享许可协议本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.