本页介绍了您可以执行哪些任务来确认 Virtual Machine Threat Detection 中的内核模式根 kit 检测结果的有效性。内核模式 rootkit 发现结果表明,虚拟机的内核内存可能已被恶意软件篡改。
当您收到来自 VM Threat Detection 的内核模式 rootkit 发现结果时,我们建议您在受影响的 Compute Engine 实例上运行以下 Linux 命令,以探查系统中可能表明异常的数据点,例如被盗用的系统调用或隐藏的内核模块。
或者,您也可以在受影响的虚拟机上运行提供的数据收集脚本。该脚本会执行本页介绍的命令。
除非另有说明,否则本页上的每个检查任务都与所有内核模式根 kit 发现结果相关。
本文档假定您满足以下条件:
您在收到 VM Threat Detection 发送的内核模式根 kit 发现结果后,执行本文档中的任务。如需查看相关发现结果类别的列表,请参阅内核模式的根 kit 威胁发现结果。
您了解 Linux 命令行工具和 Linux 内核。
VM Threat Detection 简介
Virtual Machine Threat Detection 是 Security Command Center 的一项内置服务,在 Enterprise 和 Premium 层级提供。此服务会扫描 Compute Engine 实例,以检测在遭到破解的云环境中运行的潜在恶意应用,例如加密货币挖矿软件、内核模式 rootkit 和恶意软件。
VM Threat Detection 是 Security Command Center 威胁检测套件的一部分,旨在补充 Event Threat Detection 和 Container Threat Detection 的现有功能。
如需了解 VM Threat Detection,请参阅 Virtual Machine Threat Detection 概览。如需了解如何查看 VM Threat Detection 发现结果的详细信息,请参阅在 Google Cloud 控制台中查看发现结果。
准备工作
如需获得查看 Security Command Center 中的所有资源和发现以及管理受影响的 Compute Engine 实例所需的权限,请让您的管理员为您授予以下 IAM 角色:
-
组织的 Security Center Admin Viewer (
roles/securitycenter.adminViewer
) -
针对 Compute Engine 实例的 Compute Instance Admin (v1) (
roles/compute.instanceAdmin.v1
)
如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
确定受影响的虚拟机
- 查看发现结果的详细信息。
- 在受影响的资源部分的资源全名字段中,点击链接。受影响 Compute Engine 实例的详细信息视图会在新标签页中打开。
- 连接到实例。如需了解详情,请参阅 Compute Engine 文档中的连接到 Linux 虚拟机。
查找意外的内核模块
如果虚拟机中存在意外模块,则可能表示虚拟机的内核内存可能已遭到入侵。
如需查找意外的 kernel 模块,请按以下步骤操作:
列出虚拟机中所有已加载的内核模块:
lsmod cat /proc/modules
列出已加载和已卸载模块的
sysfs
条目:ls -l /sys/module/
将这些列表的结果与项目中其他虚拟机的列表进行比较。查找在受影响的虚拟机中显示但在其他虚拟机中未显示的模块。
在 syslog
中搜索树外模块
虚拟机中已加载非树模块的迹象可能表明已加载非典型内核模块。您可以搜索内核日志缓冲区和 syslog
消息,以确定是否已加载非树模块。在日志条目中,树外模块被标记为已污染的加载。
在内核日志缓冲区和 syslog
消息中,搜索类似于以下内容的日志条目:
MODULE_NAME: loading out-of-tree module taints kernel.
搜索内核日志缓冲区,查找指示存在树外模块的日志条目:
sudo dmesg | grep out-of-tree
搜索所有
syslog
消息,查找指示存在树外模块的日志条目:grep "out-of-tree" /var/log/syslog*
检查是否有热修补
虚拟机中的实时修补可能会干扰 VM Threat Detection 检测,并可能会触发误报发现结果。
如需检查是否有实时修补,请按以下步骤操作:
请检查
syslog
,了解实时修补模块安装和日志记录。实时修补通常通过安装内核ftrace
点来修改内核代码。sudo grep livepatch /var/log/syslog*
搜索为实时修补而安装的新内核模块(通常带有
livepatch
前缀):sudo lsmod | grep livepatch
搜索补丁文件:
sudo ls -l /sys/kernel/livepatch
如需了解实时修补,请参阅 Linux 内核文档中的 Livepatch。
检查虚拟机中是否检测到其他可能的恶意活动
- 在 Security Command Center 中,查看您要调查的 VM Threat Detection 发现结果的详细信息。
- 在受影响的资源部分的资源全名字段中,点击下拉箭头,然后点击显示使用此资源全名的所有发现结果。发现结果查询会更新为仅显示此虚拟机的发现结果。
- 检查是否有任何发现指向潜在的挖矿活动、恶意软件、异常的 IAM 授权和其他安全威胁。
检查杀毒软件是否导致了假正例检测结果
杀毒软件可能会干扰 VM Threat Detection 检测,并可能会触发误报发现结果。
检查系统上所有正在运行的进程
存在意外进程可能表明 VM Threat Detection 发现结果有效,并且虚拟机已遭到入侵。
列出虚拟机上运行的所有进程:
ps -eAf
查找您通常不会在此虚拟机上运行的调试程序进程,例如
gdb
、strace
和pstack
。Debugger 程序进程可以窥探其他进程。在虚拟机上查找其他可疑进程。
检查已启动的内核
检查已启动的内核以确定您的 Linux 内核:
cat /proc/version
如果返回的值不是您预期的内核版本,则可能表示存在利用内核中的 kexec
工具进行的盗用攻击。kexec
工具可以软启动系统以使用其他内核。
针对 Unexpected kernel code modification
发现的其他任务
本部分中的任务仅适用于 Defense Evasion: Unexpected
kernel code modification
发现类别。请执行以下部分中的任务,以验证此类别中的发现结果的有效性。
这些部分可帮助您确定您的虚拟机是否在使用调试程序 API。Debugger API 可能会触发误报,因为它们可以修改正在运行的核心的代码区域。
通常,如果 VM Threat Detection 检测到使用了调试程序 API,则不会生成发现结果。不过,如果您的虚拟机使用的是 VM Threat Detection 不认识的调试程序 API,您仍然可能会收到误报。
检查是否启用了调试跟踪器
跟踪器(nop
跟踪器除外)可能会导致内核代码修改。这些进程可能会干扰 VM Threat Detection 检测,并触发假正例发现结果。通常,如果 VM Threat Detection 检测到存在跟踪器,则不会发送 Defense Evasion: Unexpected kernel code
modification
发现结果。
如需检查已启用的调试跟踪器,请按以下步骤操作:
查看可用的跟踪工具:
cat /sys/kernel/debug/tracing/available_tracers
输出类似以下内容:
hwlat blk mmiotrace function_graph wakeup_dl wakeup_rt wakeup function nop
检查当前的跟踪器:
cat /sys/kernel/debug/tracing/current_tracer
结果是上一个命令中返回的可用跟踪器之一。
确认系统是否启用了跟踪:
cat /sys/kernel/debug/tracing/tracing_on
值
1
表示系统上已启用跟踪。列出启用了跟踪功能的 CPU:
cat /sys/kernel/debug/tracing/tracing_cpumask
查看跟踪记录详情:
cat /sys/kernel/debug/tracing/trace_stat/function*
输出类似以下内容:
Function Hit Time Avg s^2
检查调试跟踪器事件
内核中的事件监控可能会导致内核代码修改,并导致虚拟机威胁检测发现结果出现误报。许多调试和性能监控工具都可以自动启用事件监控。
如需检查事件监控是否已启用,请运行以下命令:
cat /sys/kernel/debug/tracing/events/enable
cat /sys/kernel/debug/tracing/events/*/enable
如果输出为 0
,则表示事件监控已停用。如果输出为 1
,则表示事件监控已启用。
不妨停用事件监控,看看 VM Threat Detection 是否会发出相同的发现结果。如果发现结果减少了,则可能表示一些初始发现结果是误报。
检查 kprobe、eBPF 规则和 netfilter
Netfilter、kprobe 和 eBPF 规则可能会触发代码修改,因为它们会触发对自定义回调的调用转移。VM Threat Detection 会检测这些探测的存在情况,并将其映射到经过修改的代码页,而不考虑哪些探测可能会触发误报。
如需检查 kprobe、eBPF 规则和 netfilter,请运行以下命令:
iptable -L
cat /sys/kernel/debug/kprobes/enabled
cat /sys/kernel/debug/kprobes/list
cat /sys/kernel/debug/kprobes/blacklist
cat /sys/kernel/debug/tracing/enabled_functions
sudo apt-get update && sudo apt-get install bpftrace
bpftrace -l
sudo apt install linux-tools-`uname -r`
bpftool prog
检查是否有早期调试跟踪器
启动时启用的早期调试跟踪器的存在可能会干扰 VM Threat Detection 检测,并可能会触发误报。
如需检查是否有早期调试跟踪器,请运行以下命令:
cat /proc/cmdline
如需查看可能的早期调试跟踪器的列表,请参阅 Linux 内核文档中的启动时跟踪。
Unexpected system call handler
的其他任务
如果您收到 Defense Evasion: Unexpected system call handler
发现结果,请执行此任务。
审核系统调用,并查找其使用情况和调用方中的异常。审核日志会提供有关调用进程和系统调用的参数的信息。您还可以执行验证任务,检查常见系统调用的预期行为。如需了解详情,请参阅本页上的使用 Diamorphine 根木马进行的检查示例。
Unexpected interrupt handler
的其他任务
如果您收到 Defense Evasion: Unexpected interrupt handler
发现结果,请执行此任务。
列出系统上的实时中断处理程序,并将结果与项目中其他类似虚拟机中的信息进行比较。意外的中断处理程序可能表明虚拟机已遭到入侵。
如需列出实时中断处理程序,请运行以下命令:
cat /proc/interrupts
输出类似以下内容:
CPU0 CPU1 0: 44 0 IO-APIC 0-edge timer 1: 9 0 IO-APIC 1-edge i8042 4: 17493 0 IO-APIC 4-edge ttyS0 8: 0 0 IO-APIC 8-edge rtc0 9: 0 0 IO-APIC 9-fasteoi acpi 12: 0 152 IO-APIC 12-edge i8042 24: 16 0 PCI-MSI 81920-edge virtio2-config 25: 0 40194 PCI-MSI 81921-edge virtio2-inflate 26: 58528 0 PCI-MSI 81922-edge virtio2-deflate 27: 0 966356 PCI-MSI 81923-edge virtio2-stats 28: 0 0 PCI-MSI 49152-edge virtio0-config 29: 0 0 PCI-MSI 49153-edge virtio0-control 30: 0 0 PCI-MSI 49154-edge virtio0-event 31: 0 555807 PCI-MSI 49155-edge virtio0-request 32: 0 0 PCI-MSI 98304-edge virtio3-config 33: 184 0 PCI-MSI 98305-edge virtio3-input 34: 0 0 PCI-MSI 65536-edge virtio1-config 35: 556203 0 PCI-MSI 65537-edge virtio1-input.0 36: 552746 1 PCI-MSI 65538-edge virtio1-output.0 37: 1 426036 PCI-MSI 65539-edge virtio1-input.1 38: 0 408475 PCI-MSI 65540-edge virtio1-output.1
Unexpected processes in runqueue
的其他任务
如果您收到 Defense Evasion: Unexpected processes in
runqueue
发现结果,请执行以下步骤。本部分可帮助您收集更多数据点,以调查您的发现结果。这些数据点可能并不能直接表明存在恶意软件问题。
在此任务中,您将查看每个 CPU 的调度器队列。虽然某些进程可能短暂存在,但您仍然可以根据每个 CPU 的运行进程评估调度器队列行为,以查找异常行为。
显示每个正在运行的进程在每个 CPU 上花费的时间的详细信息。这有助于您了解特定 CPU 是否非常繁忙。您可以将结果与从
/proc/interrupts
固定到 CPU 的中断相关联。cat /proc/schedstat
如需详细了解此命令,请参阅 Linux 内核文档中的调度程序统计信息。
列出当前所有可运行任务,以及每个 CPU 的上下文切换详细信息。
cat /proc/sched_debug
输出类似以下内容:
Sched Debug Version: v0.11, 5.4.0-1081-gke #87-Ubuntu ktime : 976187427.733850 sched_clk : 976101974.761097 cpu_clk : 976101973.335113 jiffies : 4538939132 sched_clock_stable() : 1 sysctl_sched .sysctl_sched_latency : 12.000000 .sysctl_sched_min_granularity : 1.500000 .sysctl_sched_wakeup_granularity : 2.000000 .sysctl_sched_child_runs_first : 0 .sysctl_sched_features : 2059067 .sysctl_sched_tunable_scaling : 1 (logarithmic) cpu#0, 2199.998 MHz .nr_running : 0 .nr_switches : 16250401 .nr_load_updates : 0 .nr_uninterruptible : 12692 .next_balance : 4538.939133 .curr->pid : 0 .clock : 976101971.732857 .clock_task : 976101971.732857 .avg_idle : 880408 .max_idle_balance_cost : 500000 runnable tasks: S task PID tree-key switches prio wait-time sum-exec sum-sleep ----------------------------------------------------------------------------------------------------------- S systemd 1 51740.602172 326778 120 0.000000 165741.786097 0.000000 0 0 /init.scope S kthreadd 2 1482297.917240 1361 120 0.000000 112.028205 0.000000 0 0 / I rcu_sched 11 1482642.606136 1090339 120 0.000000 17958.156471 0.000000 0 0 / S cpuhp/1 15 537.058588 8 120 0.000000 2.275927 0.000000 0 0 / S idle_inject/1 16 -2.994953 3 49 0.000000 0.012780 0.000000 0 0 / S migration/1 17 0.000000 245774 0 0.000000 5566.508869 0.000000 0 0 / S ksoftirqd/1 18 1482595.656315 47766 120 0.000000 1235.099147 0.000000 0 0 / I kworker/1:0H 20 536.961474 5 100 0.000000 0.043908 0.000000 0 0 / S kdevtmpfs 21 11301.343465 177 120 0.000000 3.195291 0.000000 0 0 / I netns 22 6.983329 2 100 0.000000 0.021870 0.000000 0 0 / Srcu_tasks_kthre 23 10.993528 2 120 0.000000 0.010200 0.000000 0 0 / S kauditd 24 1482525.828948 319 120 0.000000 14.489652 0.000000 0 0 /
请查找以下内容:
- 正在运行的进程名称。
- 每个 CPU 的上下文切换次数。了解进程在 CPU 上是否发生了过少或过多的切换。
- 所花费的 CPU 时间(非空闲时间)。
使用 Diamorphine 根木马进行检查的示例
本部分演示了如何检查安装了 Diamorphine 根木马的虚拟机。Diamorphine 是一种常用的可加载内核模块 (LKM)。此根木马会触发以下发现结果类别:
Defense Evasion: Unexpected system call handler
Defense Evasion: Unexpected kernel modules
Defense Evasion: Unexpected kernel read-only data modification
如需详细了解这些发现类别,请参阅内核模式根 kit 威胁发现结果。
所采取的检查步骤和在虚拟机上观察到的症状如下:
在
syslog
中搜索已加载的所有树外内核模块。搜索内核日志缓冲区:
sudo dmesg | grep out-of-tree
输出:
diamorphine: loading out-of-tree module taints kernel.
搜索
syslog
消息:grep "out-of-tree" /var/log/syslog*
输出:
/var/log/syslog: diamorphine: loading out-of-tree module taints kernel.
搜索
syslog
以查找任何模块验证失败情况(此功能并非适用于所有 Linux 发行版)。搜索内核日志缓冲区:
sudo dmesg | grep "module verification failed"
输出:
diamorphine: module verification failed: signature and/or required key missing - tainting kernel
搜索
syslog
消息:sudo grep "module verification failed" /var/log/syslog*
输出:
/var/log/syslog: diamorphine: module verification failed: signature and/or required key missing - tainting kernel
确认该模块已从
/proc/modules
和lsmod
命令中隐藏。sudo grep diamorphine /proc/modules sudo lsmod | grep diamorphine
没有显示任何结果。
确认该模块在
sysfs
中具有条目。sudo cat /sys/module/diamorphine/coresize
输出:
16384
获取架构的系统调用表:
sudo ausyscall --dump
输出:
Using x86_64 syscall table: 0 read 1 write 2 open 3 close
审核系统调用(例如
kill
和getdents
)中的异常情况,这些调用通常会被 rootkit 篡改。如需检查系统调用处理程序是否遭到篡改,请审核系统调用并检查是否存在异常行为。这些行为因系统调用而异。
通常被黑客入侵的系统调用是
kill
调用。您可以检查kill
系统调用是否已被绕过。在以下示例中,系统对kill
系统调用进行了审核。安装
auditd
,并在没有 Diamorphine 恶意软件库的情况下观察虚拟机的行为:$ sudo apt-get update && sudo apt-get install auditd $ # Add audit rules for specific system calls $ sudo echo "-a exit,always -F arch=b64 -S kill -k audit_kill" >> /etc/audit/rules.d/audit.rules $ sudo /etc/init.d/auditd restart Restarting auditd (via systemctl): auditd.service. $ # Behavior observed without rootkit $ sleep 600 & [1] 1119 $ sudo kill -9 1119 $ sudo ausearch -k audit_kill | grep -A 3 "pid=1119" type=OBJ_PID msg=audit(1677517839.523:198): opid=1119 oauid=1001 ouid=0 oses=1 obj=unconfined ocomm="sleep" type=SYSCALL msg=audit(1677517839.523:198): arch=c000003e syscall=62 success=yes exit=0 a0=45f a1=9 a2=0 a3=7f61c64b2ac0 items=0 ppid=1034 pid=1035 auid=1001 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="bash" exe="/usr/bin/bash" subj=unconfined key="audit_kill" $ sleep 600 & [1] 1087 $ sudo kill -31 1087 $ sudo ausearch -k audit_kill | grep -A 3 "pid=1087" type=OBJ_PID msg=audit(1677517760.844:168): opid=1087 oauid=1001 ouid=0 oses=1 obj=unconfined ocomm="sleep" type=SYSCALL msg=audit(1677517760.844:168): arch=c000003e syscall=62 success=yes exit=0 a0=43f a1=1f a2=0 a3=7f61c64b2ac0 items=0 ppid=1034 pid=1035 auid=1001 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="bash" exe="/usr/bin/bash" subj=unconfined key="audit_kill"
在检查过程中,此时安装了 Diamorphine 根 kit。以下步骤展示了安装 rootkit 后的虚拟机行为。
确认在安装 Diamorphine 根木马后,信号的审核日志条目现在不存在:
$ sudo ausearch -k audit_kill | grep -A 3 "pid=1158" $ sleep 600 & [2] 1167
查看信号的审核日志条目中的详细信息。在此示例中,虽然此特定信号并未被 Rootkit 完全盗用,但可以获取有关调用方进程的信息。
$ sudo kill -9 1167 $ sudo ausearch -k audit_kill | grep -A 3 "pid=1167" type=OBJ_PID msg=audit(1677518008.586:237): opid=1167 oauid=1001 ouid=0 oses=1 obj=unconfined ocomm="sleep" type=SYSCALL msg=audit(1677518008.586:237): arch=c000003e syscall=62 success=yes exit=0 a0=48f a1=9 a2=0 a3=7f61c64b2ac0 items=0 ppid=1034 pid=1035 auid=1001 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="bash" exe="/usr/bin/bash" subj=unconfined key="audit_kill"
调试数据收集脚本
以下脚本会执行本页介绍的许多调试任务。您可以在 sudo
或 root
模式下运行此脚本。该脚本仅从系统读取调试信息。
$ cat kprot.sh
#!/bin/bash
echo "Boot command line"
cat /proc/cmdline
echo "=================================================="
echo "Loaded modules"
cat /proc/modules
echo "=================================================="
echo "Current tracer"
cat /sys/kernel/debug/tracing/current_tracer
echo "=================================================="
echo "Tracing event enable"
cat /sys/kernel/debug/tracing/events/enable
echo "=================================================="
echo "Tracing sub events enable"
for en in `find /sys/kernel/debug/tracing/events/*/enable`; do printf "\b$en\n"; cat $en; done
echo "=================================================="
echo "IP table rules"
iptables -L
echo "=================================================="
echo "Ftrace list"
cat /sys/kernel/debug/tracing/enabled_functions
echo "=================================================="
echo "Kprobes enabled"
cat /sys/kernel/debug/kprobes/enabled
echo "=================================================="
echo "Kprobes list"
cat /sys/kernel/debug/kprobes/list
echo "=================================================="
echo "Kprobes blocklist"
cat /sys/kernel/debug/kprobes/blacklist
echo "=================================================="
echo "BPF trace"
sudo apt update && sudo apt-get update && sudo apt-get install bpftrace
bpftrace -l
echo "=================================================="
echo "BPF prog list"
sudo apt update && sudo apt install linux-tools-`uname -r`
bpftool prog
echo "=================================================="