☰
Linux服务器挖矿木马应急响应排查与处置实战指南
2026/10/21 14:51:51 网站建设 项目流程

1. 事件开端:凌晨的两条安全告警

上周值班,晚上十一点多,安全平台的告警突然响了两条。第一条是某台服务器的CPU使用率持续15分钟超过90%,第二条更直接——检测到该服务器与一个已知矿池地址建立外联通信。

半夜看到这种组合告警,基本可以判定是挖矿木马了。单看CPU飙高可能有别的解释,比如业务高峰期或者定时任务跑批,但一旦同时出现外联矿池的行为,那问题就比较明确。

我没有直接登服务器就动手,而是先做了一件应急响应里最容易被忽略的事——确认这台机器上跑的是什么。

这里想强调一个处置原则:接到告警的第一反应不该是赶紧杀进程,而是先搞清楚这台服务器承载什么业务、有没有其他节点可以顶替、能不能直接隔离。因为一旦误操作,比如把还在跑批的业务进程当成木马干掉,或者贸然重启服务器,后果可能比木马本身更严重。

确认了一下,这台机器是某内部系统的单机节点,不是核心数据服务,影响面可控。于是按流程走处置:先查封端口和恶意IP,再做现场定位和清理,整个过程从登录到基本控制住,大约用了两个小时。

2. 排查定位:从CPU异常到挖矿木马实锤

2.1 进程排查:异常进程不会藏太久

登录服务器之后,我习惯性的第一屏操作还是top,先看整体负载。单看下图的意思大家应该都懂:系统满负载,几个核心都跑满了,User态占用非常高。

接着按CPU降序,直接锁定一个可疑进程,进程名看起来是一串随机字符串。随手用ps -ef拉一下这个进程的详细信息,能看到启动时间、运行用户、父进程PID。

这里有个细节值得多说一句:不要只看进程名。挖矿木马很多会伪装成系统进程名,或者用看起来很正常的名字,比如 "php-fpm"、"kworker"、"java" 之类,所以我判断异常进程的要点是——启动时间是不是系统开机或者正常业务部署的时间点、运行用户是不是异常用户、CPU占用率是不是持续居高不下,而不是只凭进程名。

这一步我拿到了关键信息:

  • 进程启动时间正好是三天前凌晨,这个时间点没有发布、没有变更记录
  • 运行用户是www,但这台机器不是Web服务器
  • 父进程是PID 1(systemd),典型的daemon型驻留方式

实锤基本跑不掉了,继续往下挖。

top -c ps -ef | grep <PID>

2.2 从进程反查文件与网络连接

挖矿木马三个要素缺一不可:恶意样本文件、外联矿池的网络连接、持久化机制。

进程已经锁定,接下来要找到它对应的文件。这个不一定要去翻目录,直接用Linux的/proc文件系统就行:

ls -l /proc/<PID>/exe cat /proc/<PID>/cmdline lsof -p <PID>

这里可以看到三个东西:

  • 可执行文件的实际路径(指向一个奇怪的路径,比如/tmp/.x或/var/tmp/...)
  • 命令行参数(矿工程序通常有一堆参数,比如指定矿池地址、钱包地址、线程数)
  • 进程打开的文件列表(能看到日志文件、配置文件等)

网络排查也是同步进行的。用netstat或ss查端口连接,直接过滤这个PID:

ss -anop | grep <PID>

结果就是刚才告警里提到的那个IP,走的是SSH端口高位区间的一个端口。这里插一句,很多挖矿木马用的外联端口不是常规80/443,而是自定义高位端口,千过滤的时候别只盯着常见端口看。

2.3 持久化机制排查:木马是怎么活下来的

挖矿木马的驻留方式就那么几类,但很多应急响应新手最容易漏掉的恰恰是这一环。进程杀了、文件删了,结果几分钟后木马又自己起来了,就是因为持久化没清干净。

我排查持久化是这么做的,按优先级逐个过:

  1. 定时任务:crontab -l、/etc/crontab、/etc/cron.d/、/etc/cron.hourly/、/var/spool/cron/
  2. 系统服务:systemctl list-unit-files | grep enabled,重点看近期修改过的service文件
  3. 启动脚本:/etc/rc.local、/etc/init.d/、~/.bashrc、~/.profile
  4. SSH后门:~/.ssh/authorized_keys里有没有陌生的公钥

