☰
挖矿木马应急响应实战:从CPU飙升到彻底清除
2026/10/21 15:46:29 网站建设 项目流程

说真的,做运维这几年,最怕的不是半夜被监控短信叫醒,而是白天正喝着咖啡,监控面板突然弹出告警:某台线上服务器的CPU使用率直接冲上98%。我最初以为是业务代码出了死循环,直到打开进程列表,看到那个叫kworkerd的陌生进程稳稳占着CPU第一的位置,心里才反应过来——八成是遇到挖矿木马了。

这篇文章就围绕这次真实的应急响应过程展开,从发现异常、定位进程、分析样本,到清理加固、总结复盘,完整走了一遍。我不仅会把每一步操作和命令写清楚,还会解释这些操作背后的逻辑:为什么这么查、踩了哪些坑、哪些环节新手最容易漏。如果你是对网络安全感兴趣的开发者,或者正被服务器莫名卡顿折磨的运维新手,这篇文章应该能帮你省掉不少摸索时间。

1. 意外的告警:从一台CPU满载的服务器说起

1.1 值班日志里的第一丝异常

事情发生在一个普通的工作日下午。同事发来消息,说某个业务模块的接口响应时间突然从200毫秒飙升到5秒,用户刷新列表要转圈半天。我第一反应是数据库慢查询或者缓存失效,于是登录服务器准备看监控面板。

登录之后,终端敲了sar -u看CPU历史数据,连续看几行,发现从当天上午10点开始,CPU使用率从不到20%缓慢爬升,到中午已经稳定在95%以上。关键是,这台机器根本不是高负载业务节点,平时连数据迁移都不敢在上面跑,这个CPU曲线怎么看都不正常。

我接下来做了一连串基础检查:内存(free -m)显示剩余内存不多但还有余量;磁盘IO(iostat)基本没压力;网络流量(iftop)却非常诡异——主机对外发送的流量比接收高出好几个量级。业务不可能产生这种单向流量模式,这几乎是明晃晃的暗示:有东西在向外“搬运”数据,或者更准确地说,在下发任务、回传状态、被远控指挥着干活。

1.2 用top和ps把可疑进程“揪”出来

直觉告诉我要赶紧看进程了。我执行了top -b -n 1 | head -20,第一眼就看到进程表里一个叫kworkerd的进程CPU占用97.3%,紧跟其后的几个进程也都带着异常的名称,比如kthreaddi、xmrig这种明显不在正常业务库里的名字。

当时我脑子里第一反应:kworkerd乍一看很像内核工作线程(平时熟悉的系统内核线程确实叫kworker之类),但如果真是内核线程,它是不会出现在用户态普通进程列表里的。而且top里显示这个进程的USER列是root,启动时间却是昨天——一台刚接手不到两天的服务器,怎么会有这种进程?

接下来我用三条命令快速确认:

# 查看进程的完整路径 ls -l /proc/PID/exe # 查看该进程的启动命令行 cat /proc/PID/cmdline | tr '\0' ' ' # 查看该进程的网络连接 lsof -p PID

这三条命令的输出结果让我彻底坐不住了:进程的可执行文件路径是/tmp/.X11-unix/kworkerd,命令行参数里带着矿池地址字符串,lsof显示它正持续地向某个境外IP的端口发起TCP连接。CPU被偷走了,证据链已经基本完整。

2. 挖矿木马的三张“身份证”:进程、定时任务与网络外联

2.1 为什么挖矿木马偏爱“偷CPU”

很多人第一次接触“挖矿木马”会困惑:这木马为什么不像勒索病毒那样把文件加密、或者像窃密木马那样把数据偷走,而是闷声不响地占着CPU资源?

道理其实很简单。加密货币系统(以门罗币这类隐私币为代表)的设计思路,就是通过让参与者提供计算机的计算能力来“解题”,谁贡献的算力多,谁就能获得到账的加密货币奖励。“挖矿”本质上就是拿CPU/GPU做哈希运算。攻击者手里握着大量被攻陷的服务器资源,把这些机器串成一条“矿机流水线”,每台机器分担一点运算,汇总起来就是一笔可观的收益。

换句话说,挖矿木马干的活就是“免费开你家里的电暖器,电费你来交,暖和气他去外面卖钱”。CPU是机器的核心资源,也是挖矿计算最直接的消耗品。所以一旦机器被植入矿机程序,最典型的表现就是CPU占用率拉满,温度升高,风扇狂转,整个服务器卡得像是水池里泡了个大木桶。

