简介
在本实验中,你将学习攻击者如何维持持久化访问并规避基础检测。虽然像 Metasploit 这样的自动化框架使用 Meterpreter 将载荷无缝迁移到稳定的 Windows 进程(如 explorer.exe 或 svchost)中,但 Linux 环境需要不同的方法。
其核心原则与平台无关:攻击者更倾向于隐藏在长期运行、外观普通的执行上下文中,而不是不稳定或明显可疑的进程中。
在 Linux 中,攻击者通过识别稳定的系统进程并使用「进程名称伪造」(Process Name Spoofing)来伪装其恶意载荷,从而达到相同的规避目的。你将学习如何对运行中的进程进行侦察,识别受信任的系统组件,并执行一个伪装成合法内核线程的载荷以规避检测。
这既关乎稳定性,也关乎人类的感知。防御者在查看庞大的进程列表时,更容易忽略那些融入了预期系统噪声的名称。
查看运行中的进程 (ps)
在这一步中,你将学习如何列出并分析 Linux 系统中运行的进程。攻击者利用这一侦察阶段来了解环境,并寻找可以冒充的合法进程。
同样,枚举是第一步。如果你不知道主机上「正常」的状态是什么样,就无法选择一个可信的伪装进程。
ps (process status) 命令是查看活动进程的标准工具。要全面查看系统上运行的所有进程,可以使用 aux 参数。
在终端中运行以下命令以查看运行中的进程:
ps aux | head -n 15
a 参数显示所有用户的进程,u 显示面向用户的格式(包括 CPU 和内存使用情况),x 显示未连接到终端的进程。我们将输出通过管道传递给 head -n 15,以便仅显示前 15 行,使输出易于管理。
你应该会看到类似以下的输出:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 167008 11468 ? Ss 10:00 0:01 /sbin/init
root 2 0.0 0.0 0 0 ? S 10:00 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? I< 10:00 0:00 [rcu_gp]
root 4 0.0 0.0 0 0 ? I< 10:00 0:00 [rcu_par_gp]
root 5 0.0 0.0 0 0 ? I< 10:00 0:00 [slub_flushwq]
root 6 0.0 0.0 0 0 ? I< 10:00 0:00 [netns]
root 8 0.0 0.0 0 0 ? I< 10:00 0:00 [kworker/0:0H-events_highpri]
root 10 0.0 0.0 0 0 ? I< 10:00 0:00 [mm_percpu_wq]
root 11 0.0 0.0 0 0 ? S 10:00 0:00 [rcu_tasks_rude_]
root 12 0.0 0.0 0 0 ? S 10:00 0:00 [rcu_tasks_trace]
root 13 0.0 0.0 0 0 ? S 10:00 0:00 [ksoftirqd/0]
root 14 0.0 0.0 0 0 ? I 10:00 0:00 [rcu_sched]
root 15 0.0 0.0 0 0 ? S 10:00 0:00 [migration/0]
root 16 0.0 0.0 0 0 ? S 10:00 0:00 [idle_inject/0]
注意那些用方括号括起来的进程,例如 [kthreadd] 或 [kworker/0:0H-events_highpri]。这些是内核线程。它们高度稳定,持续运行,且很少受到系统管理员的检查,因此是规避检测的绝佳目标。
识别稳定的目标进程
在这一步中,你将识别出适合规避检测的特定进程。稳定的进程通常是自动启动并长期运行的系统守护进程或桌面服务。
如果攻击者的载荷崩溃,他们就会失去访问权限。通过将载荷伪装成稳定进程,他们可以避免引起怀疑。在某些 Linux 环境中,kworker 条目很容易观察到,并且是一个方便的命名模型,因为它们的名称看起来很专业,能够融入冗长的进程列表中。
让我们检查一下当前环境是否显示任何 kworker 风格的名称。运行以下命令:
ps -ef | grep kworker | head -n 5
-e 参数选择所有进程,-f 执行全格式列表。我们使用 grep 过滤出仅包含 "kworker" 的行。
如果环境暴露了内核工作线程条目,你可能会看到类似以下的输出:
root 8 2 0 10:00 ? 00:00:00 [kworker/0:0H-events_highpri]
root 25 2 0 10:00 ? 00:00:00 [kworker/1:0H-events_highpri]
root 31 2 0 10:00 ? 00:00:00 [kworker/2:0H-events_highpri]
root 37 2 0 10:00 ? 00:00:00 [kworker/3:0H-events_highpri]
root 43 2 0 10:00 ? 00:00:00 [kworker/0:1-events]
如果你只看到 grep 命令本身而没有看到真实的 kworker 条目,这在实验环境中是可以接受的。我们将在下一步中使用熟悉的 [kworker/X:Y] 命名风格,因为我们的目标是学习进程名称伪造的工作原理,而不是依赖于特定的内核线程是否可见。
迁移到稳定进程
在这一步中,你将通过启动一个长期运行的进程并伪造其进程名称来模拟进程迁移。
在 ~/project 目录下已经为你准备了一个名为 malicious_payload.sh 的虚拟载荷,但这里有一个重要的 Linux 细节。当你运行 shell 脚本时,进程列表通常会显示解释器,例如 /bin/bash /home/labex/project/malicious_payload.sh。这种行为使得伪造的名称在此环境中难以清晰观察。
为了使伪造过程易于验证,我们将改用一个简单的长期运行命令。安全概念是一样的:我们给进程一个具有误导性的可见名称,使其融入进程列表。
执行以下命令以启动一个伪装的后台进程:
bash -c 'exec -a "[kworker/u4:2]" sleep 600' &
bash -c 部分启动一个新的 Bash 进程并运行随后的命令字符串。exec -a "[kworker/u4:2]" 将该 Bash 进程替换为 sleep 600,但告诉操作系统将进程名称显示为 [kworker/u4:2]。sleep 600 命令使进程保持足够长的时间以便你进行检查。末尾的 & 将进程置于后台运行。
你将看到一小段输出,指示后台作业编号和进程 ID (PID),类似于:
[1] 1337
你伪装的进程现在正在后台静默运行,并且应该以伪造的名称显示。
验证持久化与访问
在最后一步中,你将验证伪装的进程是否以其伪造的身份显示,然后将其清理。
搜索你在上一步中分配的伪造名称:
ps aux | grep "kworker/u4:2"
你应该会看到类似以下的输出:
labex 1337 0.0 0.0 7008 1536 pts/0 S 10:15 0:00 [kworker/u4:2]
labex 1345 0.0 0.0 6480 2272 pts/0 S+ 10:16 0:00 grep --color=auto kworker/u4:2
在此环境中,伪装的进程只是用 sleep 创建的演示,并非真正的内核工作线程。重点在于,进程列表中可见的名称现在看起来像是一个受信任的系统组件。
最后,通过终止包含伪造名称的命令行来清理演示进程。运行以下命令:
pkill -f "kworker/u4:2"
你可以再次运行 ps aux | grep "kworker/u4:2" 以确认伪装的进程已被成功终止。
总结
恭喜!你已成功完成了「进程迁移与规避」实验。
你学习了攻击者如何分析运行中的进程以识别稳定、受信任的系统组件。你还学习了如何使用进程名称伪造 (exec -a) 将恶意载荷伪装成合法的内核线程,有效地模拟了 Meterpreter 等高级框架使用的规避技术。最后,你验证了伪装进程的隐蔽性并学会了如何正确终止它。这些技能对于理解持久化威胁如何在 Linux 环境中隐藏至关重要。