结果不出所料,在/etc/cron.d/里发现一个隐藏文件,内容是一行定时任务,每三分钟执行一次某个脚本。脚本内容我没急着看,先复制存档,因为这种东西是后面做溯源的关键证据。

又检查了一下/root/.ssh/authorized_keys,果然多了一条陌生的公钥——这属于典型的后门行为,攻击者给自己留了个随时能回来的通道。这一步如果不检查,光杀木马是没用的。

3. 攻击入口还原:这木马是怎么进来的

3.1 矿机木马最常见的入侵路径

处理过几次矿机事件之后,你会发现攻击入口翻来覆去就那么几种,对号入座就能省去大量排查时间:

入口类型具体途径典型特征
弱口令爆破SSH、数据库、Redis等对外服务口令过于简单登录日志大量失败记录,最终有成功记录
未授权访问Redis空口令、Docker API暴露、Elasticsearch无认证直接可写入crontab或执行命令
Web漏洞反序列化、上传漏洞、命令注入进程运行在Web应用用户下
系统漏洞补丁长期未更新,被已知漏洞利用通过漏洞利用工具下载样本落地

这次的事件基本可以锁定为第一类——弱口令爆破。

3.2 从日志里找证据

我翻了/var/log/secure(CentOS/RHEL系统)和/var/log/auth.log(Debian/Ubuntu系统)的登录记录,两头时间线一对,情况就清楚了。

在木马进程启动的那天凌晨,这台机器从某个IP段发起了连续几百次SSH登录尝试,用户名就是一个常见的弱口令。前面全是Failed password,中间穿插着一次Accepted password for root,时间跟恶意文件的创建时间几乎同步。

这里建议大家排查的时候,重点看这个时间交叉点:

  • 成功登录的时间点
  • 恶意文件落地的时间点(stat文件的 mtime/ctime)
  • 挖矿进程启动的时间点

三个时间点吻合,就能把“入口——落地——执行”这条链还原出来。

至于那个IP的地理归属和具体来源,我不建议花太多精力去深挖,因为挖矿木马基本都是批量扫描批量种,攻击者的肉鸡也可能只是另一台被控机器,溯源到这一步就够了。应急响应的重点永远是先止损、后修复,而不是破案。

4. 清除与恢复:现场处置操作实录

4.1 处置前准备:先留证,再动手

我之前处理过几起应急事件,也踩过“什么都还没留就把样本删了”的坑,所以这次特意等了几分钟,先把该存的东西全部打包:

cp /etc/cron.d/<恶意文件> /root/recovery/sample_cron.txt cp /tmp/.x/挖矿程序 /root/recovery/miner_sample crontab -l > /root/recovery/crontab_backup.txt ss -anop > /root/recovery/network_connections.txt

留证据这件事特别重要,不只是为了写报告交差,更实际的意义在于,后续想分析这个木马的传播方式、回连地址、内部特征,手里得有样本和原始数据。如果杀太快,到时候想复盘就只能靠记忆了。

4.2 网络隔离与外联封禁

在确认这台机器不是核心业务之后,我做的第一件事不是杀进程,而是先切断外联。如果最后要保留样本做行为分析,网络隔离是必须的前提;即便是纯处置,限制木马与矿池通信也能避免它继续“干活”。

实操上分两步:

  1. 在防火墙上将外联目标IP加入黑名单
  2. 在本地用iptables临时封禁该IP
iptables -A OUTPUT -d <矿池IP> -j DROP iptables -A INPUT -s <攻击者IP> -j DROP

注意,这种操作是临时手段,但能立刻止损。我见过有人不做隔离直接杀进程的案例,结果木马在清理完后又换了端口重新连出去,等于白忙。

4.3 终止进程并清理文件

网络隔离做完,接下来才轮到杀进程。第一步先确认进程状态,然后用kill结束它:

kill -9 <PID>

杀掉之后稍等几秒,再用top和ps确认没有自动拉起。这一步是有讲究的,很多木马带了守护进程,或者通过定时任务几分钟后重新拉起,所以杀完进程之后,至少要观察两个周期(也就是定时任务执行周期的两倍),确认没有复活才算初步控制住。

如果出现反复拉起的情况,建议直接用chattr +i给恶意文件加锁,或者先删除定时任务再杀进程,顺序不能反。

进程清理完之后,就是文件清理。我把发现的恶意文件全部记录路径,逐一删除:

rm -rf /tmp/.x rm -f /etc/cron.d/<恶意文件> rm -f /usr/lib/.../... sed -i '/恶意内容/d' /root/.bashrc

删除完之后,把定时任务目录又过了一遍ls -la /etc/cron.d/,把带着奇怪文件名和隐藏属性的文件全部找出来。这块真得细心,很多应急响应失败就失败在只清了一半。

4.4 账号与后门清理

文件清理完成,还有三类东西要处理:

第一是SSH公钥后门。直接编辑/root/.ssh/authorized_keys,把陌生公钥那一行删掉。这里顺手检查了所有有home目录的用户,确保不只是root被留了后门。

第二是可疑系统账号。/etc/passwd、/etc/shadow都翻了一遍,重点看有没有UID为0的非root账号,或者最近新增的具备shell登录权限的账号。这次倒是干净,没有这种问题。

第三是密码整改。不管木马是不是通过弱口令进来的,密码全部强制改一遍是必须的。而且这台机器用了多长时间没用过复杂密码,可能连管理员自己都不清楚了。

4.5 观察期:别急着宣布恢复

处置完成不代表可以撒手不管。我把定时任务清除、恶意文件删除、账号清理完之后,没有立即交还业务,而是先观察了12个小时。

观察期间重点看三件事:

  • CPU使用率是否始终平稳
  • 是否还有新进程或新文件落地
  • 安全平台是否还在报外联告警

我见过最尴尬的局面就是上午刚宣布处置完成,下午同样的告警又来一遍。原因就是没观察够时间,或者木马的备用路径没找干净。建议大家宁可把观察期拖长,也不要为了赶进度提前收工。

5. 溯源取证:把攻击者的路径走一遍

5.1 时间线重建

清理完之后,我把手头的信息整理成一条完整的时间线:

时间点事件
三天前 02:15攻击者IP对SSH进行暴力破解
三天前 02:43弱口令登录成功
三天前 02:44恶意脚本落地到 /tmp 目录
三天前 02:45下载矿工程序并设置 /etc/cron.d/ 定时任务
三天前 02:46挖矿进程启动并连接矿池
今天 23:10安全平台告警触发

这个时间线看似简单,但真正能把时间线完整还原出来的人并不多。还原的关键是不要只看单一日志,而是把登录日志、文件时间戳、进程启动时间、网络连接日志几个维度对在一起,交叉验证。

5.2 恶意脚本的行为画像

我把那个恶意脚本的完整逻辑拆了一遍。这类脚本通常干的事很固定:

  1. 写入一个自身标记,避免被同类木马重复感染
  2. 清理其他挖矿木马留下的文件和进程(同行之间会互相攻击,这也是挖矿木马的典型特征之一)
  3. 下载矿工程序并赋予可执行权限
  4. 写入定时任务,确保周期性拉起
  5. 修改/root/.ssh/authorized_keys,植入后门

我手动复现了一遍它下载文件的URL路径,尝试拉取了同一样本做对比。这一部分不在线描述具体域名了,但方法可以分享:用wget或者curl去访问同一个路径,看返回值是否一致,如果一致,说明攻击源还在活动,需要继续封堵。

5.3 影响面评估

单机处置结束后,还有一个问题需要回答:这木马是不是只感染了这台机器?

挖矿木马一般不太会主动做内网横向扩散(相比勒索病毒,它们的横向移动能力弱得多),但并不意味着没有可能。我在同网段里抽查了几台服务器,重点看了三方面:

  • 是否有来自被感染机器的成功登录记录
  • 是否存在同样的恶意定时任务
  • 是否有外联同一个矿池IP的连接记录

抽查结果正常,只有这台机器本身中招。这是不幸中的万幸,如果内网横传开了,整个排查量会翻好几倍。

6. 防复发加固:从单台服务器到体系防御

6.1 系统基础加固清单

处置完成只是开始,真正的收尾工作在这里。所有中招服务器,我按下面这个清单做了一遍加固:

  • SSH服务整改:禁止root直接登录(PermitRootLogin no),有条件就换密钥登录,弱口令必须改
  • 密码策略:强制长度和复杂度,定期更新
  • 关闭非必要对外端口:这台机器本身没有对外提供服务的需求,我直接把不必要的端口全关了
  • 安装并配置主机安全Agent:文件监控、进程监控、登录行为监控三件套
  • 漏洞补丁更新:系统当前已知的高危漏洞补丁全部打上
  • 最小化原则:卸载不需要的组件和依赖包,减少攻击面