这个原理决定了我们的排查优先级:看到CPU异常高占用,第一件事是想清楚“谁在用我的算力”,而不是先怀疑磁盘满或者应用慢查询。

2.2 从进程路径到系统目录:三招摸清木马的藏身处

定位到kworkerd之后,我没有急着杀进程,因为直接杀掉一个挖矿木马往往是白费功夫——大多数矿机会搭配一个“守护进程”,每隔几分钟检查主程序还在不在,不在就重新下载一份新的回来。所以更稳妥的思路是:先把这个进程的老巢找出来,把整个潜伏链路完整摸透,再动手。

第一招:看进程的启动路径。

ls -l /proc/PID/exe

如果返回的路径类似/tmp/、/var/tmp/、/usr/lib/.systemd-random、/boot/这种“非正常业务运行目录”,那基本就是木马没跑了。正常来说,系统服务要么在/usr/bin/、/usr/sbin/,要么在业务自己的部署目录;出现在这种犄角旮旯,绝大多数情况就是恶意程序为了尽量不被运维发现而做的“隐蔽部署”。

第二招:看进程的启动顺序和父子关系。

pstree -ap PID

这一步很有用。木马为了做到“一荣俱荣、一损俱损”,往往会由一个父进程拉起多个子进程,比如挖矿主程序、守护脚本、清理对抗脚本各一个子进程。弄清楚进程树,就等于摸清了木马的“组织架构”,后面清理的时候才知道哪些进程是必须一锅端的。

第三招:看外联连接。

ss -antlp | grep PID netstat -antlp | grep PID

挖矿木马必须和矿池通信,通常选择的端口有矿池默认端口(如3333、4444、5555等)。如果发现这样一条连接:客户端IP是你们服务器,服务端IP是个陌生地址,并且源端口不断变化,那么几乎可以判定它正在和一个矿池“保持心跳”。这时候记录下IP、端口和连接时间,后续作为证据保存。

2.3 定时任务与启动项里的“潜伏者”

找到了进程和它的老巢之后,我立刻转入排查“持久化”这一步。所谓持久化,就是木马确保自己重启以后还能继续运行的手段,常见路线有三条:定时任务、启动脚本、SSH公钥后门。

先查定时任务:

crontab -l cat /etc/crontab ls -al /etc/cron.d/ ls -al /var/spool/cron/

结果果然不干净。/etc/crontab里被追加了一行每分钟执行一次的脚本,内容是一个wget下载远程脚本并交给sh执行的动作。这就是典型的矿木马惯用套路:本体不直接写在文件系统里,而是靠一个可变的远端脚本临时拉取,一旦执行完毕立刻删除痕迹,让追踪变得困难。

再看SSH后门:

ls -al /root/.ssh/ cat /root/.ssh/authorized_keys

这一看发现问题更严重:authorized_keys里出现了一条陌生的公钥,签发人和时间都与正常密钥毫无关联。这意味着攻击者不光植入了矿机,还留了一个“管理员钥匙”,随时可以再次进入这台机器。这条公钥必须立刻清理,否则就算矿木马被清干净,对方仍然可以进来。

再检查systemd服务:

grep -r "kworkerd\|download\|miner\|curl" /etc/systemd/system/ /usr/lib/systemd/system/ 2>/dev/null systemctl list-unit-files | grep -iE "kworkerd|systemd-random|kworker"

木马经常会往服务目录塞一个服务单元文件,通过systemd实现开机自启动。我当时就在/etc/systemd/system/下发现了一个名为kworker.service的服务文件,内容就是指向之前那个路径的可执行文件。这也就是说,即使把进程杀了、把/tmp下的文件删了,机器一重启,这个服务又会把矿工程序拉起来。这一步排查的收获,是后面能否彻底清理干净的关键。

3. 解剖样本:静态分析与动态行为追踪实录

3.1 静态分析:不运行也能看穿木马“底细”

进程层面的信息掌握得差不多了,我决定把那个可执行文件本身拿来做一次“解剖”。

先把文件从被入侵的机器上用scp复制下来,放到一台隔离的分析机里。记住一个原则:永远不要在真实生产环境直接运行未知样本,复制文件时也尽量使用离线拷贝方式,避免在传输过程中触发木马的“下载链”。

