2026/10/16 10:34:40

服务器挖矿程序入侵排查与清理:从CPU飙高定位到安全加固实战

服务器挖矿程序入侵排查与清理:从CPU飙高定位到安全加固实战 干运维时间长了几乎每个人都遇过这样的事某个深夜监控突然弹出告警一台服务器CPU持续跑在90%以上点开同类型的其他机器几条曲线一模一样地往上冲。不用猜大概率是挖矿程序偷偷进驻了。挖矿程序入侵排查与清理是服务器安全管理里最高频、最考验应急响应基本功的场景之一攻击者一旦拿到入口几分钟内就能完成投放剩下的时间就是在榨干你的CPU和带宽。这篇文章是我自己踩过无数次坑之后整理的实战流程从入侵路径、快速定位、清理处置到根源加固全部按真实处置顺序来写适合刚接触运维的新人也适合需要一套标准化流程的同行参考。1. 入侵途径与预警信号先搞清楚攻击面1.1 攻击者是怎么进来的先说结论绝大多数挖矿攻击不是定向针对你而是全网自动扫描的“一锤子买卖”。攻击者用脚本批量扫描公网IP探测常见端口和组件漏洞一旦发现突破口几秒钟内自动投毒、下载挖矿样本、加入定时任务整个过程完全可以无人值守。所以你会看到有的服务器只是开了个不起眼的端口就中招了这并不奇怪。从我的处置经验看入侵路径主要就那么几类按出现频率排序SSH暴力破解加弱口令这是最经典的入口。很多服务器把22端口直接挂在公网上还开着root密码登录爆破工具几小时就能跑完一本常用密码表。密码一旦被猜中攻击者进来第一件事就是下载挖矿程序、写入定时任务顺便再留一把SSH公钥当后门。中间件和组件的漏洞利用。外网可达的某开源数据组件、消息队列、开发框架但凡存在未授权访问或远程代码执行漏洞基本上就等同于把服务器大门敞开了。遇到过好几台测试机只是把组件的默认端口暴露到公网第二天云平台就告警说CPU跑满登录进去一看/tmp目录下全是陌生脚本。Web应用漏洞打穿。SQL注入、文件上传、命令注入随便中一个都可能让攻击者拿到执行权限这类入口在自建站点里特别常见尤其是那些没有WAF、代码又老旧的业务系统。内网横向移动与运维习惯问题。账号密码多处复用、管理平台弱口令、内网不做隔离攻击者拿下了一台用抓到的密码继续横向试其他机器。很多团队不理解“为什么我已经有防火墙了还会中招”其实安全组和防火墙只解决了端口暴露问题真正需要关注的是“暴露出来的服务本身是否安全”。我常跟人说攻击面不是你开了多少端口而是你开着的每一个端口背后是不是一个能被利用的服务。1.2 中招后的典型信号挖矿程序不是隐形杀手服务器被入侵之后一定会露出马脚关键是你能不能及时发现。我自己判断的标准就一条把异常现象当“行为信号”看而不是只看告警。CPU持续高位。这是最直接的信号挖矿的本质是计算计算就要吃CPU。云监控里如果连续十几分钟CPU跑在90%以上且没有对应的业务高峰基本可以直接列入怀疑清单。网络连接异常。服务器出现大量到陌生IP的长连接往往是挖矿客户端在与矿池通信。特征是对端IP分散、端口不常见连接数量稳定且长时间存在。进程特征可疑。进程名伪装成系统进程或随机字符串比如看起来像系统内核线程的名字实际却是一个用户态程序CPU占用极高但所属用户却是nobody、daemon或者一个陌生用户。文件系统出现陌生文件。挖矿样本最喜欢放在/tmp、/dev/shm、/var/tmp这类临时目录文件名可能是随机字符串、UUID或者带明显下载特征的名字旁边经常还跟着一个拉取脚本。定时任务和账号被改动。crontab里多出一条指向陌生URL的任务/etc/passwd里多了UID为0的新用户或者SSH的authorized_keys里出现陌生公钥。这里多说一句不要觉得挖矿程序只会静默跑着不少样本为了“保护资产”会主动把系统的history清空、关闭安全软件、抢占用常见调试工具的端口。如果某天你发现历史命令记录明显缺失也要当成入侵信号处理。2. 快速定位从异常进程到关键证据2.1 登录服务器后的第一步操作确认服务器可能中招之后最容易犯的错就是一上去就杀进程、删文件。我理解这种心情但冲动清理会带来两个后果一是丢了现场证据后面想追溯攻击源无从下手二是很多挖矿程序有守护机制你只杀进程不处理定时任务过两分钟它又回来了你会以为自己没杀干净。我建议登录服务器后先做三件事按顺序执行缺一不可。第一建立会话隔离。用 tmux 或者 screen 开一个会话避免排查过程中SSH断线导致命令中断特别是当你准备在清理时改动网络配置一旦断开可能就是“远程手残”事故现场。第二快照取证。用 date、uptime、last、history 把当前时间和登录记录留存下来顺手把 top 输出、进程列表、网络连接、系统日志中最近30分钟的内容重定向到文件。这一步不用花多少时间但在复盘时价值极大。第三确认影响范围。看同一内网或同一账号下还有没有其他机器出现同样问题云平台侧的告警和登录记录也一起翻出来。如果攻击者是通过内网横向移动进来的你处理完这台下一台很快又会沦陷。用一句话概括这阶段的心法先确证再动手先保全证据再考虑清理。2.2 从top到/proc把高CPU进程查个底朝天定位恶意进程的核心思路就一条顺着CPU和网络连接两条线把“异常”还原成“文件路径、启动方式、运行身份”三要素。先跑 top -c 或者 htop看哪个PID占CPU最狠。注意top里的%CPU可能超过100%因为这是按核数累加的一个吃满8核的进程显示800%是正常的。看到可疑进程后不要急着 kill立刻用 ps aux --sort-%cpu | head -20 把它单独拉出来看完整信息主要看USER、PID、%CPU、STARTED、COMMAND这几列。接下来对目标进程执行一组“体检命令”这是整个排查的核心动作ls -l /proc/PID/exe查看进程实际执行文件的路径。如果返回的是带 (deleted) 的结果说明原文件已经被删但进程还在内存里运行这种十有八九是攻击者故意清理了磁盘痕迹。cat /proc/PID/cmdline用tr \0 把内容转成可读字符串可以看到进程启动时的完整命令行。挖矿程序经常在这里露馅比如带着连接矿池的参数或指向陌生域名的下载地址。ls -l /proc/PID/cwd查看进程工作目录样本常见于/tmp、/dev/shm。cat /proc/PID/status重点看 Uid 和 Gid确认它到底以什么身份在跑。如果是一个普通业务进程却用nobody身份起了线程组可疑程度直接拉满。lsof -p PID列出进程打开的文件和网络连接能帮你快速找到伴生文件和通信对象。有一类样本会刻意伪装成内核线程名字看起来像 [kworker] 或者 [ksoftirqd]。判断方法很简单真正内核线程的cmdline是空的且父进程PID为2如果你用 ls -l /proc/PID/exe 能看到真实路径那它就是一个挂羊头卖狗肉的用户态进程。2.3 网络连接与持久化任务排查进程层面的证据抓完紧接着排查网络连接。执行 ss -antp把每一条ESTABLISHED状态的外部连接记录下来重点关注两类现象一是对端IP集中在海外段、端口是非标准高位端口二是连接数量不多但非常稳定挖矿客户端和矿池之间通常是长连接不像正常业务那样频繁起落。挖矿僵尸脚本最大的特点就是“留后路”所以持久化机制必须查。很多人只清进程和文件不清任务结果必然被一波波拉起来。按我的顺序走一遍crontab -l 并检查 root 用户的定时任务同时看 /etc/crontab、/etc/cron.d/ 下的所有文件以及 /var/spool/cron/ 目录。用 systemctl list-unit-files --typeservice | grep enabled 看开机启动服务列表找那些名字看上去很随机、或者明显不属于你部署过的服务。找到可疑服务后到 /etc/systemd/system/ 下看它的Unit文件内容确认ExecStart指向的脚本。检查 /etc/rc.local、/etc/profile.d/、用户home目录下的 .bashrc 和 .profile这些位置都是常见驻留点。重点关注 /etc/ld.so.preload。这是一种比较恶劣的手法攻击者放入恶意动态库让它先于所有程序被加载从而实现进程隐藏和命令劫持。正常系统里这个文件应该是空文件或者不存在如果里面有内容基本可以判定被入侵。检查 /root/.ssh/authorized_keys 和所有用户home目录下的公钥文件攻击者经常会直接种一把公钥方便随时远程登录回来。用 awk -F: $30{print $1} /etc/passwd 查看UID为0的账号确认除了root之外没有其他特权用户。这些位置检查完恶意程序在系统里的“三条命”基本就摸清了常驻进程是一条定时任务是一条SSH公钥和系统服务又各算一条。摸不清全部驻留点清理就是白做。3. 清理实战终止、删除、除根3.1 隔离与证据保留到了清理阶段第一件事不是按键盘而是隔离。如果这台机器是在IDC或云上优先在云控制台把安全组出方向规则收紧只允许必要的业务端口放行或者干脆先封掉对外访问。这样做的目的是切断挖矿程序与矿池的通信让恶意进程变成“断线状态”防止它在下线瞬间把系统里其他敏感数据外带。同时把刚才收集到的关键文件原样保留一份副本计算SHA256校验值存下来。这不是形式主义而是如果后续发现其他机器也被感染你手里有完整的样本指纹可以对账快速批量排查。在生产环境处置时还有一个顺序问题先切流量再杀进程还是先杀进程再切流量我的建议是优先切流量观察一两分钟。因为有些攻击脚本设计成“断网自毁”——发现失联立刻删文件、清日志你等它自毁完反而省了清理功夫同时也能观察它是否有守护进程在尝试重新拉起。当然这个策略要看业务容忍度如果机器上跑着核心应用就退一步直接走杀进程流程。3.2 终止恶意进程与删除恶意文件清理动作讲究先后顺序先断拉起的源头再断正在跑的进程最后删磁盘文件。顺序反了的结果就是——你删了文件进程还在内存里内存里的样本又吐出文件僵尸一样复活。第一步处理定时任务和服务。把上一轮排查出来的cron任务逐行删除把可疑systemd服务用 systemctl disable --now 停掉避免在杀进程的过程中被它们再次拉起来。如果涉及的脚本文件在/tmp等目录先记录路径这一步先不删除以便后面检查。第二步观察进程树。用 pstree -p PID 看恶意进程的父子关系确认没有更上层的守护进程。有些僵尸脚本会设置多个进程互相监控你杀掉一个另一个立刻把人拉起来。所以杀进程要一口气把整个进程树清掉或者用 pkill -f 匹配特征字符串一次性解决。第三步终止进程。执行 kill -9 PID如果命令提示没有这个进程立刻去查进程是否换了PID——那说明有守护进程正在热重启。对应处理方式是回到上一步把守护和服务先停干净再用同样的方式杀。第四步删除文件。对定位到的恶意样本、脚本、动态库顺手 rm -rf 删掉之后还要检查一遍 /tmp、/dev/shm 里有没有新文件冒出来。如果删除时提示设备忙用 lsof 查看是哪个进程还占着文件句柄处理完进程再删。对了删之前偏取证的可以留一份副本压缩打包放到隔离目录。3.3 清除定时任务、服务与SSH后门进程和文件清完紧接着处理三类容易“复发”的后门计划任务、服务、SSH授权。计划任务要清彻底。crontab -l 看的是当前用户的别忘了 /etc/cron.d/、/var/spool/cron/ 下其他用户的。很多挖矿脚本会往每个有shell的用户目录下各塞一个cron文件漏一个就是漏一个复活点。我的习惯是直接查看这些目录的修改时间把攻击时段内创建的文件全部审一遍。SSH后门要从两个方向排查一是authorized_keys中的陌生公钥直接删除对应行二是/etc/passwd和/etc/shadow里新增的账号特别是UID为0的非root账号。清除账号用 userdel -r 把home目录一起删掉。比这更隐蔽的还有SSH的配置后门比如/etc/ssh/sshd_config里被塞了额外的AllowUsers条目或者不常见的认证方式有条件的话直接对比发布备份或者用 rpm -V openssh-server 校验文件一致性。所有可疑后门清理完毕后统一做一次密码轮换修改root和所有业务账号的密码生成新的SSH keypair并替换旧公钥。即便你不知道攻击者是不是已经拿到了密码这一步也不能省因为你无法判断他是否在你排查时已经复制走了凭据。最后再执行一次全量自查重复第2章的排查清单确认没有新的定时任务、没有陌生连接、没有可疑进程然后观察至少一两个小时确认CPU回落、网络连接干净这才算基本处置完成。4. 根治封堵入口与安全加固4.1 基础防护SSH、账号与端口清理干净只是第一步入口不堵清理就是给攻击者腾地方。我见过太多团队每天杀一次进程杀了半个月最后发现是因为SSH密码一直没改。所以清完之后立刻转入加固阶段。SSH加固是优先级最高的一环。把公网侧SSH改成密钥认证关闭密码登录如果业务上允许修改默认的22端口到高位随机端口同时通过安全组或防火墙限制SSH的管理来源IP只允许自己办公网的IP段访问。有条件再上一个fail2ban对连续登录失败的IP自动封禁这属于辅助防御不能替代密钥认证。账号层面删除不再使用的账号限制root直接登录。很多人不爱用sudo习惯root一条命令走天下这在中招之后你根本分不清哪些操作是攻击者做的、哪些是自己误操作。建议日常运维都用最小权限账号加sudo审计至少在系统日志里留下可追溯的记录。4.2 服务侧加固与漏洞管理接下来是业务和中间件侧。先做端口最小化在安全组和本机防火墙两层都默认拒绝入方向只放行业务端口管理端口、数据库端口、组件控制台一律不对公网开放需要远程访问走跳板机或者内网。很多挖矿事故里的组件、数据库本质上就是“裸奔”在公网上被扫到了。然后盘点现存组件版本针对已知漏洞升级补丁。我自己有一个简单标准凡是能从外网访问到的服务必须保持在一个发布六个月以内、无已知高危CVE的版本。做不到升级就至少做到网络隔离用安全组限制来源IP别让它裸奔。Web类的服务器要在代码层面做输入校验上传目录禁止执行脚本有条件就前置WAF。这一块容易被人忽略总觉得“我的站没什么价值”实际上CPU和带宽就是价值攻击者不在乎你的站是干嘛的。4.3 监控告警与日常巡检加固做完最后一道防线是监控。对于运维资源不足的团队云监控本身就够用设好CPU使用率、公网带宽、登录行为、安全组变更几类告警任何一项异常都第一时间通知到人。比单纯看CPU更早发现入侵的往往是登录告警和账号变更告警因为攻击者总要先做“进服务器”这个动作。自建监控的话最朴素的方案是写一个巡检脚本每天检查crontab列表、SSH公钥文件、新增用户、监听端口把差异结果推送到群机器人或邮箱。挖矿攻击的持久化机制必然要改这些地方你能在第一时间看到diff就能在它真正跑起来之前打断。另外建议把系统日志/var/log/secure、/var/log/auth.log等集中收集到日志平台保留至少90天方便入侵之后回溯时间线和攻击源。安全这件事最怕的不是攻击者多厉害而是你完全没有日志可以看。5. 常见问题与排查技巧实录5.1 进程伪装与隐藏怎么办处置多了就会遇到一些“加了料”的样本。最常见的是替换系统命令比如把ps、netstat换成同名木马让你在系统里看到的进程列表和网络连接都是假的。遇到这种情况用 ls -l /bin/ps 看文件大小和修改时间再用包管理工具校验文件完整性立刻就能分辨真伪。如果连 /proc 都被做了手脚那就比较极端了多半是内核级rootkit。此时不要恋战备份业务数据、重装系统是最稳妥的选择。普通运维人员在这种情况下去跟rootkit硬磕成本远高于收益。还有一个容易忽视的细节不是所有挖矿程序都跑满CPU。有些样本为了隐蔽会在检测到CPU温度或负载过高时自动休眠或者限制占用率。判断这类隐藏样本要靠网络连接和文件持久化而不是只盯CPU。5.2 清理后复发的处理思路复发几乎每个人都会遇到而且大多数时候不是你没清理干净而是入口没堵上。处理复发时先问自己三个问题恶意进程的父进程是什么新文件是从哪个地址下载的攻击者的登录记录出现在什么时候把这三条对照起来基本能判断它是“本地残留复活”还是“外部再次入侵”。如果是本地复活回到第3章重点清理定时任务和systemd服务。如果确认是外部再次入侵而且你在排除所有入口之后仍然复发要考虑镜像被投毒或者存在内核级后门最有效的办法是备份数据后彻底重装系统换全新的密钥和密码。我见过最典型的案例是某团队连续清理两周最后发现一台跳板机的SSH公钥一直被控制着攻击者靠这条通道无限重进。5.3 快速响应的工具箱与心法把文中涉及的命令整理成一份速查表建议保存下来贴在运维知识库里排查目标关键命令说明高CPU进程top -c、ps aux --sort-%cpu先整体看再锁定PID进程真实路径ls -l /proc/PID/exe(deleted)说明文件被删但进程存活进程完整命令行tr \0 /proc/PID/cmdline查看启动参数里的矿池/下载地址进程打开文件lsof -p PID找伴生文件TCP连接ss -antp重点看ESTABLISHED外部连接计划任务crontab -l、ls /etc/cron.d/全用户检查开机服务systemctl list-unit-files --typeservice找随机名、陌生服务预加载后门cat /etc/ld.so.preload非空即异常SSH后门cat /root/.ssh/authorized_keys对比陌生公钥特权账号awk -F: $30{print $1} /etc/passwd排查UID 0最后说一句心法应急响应的节奏是“冷静、按流程、留证据”。我在实际处置中最大的体会是大多数运行事故不是入侵本身造成的而是处置时慌慌张张导致的二次问题。你把流程走顺把每一步理解到位挖矿程序清理这件事就是一次标准的“CTF式运维”。另外强烈建议你在测试机上把整个流程演练一遍从伪装进程到清理加固真实环境里反复操作过之后真出事的时候手才不会抖。