排查内核模块后门关键在于识别行为异常、来源不明、上下文冲突的模块,需检查模块名仿冒词、author字段空或未知、size异常,比对lsmod与/lib/modules路径下文件是否一致,核查modules_disabled值是否突变为1,并结合ss与netstat输出差异、系统调用表完整性及/proc/net inode反查进程等多维度验证。

排查内核模块(LKM)中的后门,关键不是“找一个可疑模块”,而是识别那些行为异常、来源不明、与系统上下文冲突的模块。攻击者常通过伪造模块名、清空作者字段、劫持系统调用表来隐藏,常规 lsmod 只能看到“已加载”,看不到“是否可信”。
看模块基础信息是否可疑
运行 lsmod 后,重点检查三类字段:
-
名称含仿冒词:如
acpi、nv、intel、hide、rootkit、drv—— 这些常是攻击者故意起的“看起来像驱动”的名字,但系统实际并不需要它 -
Author 字段为空或为未知字符串:正常内核模块(如
ext4、nf_nat)在modinfo输出中会显示明确作者(如Linux Kernel Team)。若modinfo module_name | grep author返回空或乱码,需警惕 -
Size 异常小或过大:小于 4KB 的模块极可能是空壳或 loader;大于 500KB 且无对应功能说明(如不带 GPU 或加密功能却叫
crypto_mod),也值得细查
查模块是否绕过正常加载机制
恶意模块常避开 /lib/modules/$(uname -r)/ 路径,改用动态插入方式:
- 执行
find /lib/modules/$(uname -r)/ -name "*.ko" -exec modinfo {} \; 2>/dev/null | grep -E "(^filename:|author:)",比对哪些模块在lsmod里有、但在该路径下找不到对应文件 - 检查
/proc/sys/kernel/modules_disabled:若值为1,说明模块加载已被禁用——这本身是反常行为,因为默认为0;突变为1很可能表示攻击者为防止你卸载其模块而锁定机制 - 留意
insmod直接加载的痕迹:查看命令历史(history | grep insmod)、/var/log/messages或dmesg | tail -50中是否有非标准路径的.ko加载记录
验模块是否篡改了系统行为
仅看模块本身不够,要验证它是否动了系统底层逻辑:
- 对比
ss -tulpn和netstat -tulpn输出:若后者缺失某些监听端口,而前者完整,说明netstat被劫持(常见于 rootkit 注入的模块 hook 了sys_getdents64或sys_socket) - 检查系统调用表完整性(需调试符号):若有
vmlinux和crash工具,可用crash vmlinux /proc/kcore -s 'sys_call_table'查看是否被 patch;生产环境无符号时,可退而求其次:运行strace -e trace=socket,bind,listen,accept ls / 2>&1 | grep -i "permission denied",异常拒绝可能暗示 syscall 被拦截 - 用
cat /proc/kallsyms | grep sys_call_table获取地址后,配合dd读取原始内存(高风险,仅限离线分析),确认前几项是否被替换
结合进程与网络反向追踪
很多 LKM 后门不单独运行,而是配合用户态进程启动或响应网络请求:
- 对每个可疑模块,执行
modinfo -F parm module_name,看是否声明了可配置参数(如port=4257、hidden_pid=1234),再查对应端口或 PID 是否真实存在且异常 - 若模块声称支持“隐藏进程”,立刻遍历
/proc/[0-9]*/,对每个 PID 执行readlink /proc/PID/exe和cat /proc/PID/cmdline,找(deleted)、路径不存在、或命令行与ps显示严重不符的情况 - 检查
/proc/net/{tcp,udp}第十列 inode,用find /proc/[0-9]*/fd/ -lname "socket:[<inode>]" 2>/dev/null</inode>反查归属进程 —— 若找不到任何进程,但 socket 确实存在,说明该连接可能被模块过滤掉了显示