静态分析的第一步是做“体检”:

file /tmp/kworkerd-sample # 输出结果:ELF 64-bit LSB executable, x86-64, dynamically linked md5sum /tmp/kworkerd-sample # 记录hash值,作为样本指纹,方便后续在威胁情报平台查询 sha256sum /tmp/kworkerd-sample

拿到哈希后我顺手查询了一下安全厂商的威胁情报平台,确认这个样本在平台上已经被标记为“挖矿木马”的关联家族,这就省下了不少逆向的力气。接着我用strings命令提取了样本中的字符串:

strings /tmp/kworkerd-sample | grep -iE "miner|pool|stratum|xmrig|config"

输出里直接出现了矿池地址字符串、用户编号、以及xmrig这个著名的开源挖矿程序模块名。到这里,静态分析基本可以断定:这是某个基于开源矿机程序定制改造的挖矿木马,未脱壳的ELF文件,被攻击者简单打包后放上来的。

静态分析的另一个亮点是检查样本有没有加壳特征。可以通过readelf -d看段信息,或者直接观察样本的文件熵值。如果熵值接近1.0,说明很可能加过壳,我这次拿到的样本熵值大约0.64,说明压缩比较低,属于“直接编译然后简单打包”的类型。遇到高熵样本,就需要脱壳或者动态分析了。

3.2 动态分析:在隔离环境里观察它的“一举一动”

静态分析能告诉我们“它是什么”,但在真实运行状态下的行为,还得靠动态分析来还原。

我把样本放进了虚拟机沙箱,只给它联网权限(切到一个独立的网络隔离区,出口被防火墙封死),然后观察它的行为。这一步很关键:不能把样本挂在业务网络里跑,也不能给它真正的公网联网能力,否则就是一个真实的安全事故。

沙箱里的动态观察记录了几个典型行为:

  • 启动后立刻连接之前进程里看到的那个矿池域名和IP,持续发出心跳包;
  • 尝试在/tmp目录下生成一个带隐藏点前缀的配置文件夹;
  • 向外部某个IP发送带有本机CPU型号和核数的信息,这其实是挖矿木马在汇报“算力资源”,方便矿池调度分配任务;
  • 尝试读取宿主机的环境变量和系统信息,某些样本还想利用容器逃逸漏洞尝试跳出沙箱,不过被沙箱隔离挡住了。

动态分析帮我确认了这不仅仅是一个孤立的挖矿进程,还是带有信息收集和对抗痕迹的复杂恶意程序。整个过程就像是医生给病人做运动平板测试,看完静态报告还不够,还要看它真正跑起来时心脏怎么跳、血压怎么变。

3.3 还原攻击链路:木马是怎么一步步进来的

分析完样本之后,我回到那台被入侵的服务器,重点排查“它到底是从哪进来的”。这一步对于后续加固至关重要,否则相当于只修好了伤口,没找到伤口是怎么开的,攻击者换个姿势又能进来。

排查入口的第一站是系统登录日志:

lastb grep -i "failed\|accepted" /var/log/auth.log

日志显示,在木马被植入的前一天晚上,有大量来自不同IP的SSH暴力破解尝试,其中有一条恰好成功登录了root账号。翻看历史命令记录(.bash_history),发现被执行过一串命令:先改密码、再添加用户、然后下载并运行了一个脚本。这条链路已经很清晰了:

攻击者通过SSH弱口令爆破拿到服务器控制权 → 登录后快速下载远程脚本 → 脚本自动部署挖矿程序和守护任务 → 植入SSH公钥作为持久化后门 → 清理痕迹后悄悄退出。

顺着这个思路继续“考古”,还在Web目录里发现了一个中间件漏洞的利用痕迹(日志里有一条异常请求,紧跟其后出现了命令执行的迹象),说明这台服务器同时存在两个入口:一个是SSH弱口令,另一个是Web中间件的未授权代码执行漏洞。这也解释了为什么我清理完矿木马之后,重启没过多久又看到了kworkerd——攻击者留下的另外一条通道还在偷偷工作。

到这里,攻击链路的完整拼图已经成型:弱口令爆破和Web漏洞控制服务器 → 植入矿机主程序 → 配置定时任务和服务实现持久化 → 留下SSH公钥作为应急通道。整条链路环环相扣,一步都不能漏。

