直接比对/proc目录真实pid数与ps输出数量可快速发现隐藏进程:运行find /proc -maxdepth 1 -regex "/proc/[0-9]+" | wc -l和ps -eo pid= | wc -l,若前者显著多于后者,尤其高pid目录存在但exe/cmdline缺失或权限异常,则极可能被rootkit隐藏。

直接看 /proc 目录和 ps 输出不一致的地方,就能快速揪出被隐藏的 PID —— 大多数 rootkit 不会伪造整个 /proc,只会让 ls /proc 或 ps 漏掉某些目录,但那些数字子目录本身还“在那儿”。
统计 /proc 下真实 PID 数量 vs ps 显示数量
这是最轻量、最有效的第一筛。攻击者常劫持 getdents64 系统调用,让动态链接的 ps 无法遍历到特定 PID 目录,但 /proc 文件系统底层目录仍存在。
- 运行
find /proc -maxdepth 1 -regex "/proc/[0-9]+" | wc -l—— 这个命令绕过 shell 内置ls和 libc 的干扰,直接用find扫描所有数字目录 - 同时运行
ps aux | wc -l(或ps -eo pid= | wc -l更干净) - 如果前者比后者多出 1 个以上,说明有 PID 被隐藏;差值越大,越可能有多个恶意进程
- 注意:
pid_max会影响上限,先查cat /proc/sys/kernel/pid_max,正常服务器一般为 32768 或 65536,若find结果接近该值但ps只显示几十个,基本可断定被深度隐藏
检查高数字 PID 是否“空目录”或权限异常
很多用户态隐藏方案(如 LD_PRELOAD hook)倾向隐藏高 PID(比如 >10000),因为它们启动晚、不易被人工注意到。这些 PID 对应的 /proc/PID/ 目录往往存在,但关键文件缺失或不可读。
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
- 对
find /proc -maxdepth 1 -regex "/proc/[0-9]+" | tail -20中的高 PID,逐个检查:ls -l /proc/PID/exe /proc/PID/cmdline /proc/PID/status 2>/dev/null - 若返回
No such file or directory,可能是正常退出;但若返回Permission denied,尤其是非 root 进程却报这个错,极大概率是被内核模块或 eBPF 拦截了访问 - 若目录存在但
exe是 dangling symlink(ls -l /proc/PID/exe显示-> ?),且cmdline为空,配合status中State: S却无 CPU 使用,就是典型隐藏进程特征
用静态二进制或 busybox 绕过 libc 劫持
几乎所有用户态隐藏都依赖劫持 glibc 函数(如 readdir、getdents64)。动态链接的 ps 会被拖下水,但静态编译工具不会走 libc 路径。
- 优先尝试
busybox ps(很多系统自带):busybox ps -eo pid,comm,args | grep -v 'busybox\|ps'—— 它不依赖ld.so.preload,也不走标准 libc readdir - 若无 busybox,可用
strace -e trace=getdents64 -f ps aux 2>&1 | grep -E '^[0-9]+ '观察ps自身是否漏掉了clone或fork系统调用事件;若发现大量getdents64返回 0 但没后续openat,说明它被“静默跳过”了某些条目 - 更彻底的方式:从干净环境拷一个静态链接的
ps(如 Alpine Linux 的ps),或用python3 -c "import os; print([d for d in os.listdir('/proc') if d.isdigit()])"直接调用 syscall
验证是否存在内核级隐藏(需 root 权限)
如果上述方法都找不到明显差异,但你确信有异常行为(比如 ss -tunlp 显示监听端口却无 PID),那大概率是内核模块(LKM)或 eBPF 程序在底层篡改了任务链表。
- 运行
lsmod | grep -E '(hide|root|knark|adore|ebpf)',重点看模块名是否可疑、是否签名(modinfo modulename | grep -i sign) - 检查
/lib/modules/$(uname -r)/kernel/extra/或updates/下是否有非发行版提供的模块文件 - 用
bpftool prog list查看加载的 eBPF 程序,若看到来自/tmp、/dev/shm或非系统路径的程序,尤其类型为lsm或tracing,要高度警惕 - 终极手段:用
crash /usr/lib/debug/boot/vmlinux-$(uname -r) /proc/kcore(需调试符号),然后执行ps -G—— 它直接遍历内核init_task.tasks链表,能暴露所有 task_struct,包括被隐藏进程
真正难搞的不是“找不到”,而是“找到后不敢动”——有些隐藏进程会绑定关键服务或触发反调试逻辑。确认 PID 后,先别急着 kill,用 cat /proc/PID/stack 看内核栈,用 lsof -p PID 和 ss -tunlp | grep PID 关联其网络与文件行为,再决定是隔离、dump 内存还是整机快照取证。










