首页 帮助中心 云服务器发现陌生进程怎么处理?kill前先查/proc/PID/exe路径
云服务器发现陌生进程怎么处理?kill前先查/proc/PID/exe路径
时间 : 2026-11-12 10:14:16
编辑 : 华纳云
阅读量 : 5

  在 top 里瞥见一个不认识的进程名,大多数人的手指会比脑子先动——kill -9 敲下去,世界清净了。然后去泡了杯咖啡回来,同一个进程又跑起来了,只是 PID 换了一个数字。更糟的情况是,它没再出现,但你始终不知道它当初是怎么进来的、干了什么、有没有留下别的东西。

  这个场景在云服务器运维中反复上演。问题的根源不在于 kill 命令本身,而在于顺序。陌生进程只是一个入口,真正需要回答的问题是:这个二进制文件从哪来,谁把它放进来的,它凭什么能反复复活。而所有这些问题的第一把钥匙,就藏在 /proc/<PID>/exe 这个看似不起眼的符号链接里。

  为什么 /proc/PID/exe 比进程名可信得多?

  进程名是可以随意伪造的。攻击者把异常程序命名为 kdevtmpfsi、kswapd0 或者 systemd-update,目的就是让你在扫一眼 ps 输出时把它当成系统组件放过去。ps aux 显示的 COMMAND 列只包含进程名和参数,不告诉你这个二进制文件实际位于文件系统的哪个角落。

  /proc/<PID>/exe不一样。它是一个指向进程实际可执行文件的符号链接,由内核维护,用户态无法伪造其指向。执行 ls -l /proc/<PID>/exe,你会看到类似这样的输出:

# 合法系统进程
$ ls -l /proc/1234/exe
lrwxrwxrwx 1 root root 0 Nov 10 14:22 /proc/1234/exe -> /usr/sbin/sshd

# 可疑进程
$ ls -l /proc/5678/exe
lrwxrwxrwx 1 root root 0 Nov 10 14:23 /proc/5678/exe -> /tmp/.X11-unix/.kworker (deleted)

  路径指向 /usr/sbin/ 下的已知二进制,父进程是 systemd,基本可以放心。路径指向 /tmp/、/dev/shm/、/var/tmp/ 或用户家目录下的隐藏目录,嫌疑立刻上升一个量级。(deleted) 标记更值得警惕:攻击者运行了二进制文件之后立即将其删除,只在 /proc 中留下一个残留引用,让基于文件名的扫描工具找不到它。

  除了 exe,/proc/<PID>/cwd 指向进程的工作目录,同样值得一并查看。一个“系统进程”的工作目录如果落在 /tmp 下某个随机命名的文件夹里,伪装就穿帮了。

ls -l /proc/<PID>/cwd
cat /proc/<PID>/cmdline | tr '\0' ' '

  cmdline 给出的是启动该进程时的完整命令行,按空字符分隔。用 tr 把空字符替换成空格后阅读,能看出它是否带了一些可疑的参数,比如指向外部 IP 的 -o 或 --url 选项。

  先暂停,而不是先终止

  拿到路径信息之后,下一步不是立刻 kill。直接终止进程会同时销毁/proc/<PID>/下的所有运行时信息:打开的文件描述符、网络连接状态、内存映射、环境变量。这些恰恰是判断“它做了什么”的关键材料。

  一个比 kill 更温和、信息保留更完整的手段是 kill -STOP <PID> 。SIGSTOP 信号暂停进程的执行,CPU 占用立刻归零,但进程本身仍然存活,/proc 下的信息原封不动,父进程关系、网络连接、打开的文件都还在。如果存在守护进程监控子进程状态,暂停而非终止也能争取更多时间,不至于在排查途中触发守护逻辑重新拉起一份新的。

  暂停之后,按顺序做几件事:

  1. 看网络连接。ss -tnp | grep <PID>或 lsof -i -P -n | grep <PID> 列出该进程持有的 socket。重点看目标 IP 和端口。异常程序常连的高位端口包括 3333、5555、7777、14444 等。如果连接状态是 ESTABLISHED,目标 IP 与业务无关,且端口属于上述范围,基本可以定性为矿池通信。更隐蔽的情况是走 443 端口混在正常流量里,这时候需要结合域名解析记录和连接频率来判断。

  2. 看打开的文件。lsof -p <PID> 的输出里,关注它是否在读写 /etc/ 下的配置文件、是否碰了 /root/.ssh/authorized_keys、是否访问了其他用户的 crontab 文件。这些动作指向的是持久化行为,比进程本身更能说明攻击者的意图。

  3. 看启动时间。ps -o pid,ppid,lstart,cmd -p <PID> 给出精确到秒的启动时刻。如果这个时间与某个已知的风险窗口吻合,比如安全组被短暂放开、或者日志里出现过 SSH 爆破成功的记录,时间线就串起来了。

  路径告诉你藏身地,藏身地告诉你传播方式

  /proc/<PID>/exe 指向的路径,本身就是一条线索。不同的藏身位置对应不同的入侵路径。

  落在 /tmp、/var/tmp、/dev/shm:这几个目录是所有用户可写的,攻击者上传或下载的恶意文件最常放在这里。如果可执行文件位于这些目录,大概率是通过 Web 应用的上传漏洞、Redis 未授权写入、或者某个远程命令执行漏洞投递进来的。/dev/shm 尤其值得注意,它是基于内存的文件系统,重启后内容消失,攻击者偏爱在这里存放不希望被磁盘取证发现的文件。

  落在用户家目录的隐藏目录:比如 /home/用户名/.config/ 或 /root/.local/ 下的随机命名文件夹。这种位置说明攻击者可能已经拿到了该用户的权限,或者至少能以该用户身份写入。需要回头检查该用户的登录记录、SSH 密钥和命令历史。

  落在 /usr/bin/ 或 /usr/sbin/:这是最需要警惕的情况。攻击者把恶意二进制文件放进了系统路径,冒充合法命令。如果文件名与已知系统命令相似但有细微差异——比如 mysq1(数字 1 代替字母 l)、systemd-updat(少一个 e)——说明攻击者做了精心的伪装。这种情况下,应该用包管理器校验对应路径下的文件完整性:rpm -Va 或 dpkg -V 能列出被篡改的包文件。

  拿到路径之后,还有一步值得做:确认这个文件是否还在磁盘上。如果 exe 链接带有 (deleted) 标记,文件本身已被删除,但进程仍在运行。这时候可以通过 /proc/<PID>/exe 把二进制文件复制出来留存:

cp /proc/<PID>/exe /root/evidence_$(date +%s)
sha256sum /root/evidence_*

  哈希值可以用来在威胁情报平台检索,或者作为后续取证的依据。

  杀不死的根因不在进程本身

  很多人经历过这样的循环:kill -9,进程消失,几分钟后又出现。这不是因为 kill 不够强力,而是因为拉起进程的机制还在。异常木马和大多数后门程序都配有守护机制,常见的有三种:计划任务、systemd 服务、以及父进程守护。

  计划任务是最传统也最稳定的方式。攻击者在 /etc/cron.d/ 或 /var/spool/cron/ 下放一条记录,内容通常是 curl 或 wget 拉取脚本并执行,或者直接用 @reboot 在开机时触发。检查的时候不要只看 crontab -l,系统级目录和 @reboot 条目同样重要:

ls -la /etc/cron.d/ /etc/cron.hourly/ /etc/cron.daily/
cat /etc/crontab
grep -r "@reboot" /etc/cron* 2>/dev/null

  systemd 服务是更现代的方式。攻击者创建一个 unit 文件放在 /etc/systemd/system/ 下,ExecStart 指向 /tmp 或隐藏目录中的二进制文件,然后 systemctl enable 让它开机自启。用 systemctl list-unit-files --state=enabled 列出所有已启用的服务,逐个核对 ExecStart 路径。指向非标准路径的 unit 文件需要重点审查:

systemctl list-unit-files --state=enabled | awk '{print $1}' | while read svc; do
    exec_path=$(systemctl show -p ExecStart "$svc" 2>/dev/null | grep -oP 'path=\K[^ ;]+')
    [ -n "$exec_path" ] && echo "$svc -> $exec_path"
done | grep -vE '/(usr/)?(s?bin|lib)/'

  父进程守护则更隐蔽。恶意程序启动两个进程:一个负责实际工作(异常或监听),另一个作为守护者监控前者。工作进程被杀,守护进程立刻拉起一个新的。这种情况下,只杀工作进程没有用,必须同时终止父进程链。ps -o ppid= -p <PID>获取父进程 PID,然后对父进程也执行同样的路径检查,直到追溯到 PID 1 或者一个已经消失的父进程。

  还有一处容易被忽略的持久化位置:/etc/ld.so.preload。这个文件如果存在且包含内容,其中列出的共享库会在所有程序启动前被强制加载。攻击者利用它来劫持 ps、top、ss 等排查工具,让它们隐藏恶意进程和连接。检查方法很简单:

cat /etc/ld.so.preload 2>/dev/null

  正常情况下这个文件不存在或为空。如果有内容,里面的 .so 文件路径需要立即核查。

  什么情况下该放弃清理?

  清理完持久化、终止了进程、确认没有复活,是不是就结束了?不一定。需要诚实地面对一个问题:攻击者拿到过什么权限。

  如果陌生进程是以非 root 用户运行的,且持久化机制仅限于该用户可写的范围,清理后的风险相对可控。但如果进程以 root 运行过——入侵场景中这几乎是默认情况——那么系统核心组件的完整性已经不可信。攻击者可能替换了 ps、ss、netstat,让你看不到某些东西;可能在 PAM 模块中留了记录密码的后门;可能加载了内核模块。这些层面的篡改,靠手工排查很难彻底排除。

  一个实用的判断标准:如果入侵入口是 SSH 弱口令或已知的远程利用漏洞,且攻击者获得 root 权限的时间窗口超过几分钟,重建实例是更稳妥的选择。把业务数据备份出来(只备份数据文件,不备份系统可执行文件和配置文件),在新实例上恢复。云服务器的弹性优势正在于此:重装一台干净机器的成本,远低于长期运行一台“可能还有后门”的机器所承担的风险。

  如果选择保留原机,至少要用包管理器重新安装核心系统工具:coreutils、procps、iproute、openssh-server、systemd。重置所有账户密码和 SSH 密钥,检查 /etc/passwd 中是否有 UID 为 0 的非 root 账户。但这些操作能提供的保证是有限的,需要清楚这一点。

  陌生进程本身并不值得恐惧,它只是一个信使。真正需要关注的是它带来的信息:路径指向哪里,连接通向何方,谁在背后维持它的存在。把 /proc/<PID>/exe 作为排查的起点而不是跳过它直接 kill,意味着你在处理一个事件而不是一个症状。这两者之间的差别,决定了你是花十分钟解决问题,还是花一整天反复解决同一个问题。

相关内容
客服咨询
7*24小时技术支持
技术支持
渠道支持