首页/安全/应急响应速查/ps 与 /proc 对比发现隐藏进程

ps 与 /proc 对比发现隐藏进程

把 ps 输出的 PID 集合与 /proc 下的数字目录集合做差集:只在 /proc 里出现的 PID,就是被工具层过滤掉的隐藏进程。

应急响应速查安全更新于 2026-10-13

对比发现隐藏进程

用户态工具输出的进程列表是可以被伪造的:rootkit 可以挂在内核层过滤 ps、top 的结果,或者直接替换这些二进制。内核提供的 /proc 目录则难以整体隐藏,因此把 ps 输出的 PID 集合与 /proc 下的数字目录集合做差集,只在 /proc 里出现、ps 里没有的 PID,就是被过滤掉的隐藏进程。同理可以把 ss 的连接列表与 /proc/net/tcp 的内容做对比。

基本原理

对比对象一ps -eo pid= 与 ls /proc 的数字目录
对比对象二ss -antp 的连接与 /proc/net/tcp 记录
对比对象三文件系统列表与 ls -la 的目录内容(用于发现被隐藏的文件)
判据两条命令的集合差集,稳定出现的差异才可信
噪声来源线程(不占 PID 目录)、短命进程、正在退出的进程
权限要求读取 /proc 目录本身无需特权,取细节需要 root

典型使用场景

  • 怀疑主机被植入 rootkit,常规 ps 输出与实际进程数不符
  • 确认告警里提到的进程为什么在 ps 里找不到
  • 清理前核对进程全景,避免遗漏仍在运行的后门
  • 与网络连接对比,找出有连接但没有可见进程的异常情况
  • 验证应急工具(busybox ps)与系统自带 ps 的差异

两次采集后取差集

两次采集后取差集
ps -eo pid= | tr -d ' ' | sort -n > /tmp/ps_pids.txt          # 用户态视角
ls /proc | grep -E '^[0-9]+$' | sort -n > /tmp/proc_pids.txt    # 内核视角
comm -13 /tmp/ps_pids.txt /tmp/proc_pids.txt | head -n 30       # 只在 /proc 里出现的 PID
ls -d /proc/[0-9]* | wc -l; ps -eo pid= | wc -l                 # 数量对照,一眼看出差距
for p in $(comm -13 /tmp/ps_pids.txt /tmp/proc_pids.txt | head -n 5); do
  echo "== $p"; ls -l /proc/$p/exe /proc/$p/cwd; tr '\0' ' ' < /proc/$p/cmdline; echo; done   # 逐个画像

对比维度

维度用户态命令内核视角差异含义
进程ps -eo pid=ls /proc 数字目录ps 缺失即被过滤
连接ss -antp/proc/net/tcpss 缺失可能是工具被替换
打开文件lsof 输出/proc/<PID>/fdlsof 结果异常时以此为准
监听端口ss -lntup/proc/net/tcp 中的 0A 状态内核表里存在即确有监听
文件内容ls -la 目录目录自身与 stat 结果两者不一致提示文件被隐藏
差集出现 PID 后先别急着终止:用 ls -l /proc/<PID>/{exe,cwd,cmdline} 做一次完整画像,把样本、连接与启动时间记录下来,再决定处置顺序,否则会丢掉唯一的现场。
噪声要控制:两次采集之间间隔越久,短命进程造成的差集越大。建议采集间隔控制在几秒内,并对同一 PID 连续两轮都出现才算稳定命中。

易错点

  • 两次采集间隔太久:短命进程让差集全是噪声,无法区分真隐藏与正常退出
  • 只做一次差集就下结论:连续两轮稳定出现才可信,否则容易误判
  • 差集出现后就 kill:未画像即处置,样本与连接证据同时丢失
  • 忽略连接维度的对比:进程可以藏,连接也可以被过滤,两个方向都要查
  • 把线程当成隐藏进程:/proc 下只有进程目录,线程数不参与该对比

数据来源与参考

  • Linux 内核 procfs 文档
  • SANS 隐藏进程检测实践

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