应监控 init_module 和 finit_module 系统调用,而非仅 insmod/modprobe 命令;通过 auditd 配置双架构规则捕获加载行为,并结合 exe、comm、auid/uid 字段识别可疑进程及上下文,再交叉验证模块来源与符号表以确认 rootkit。

要捕获内核模块加载行为(如 insmod、modprobe),关键不是监控命令本身,而是监控触发模块加载的系统调用——特别是 init_module 和 finit_module。auditd 无法直接记录“谁执行了 insmod”,但能精准捕获内核真正执行模块加载的那一刻,这对发现隐蔽 rootkit 至关重要。
必须监控的两个核心系统调用
Linux 加载内核模块最终都通过以下两个系统调用之一完成:
-
init_module:传统方式,参数为内存中已读取的模块镜像 -
finit_module:较新接口(自 Linux 3.8+),参数为模块文件描述符,更常被攻击者用于绕过基于路径的检测
仅监控 insmod 或 modprobe 二进制执行(execve)远远不够——rootkit 可通过直接调用 syscall 或利用已有合法进程注入完成加载,完全绕过用户态命令。
正确配置 auditd 规则(支持多架构)
将以下内容保存为 /etc/audit/rules.d/module-load.rules(注意后缀必须是 .rules):
-a always,exit -F arch=b64 -S init_module,finit_module -k module_load -a always,exit -F arch=b32 -S init_module,finit_module -k module_load
然后重载规则:
-
sudo augenrules --load(推荐,自动合并并加载) - 或
sudo auditctl -R /etc/audit/rules.d/module-load.rules
验证是否生效:sudo auditctl -l | grep module_load 应看到两条规则;sudo ausearch -k module_load -m SYSCALL -ts recent 可测试是否捕获到操作(例如手动 sudo insmod /lib/modules/$(uname -r)/kernel/drivers/input/joydev.ko 后立即运行)。
如何识别可疑模块加载事件
用 ausearch 提取日志后,重点关注三项:
-
exe=:实际触发调用的程序路径(如/usr/bin/modprobe、/bin/bash,甚至/usr/local/bin/evil_tool) -
comm=:进程名(可能被篡改,但比 exe 更快判断上下文) -
auid=和uid=:登录用户 ID 与实际有效用户 ID,若auid=4294967295(即 unset)或uid=0但无对应运维记录,高度可疑
典型可疑线索示例:
-
exe=/usr/bin/python3+comm=python3+auid=1001:普通用户用 Python 调用 syscall 加载模块,极不寻常 -
exe=/bin/sh+comm=sh+uid=0+cwd="/tmp":从临时目录以 root 身份加载,大概率恶意 - 同一
pid在短时间内连续触发init_module和finit_module:可能在试探兼容性或隐藏主模块
配合其他检查提升检出率
auditd 日志只是起点,需交叉验证才能确认 rootkit:
- 查模块来源:
ausearch -k module_load | awk -F'exe="' '{print $2}' | cut -d'"' -f1 | sort -u列出所有触发程序,再人工核查是否可信 - 比对加载状态:
lsmod输出应与/proc/modules完全一致;若 lsmod 显示某模块,但find /lib/modules/$(uname -r) -name "*.ko" | xargs ls -l 2>/dev/null | grep -i suspicious_name找不到对应文件,说明模块非标准编译或已被卸载但残留符号 - 检查符号表异常:
sudo cat /proc/kallsyms | grep -E "(sys_|do_|entry_)" | grep -v " t " | head -30,留意含hide、fake、rootkit、logk等关键词的函数名
不复杂但容易忽略


