4. 清除与加固:从应急响应到长效防御

4.1 清除六步走:杀进程、删文件、清计划任务

分析工作做完,接下来才是真刀真枪的清理环节。我在动手前把清理步骤写成了一张执行清单,避免在高压环境下漏掉哪一步。这六步可以说是最稳妥的通用处置流程:

第一步:隔离网络。先确认这台机器不是核心数据库节点,然后把它的外网访问权限临时断掉。这一步不是为了让木马“跑不出去”,而是防止攻击者在被清理的瞬间发动反向连接,尝试再次夺取控制权。

第二步:终止可疑进程。直接用kill -9之前定位到的所有可疑PID,从进程树的最顶层杀起。这个顺序比从叶子节点杀更有效,因为父进程一旦被干掉,子进程往往会失去守护而自行退出。

kill -9 所有可疑PID

第三步:删除恶意文件和目录。把/tmp、/usr/lib、/etc/systemd/system下的样本和配置全部清理干净,包括隐藏的文件夹。这一步特别强调:要删除的不是单个矿工程序,而是整个植入相关的文件簇,包括下载器脚本、配置目录、临时日志。

第四步:清理持久化入口。删除/etc/crontab里被注入的行,删掉/etc/cron.d下的脚本;把可疑的kworker.service在systemctl disable之后再删;一定要处理SSH公钥,删掉authorized_keys里攻击者留下的那条密钥。

第五步:修改所有密码和密钥。用passwd修改管理员密码、数据库密码、业务账号密码,同时把所有服务器的SSH密钥对重新生成一遍。攻击者可能已经把旧密钥转移到了别的机器,不改就等于给那些潜伏的通道留着后门。

第六步:重启并验证。最后重启服务器,等十分钟,重新观察CPU、网络、进程和日志。如果一切正常,再执行一次全磁盘扫描确认干净。

4.2 系统加固:把进不来的门焊死,把进得来的门锁好

清理完木马之后,如果不做加固,大概率过段时间同样的日子还会再上演一遍。这个过程我总结成一句话:把进不来的门焊死,把进得来的门锁好。

先处理SSH远程访问:

# 禁止root直接登录 sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config # 限制SSH来源IP,只允许办公网段 iptables -A INPUT -p tcp --dport 22 -s 192.168.10.0/24 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j DROP

禁用root登录这件事,网上争议很大,但我的经验是:宁可把权限管控放到sudo和堡垒机里,也别让一个固定密码的root裸奔在公网。攻击者一旦爆破成功,直接就是最高权限;换成普通用户加sudo授权,即便爆破成功也得多撞一道门。

然后处理中间件漏洞。我们当时把中间件升级到了最新版本,关闭了文件上传和调试模式的非必要路径,并在Web层增加了访问频率限制和非法请求拦截。这里需要注意:升级操作要有灰度策略,不能一台机器直接躺下,否则没过一会儿可能就是另一场事故。

监控层面的加固也不能少:给服务器加上主机安全防护软件,开启CPU使用率按进程维度的告警。一旦某个进程占用超过一个阈值(比如80%持续5分钟),立刻触发通知;这种监控在木马刚起跑的时候就能报警,比跑到100%才发现要舒服得多。

4.3 挖矿木马排查与处置速查表

我把这次应急响应的核心经验整理成一张速查表,放在这里供各位直接“抄作业”。这不是从网上复制的模板,而是结合本次完整处置过程的复盘:

阶段检查点核心命令/动作备注
发现CPU占用率top -b -n 1 | head -20挖矿进程通常CPU占用>90%
发现进程异常ps aux --sort=-%cpu关注异常进程名、路径、启动用户
定位进程路径ls -l /proc/PID/exe路径在/tmp等目录基本可判定
定位启动链路crontab -l; cat /etc/crontab; systemctl list-unit-files重点查定时任务和systemd服务
定位后门残留cat /root/.ssh/authorized_keys存在陌生公钥即视为后门
定位网络外联ss -antlp | grep PID检查矿池地址、异常远端IP
取证样本留存md5sum+sha256sum+strings记录哈希后归档样本
清理杀进程删文件kill -9 PID; rm -rf 路径按进程树整体清理
清理清持久化删除crontab/systemd/authorized_keys必须事件后验证重启
加固封闭入口改密码、禁root、关不必要的端口同时升级中间件版本
加固持续监控主机安全软件 + CPU阈值告警含按进程维度的告警规则