这里想单独说一下SSH的处置逻辑——攻击者能进来,核心原因就是弱口令。只改一个密码其实不够,因为密码这种东西总有可能再次被猜中。更好的做法是直接用密钥登录,彻底关掉密码认证。如果团队还没有统一的密钥管理系统,至少也要把root密码禁用的规则落地。

6.2 告警与监控策略调优

告警为什么会到第二天才触发?关键原因是挖矿进程的行为特征没有在第一时间被识别。

这次告警其实是靠CPU阈值触发的,说明平台之前没有部署针对外联矿池特征地址的IOC检测规则,也没有针对可疑进程行为的检测模型。

事后我把两条规则补上了:

  • 主机外联已知恶意IP或矿池地址的实时告警(参考了公开威胁情报库)
  • 针对/tmp、/var/tmp目录下新增可执行文件的行为监控

这里有一个经验,告警规则宁可比全也不要比精。挖矿这类事件,核心特征是和高频、稳定的数据源(威胁情报、文件监控)做关联,而不是完全依赖单一设备的告警。

6.3 从单点处置到批量巡检

处置完一台机器后,我还做了一件很重要的事,把同网段、同配置的一批服务器全部拉出来做了批量巡检。这一批巡检清单包括:

find /tmp /var/tmp /dev/shm -name "*.sh" -type f -mtime -7 crontab -l cat /etc/cron.d/* ls -la /root/.ssh/authorized_keys cat /etc/passwd | grep -v /bin/false

批量巡检这件事很多时候会被省略,但我在实际工作中吃过亏——如果不做全网巡检,第二台中招的机器可能在一周后才被发现,到时候整个安全团队又要熬夜。所以这里强烈建议,任何安全事件处置完毕后,至少在相关网段做一轮“同因隐患排查”。

7. 复盘总结:命令速查与避坑心得

7.1 应急处置速查表

最后把这次用到的排查命令整理成一个速查表,供大家直接复制使用:

排查目标推荐命令
查看CPU高占用进程top -c/ps aux --sort=-%cpu`
查看进程详情ps -efcat /proc/<PID>/cmdline
查看进程落地文件ls -l /proc/<PID>/exelsof -p <PID>
查看网络外联ss -anopnetstat -anop
查看定时任务crontab -lcat /etc/crontabls /etc/cron.d/
查看SSH后门cat /root/.ssh/authorized_keys
查看异常账号cat /etc/passwdcat /etc/shadow
查看系统服务`systemctl list-unit-files
查看登录日志grep "Accepted" /var/log/secure*

这张表的逻辑是排查面全覆盖:从进程到网络、从文件到持久化、从账号到日志。建议大家可以打印出来贴工位上,或者存进自己常用的工具笔记里。

7.2 这次踩过的坑

第一个坑:刚开始我只处理了定时任务和矿工程序,直接忽略了SSH公钥后门。如果不是顺手多查了一步,攻击者过几天就能重新连回来,之前的工作全都白做。

第二个坑:清理完文件之后没有立刻做文件系统快照对比。后来想复盘木马具体改动了哪些系统文件时,已经找不到原始状态了。如果条件允许,建议处置前先做一次全盘hash清单(比如find命令配合md5sum),方便事后比对。

第三个坑:处置期间忘了通知业务方。虽然这台机器不是核心业务,但数据平台上的临时任务还是被中断了,业务同事第二天看到告警邮件才来找我。应急响应虽然是安全部门主导的事,但上报和沟通不能漏。

7.3 个人体会

挖矿木马这种事件,说难不难,说简单也不简单。它不像零日漏洞利用那样需要高超的技巧,更像是一次“照妖镜”,把系统弱口令、补丁滞后、监控缺失、权限过大这些日常疏忽照得一清二楚。

这次事件处置完,我最大的感受是——应急响应拼的不是单一的技术环节,而是完整的处置链条:及时发现、准确判断、全面排查、干净处置、深入追溯、彻底加固。这个链条任何一个环节薄弱,都可能让前面的努力白费。

最后再多说一句:如果你发现自己碰到的服务器也出现了CPU异常升高的情况,不要慌,按上面的流程一步步走,先取证、再隔离、再清理、最后加固,每一步都别省,基本就能稳稳收住。安全这个活儿,有时候考验的真的不是知识量,而是能不能耐着性子把最基础的步骤做实做透。

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

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

立即咨询