这张表的用法不是照着一条条跑完就算完事,而是要带着“为什么这么查”的思考走一遍。比如查看进程路径时,你和业务同学对一下线上目录结构,确认哪些路径是合法部署的,哪些是一眼就看得出奇怪的,这个过程本身就是排查能力的积累。

5. 从零基础到精通:一条可复制的成长路线

5.1 打好基本功:四类能力是排查的基础

我常被问到一个问题:“遇到这种木马,我连命令都记不住几个,怎么开始学排查?”我的答案是:从基本功开始,别急着背各种花哨的攻击工具,先把四类能力练扎实。

第一类是Linux系统的日常操作能力。ps、top、netstat、ss、find、grep这些命令的常见用法要做到张口就来,至少要能快速解决“机器卡了,看看谁在跑”这种问题。每天花十分钟看系统日志,也能积累出敏锐的“异常感”。

第二类是日志分析能力。日志不是数据库里那些数字,而是系统的“告白”和“吐槽”。学会看/var/log/auth.log、/var/log/syslog、Web服务的access日志和error日志,搞清楚哪些字段是用户IP、哪些是响应码、哪些是时间戳,这决定了你拿到一堆日志的时候是满眼乱码还是能一眼盯出可疑请求。

第三类是基础取证能力。不用去学高阶的反汇编,先把file、md5sum、strings、readelf这几个工具用好,学会从样本里提取哈希、字符串、调用关系,就是静态分析的入门。在此基础上若能跑一个沙箱,观察样本联网、写文件、进程调用的动作,动态分析的基本盘就有了。

第四类是安全加固意识。不是“等出问题再救火”,而是“没出问题前把坑填平”。密码策略、补丁升级、最小权限、外网端口收敛,这四件事做好,木马进来的门槛不知道要高多少。

为了方便新手查漏补缺,我列了一张自查表:

能力模块入门标准进阶方向
Linux命令能排查进程/网络/日志熟悉常见运维自动化和监控告警
日志分析能看懂登录日志和Web日志能通过时间线关联还原攻击路径
恶意样本分析会提取hash、字符串能脱壳、逆向关键逻辑
主机加固会改SSH配置、关端口能搭建主机入侵检测与告警体系

5.2 长期防护:让“矿工”进不来、跑不快、活不久

文章说到这里,最后想聊一聊长期防护的四个思路。我在很多项目里看到过一种奇怪的现象:清理完一台机器,开心地把报告发出去,结果三天后隔壁机器又被种了同样的矿。原因很简单,攻击者从来不会只盯着一台机器,而是对整个网段批量撒网。所以处理完之后,必须把防护动作上升到“全网”而不是“单机”。

思路一:收敛攻击面。把不需要暴露到公网的端口和服务全部停止,尤其是Redis、MySQL这类数据库服务,以及NFS、SMB这样的共享服务。任何服务被开放到外网,就意味着攻击者多了一条不用打补丁就能触达你的门路。防御时犹豫一天,攻击者可能已经扫了整个网段。

思路二:启用“应用白名单”。尽量通过主机安全产品设置进程白名单,只允许已知的合法进程运行。这就像是公司大楼只放行早已登记的工牌,矿机程序这种“陌生访客”在第一道闸机就会被拦下来。

思路三:部署“蜜罐”,给攻击者造一座迷宫。在一台低优先级机器上部署一个模拟服务,记录所有针对它的探测和利用尝试。一旦蜜罐被触碰,就给运维人员发送报警,同时引导追踪。这套技术并不昂贵,很多开源项目都能轻松搭建,效果却相当不错。

思路四:日志集中审计。把每台服务器的登录日志、Web日志、进程快照定期拉到一个集中的日志平台,设置自动关联分析和告警。在这次事件里,如果当时有集中式的日志告警,弱口令爆破成功的那一刻我就会收到通知,后面那些挖矿程序根本不会有在服务器上安家的机会。

我个人在实际操作中的体会是,处理挖矿木马最关键的环节其实不是“杀”,而是“防”之后的持续验证。清理完一次,一定要在半小时后、一天后、一周后分别复查CPU曲线、进程列表和定时任务;上线新的监控告警,才能真正确认伤口已经长好。相信读完这一篇,你对挖矿木马从发现到处置已经有了完整的概念,真正动手时也会更从容。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询