新闻详情

新闻详情

首页 / 资讯中心 / 详情

挖矿病毒入侵实录:CPU飙高排查与服务器安全加固指南

发布时间:2026/9/15 14:58:14来源:尧图网络
挖矿病毒入侵实录:CPU飙高排查与服务器安全加固指南
1. 故障初现好好的服务器CPU怎么突然飙满了那天下午我正处理手头的事突然收到一连串监控告警同一台线上服务器的CPU使用率从平时不到20%一路冲到99%持续了好几分钟没降下来。第一反应是业务代码出问题了比如死循环、内存溢出导致频繁GC或者定时任务重叠但登录服务器后感觉不对劲——top看下来进程列表里根本没有一个属于我们业务的进程反而是系统目录里多了一个奇怪的东西。这里先说明一下背景。中招的这台服务器是常见的Linux发行版跑着Nginx和Java应用对外开放了80/443端口另外因为运维需要还开着22端口。没有上云平台自带的安全防护安全组规则也不算严格属于“裸奔”状态。排查下来确认是被人植入了挖矿病毒恶意文件路径和进程名都指向同一个关键词systemd-service.sh。这类入侵在当下非常普遍原理不复杂攻击者扫描互联网上暴露的端口利用弱口令爆破或者应用漏洞拿到一台服务器的控制权然后投放挖矿程序让服务器24小时替他们计算加密货币电费和CPU损耗都由受害者承担。这篇文章把当时的完整排查思路、定位方法、清理步骤和事后加固都整理出来如果你是做运维、后端或者自己捣鼓服务器的遇到CPU异常飙高可以直接照着排查一遍。2. 排查思路遇到CPU飙高先别急着kill进程很多人一看CPU满了第一反应就是top找到高占用PID然后顺手kill -9。但挖矿病毒通常不会单点作战——你杀掉主进程它的守护进程几十秒内就能把它重新拉起来甚至换一个名字继续跑。所以我当时给自己定了一个排查顺序也建议你按这个顺序来先确认现象CPU到底是被哪些进程吃掉的进程的可执行文件在哪个路径。再确认持久化手段进程是靠什么机制被重新拉起来的crontab、systemd服务、启动项等。最后才动手清理按“关守护机制→杀进程→删文件→删定时任务”的顺序操作顺序反了就是白忙。这个思路不是我发明的方法论而是踩过坑之后的教训。早些年内网也出现过类似问题有同事看到进程PID就kill -9结果一分钟后又冒出来一个新PID来回折腾了几轮才发现crontab里藏着一条下载执行的定时任务每两分钟就把脚本重新拉起来一次。所以遇到挖矿病毒第一步永远是诊断不是治疗。另外一个容易忽略的细节是要记录现场。top、ps的输出、/proc目录下的软链接信息在清理前都值得留一份副本。原因有二一是排查时需要反复对照二是如果清理后问题复发历史快照能帮你快速判断是不是同一个样本变种。在正式动手前我先把关键信息抓了一遍。以下几条命令是整个排查的“起手式”# 查看当前CPU占用最高的进程 top -c -b -n 1 | head -30 # 查看进程完整命令行和父子关系 ps -ef --sort-%cpu # 查看所有监听端口和对应进程 ss -tnp # 查看进程可执行文件路径关键 ls -l /proc/PID/exe执行之后情景很快浮出水面。一个PID显示为systemd-service的进程CPU占用率稳定在300%以上而且/proc/PID/exe指向了一个脚本文件路径在/tmp下这本身就极不正常——正常的systemd服务不会从/tmp启动更不会用300%的CPU。2.1 top和ps输出里的“伪装痕迹”挖矿程序为了降低存在感进程名通常会伪装成系统服务、内核线程或者常见软件名。常见伪装名有systemd-service、kworker、kthreadd、mysql、nginx这种但仔细看还是有马脚进程名和实际路径对不上。ps -ef里叫systemd-service但/proc/PID/exe、/proc/PID/cwd指向的却是/tmp、/var/tmp、/dev/shm这类临时目录。CPU占用极其稳定长时间维持在百分之几百不是业务流量的波峰波谷。启动时间点非常蹊跷往往在凌晨或者最近几天某一次登录日志附近和人工上线时间对不上。我当时看到systemd-service.sh这个名字基本就能判断是常见挖矿投放脚本。原因很简单正常systemd服务单元文件是/etc/systemd/system/xxx.service里面写的是启动命令和依赖关系不会出现一个直接挂在/tmp下的.sh文件。而很多自动化的挖矿投放脚本为了省事直接通过crontab下载执行一段shell这段shell再创建服务和进程命名的时候随手用了看起来像系统服务的名字。ps和top的输出里还有另外一个特征值得留意很多挖矿进程会用comm字段占位真正的执行文件路径反而在命令行参数里。所以排查时不能只看ps -ef列表里的前几个字段要把完整命令行打出来ps -eo pid,user,stat,pcpu,pmem,args --sort-pcpu | head -40这条命令的优势在于args列包含了进程的完整参数能直接看到它启动时带了什么参数、指向什么脚本或二进制文件。我执行的输出里有一个进程发起了一个看起来非常可疑的bash进程参数里带了curl加一个外部域名加管道|加bash典型的一行远程下载执行。3. 顺着进程信息挖脚本.systemd-service.sh的完整结构拿到PID之后我做的第一件事不是杀而是把进程相关的所有细节都翻出来。这里给出一份可以直接抄的检查清单# 1. 确认可执行文件真实路径 ls -l /proc/PID/exe # 输出里会告诉你这个进程实际在跑的文件是哪个 # 2. 查看进程的工作目录 ls -l /proc/PID/cwd # 3. 查看进程打开的fd尤其是它写了哪些文件 ls -l /proc/PID/fd # 4. 查看进程启动时使用的环境变量 cat /proc/PID/environ | tr \0 \n # 5. 查看进程命令行 cat /proc/PID/cmdline | tr \0 这套操作比ps更底层因为这些信息直接来自内核的/proc文件系统很难被用户态程序完全掩盖。我一个个看下来发现几个关键线索/proc/PID/exe已经被脚本删除所以ls -l出现“deleted”字样。这几乎可以断定是样本的自我保护手段——运行后删除自身文件避免被find / -name扫到。这个进程的fd里有一条连接指向一个境外IP的3333端口这是很多挖矿程序连接矿池的典型端口区间。工作目录在/tmp说明来源很可能是一个从外部下载到/tmp的shell脚本。顺着这些线索我在/tmp目录下找到了残留的systemd-service.sh。清理和溯源都需要把这脚本读一遍。打开文件后里面是很典型的挖矿投放三段式逻辑第一段环境准备。检查系统里有没有curl、wget这类下载工具没有就换一种方式下载把CPU核心数和可用内存记录下来方便后面决定启动多少个挖矿线程。第二段下载执行核心载荷。脚本从远程服务器拉取一个二进制文件通常是XMRig这类开源门罗币挖矿程序或者其魔改版本赋予执行权限后直接在后台运行。输出信息一般瞒不住脚本作者会把它重定向到日志文件像/tmp/.xrig.log这种隐藏文件。第三段持久化和自我复制。脚本向/etc/cron.hourly、/etc/cron.d/、当前用户的crontab里写入定时任务确保每隔几分钟就重新执行一次自身如果系统里存在systemd且权限足够还会写一个伪装成系统服务的unit文件设置Restartalways。这就是为什么进程名叫systemd-service其实就是一个挂名systemd的服务单元。我需要强调一下挖矿病毒的可执行文件极多systemd-service.sh只是其中一个样本名。你排查时遇到的文件名可能是kworker、crond、sysguard、php-fpm、.x11vnc等等但整体套路大同小异。掌握了解析脚本的能力剩下的就是见招拆招。3.1 揪出隐藏的持久化项crontab和systemd服务定位到脚本文件后下一步是清理所有能把它拉起来的持久化机制。这一步不能省因为很多人清理完进程和文件后发现CPU又飙起来几乎都是漏了持久化项。重点检查以下位置# 1. 当前用户和root用户的crontab crontab -l # 如果系统里还有其他用户也要逐个检查可以查看 /var/spool/cron/ 目录 # 2. 系统定时任务目录 ls -la /etc/cron.d/ ls -la /etc/cron.hourly/ ls -la /etc/cron.daily/ # 3. systemd服务单元包括真正生效的和残留的 systemctl list-unit-files | grep -i -E systemd|tmp|mine|watch ls -la /etc/systemd/system/ | grep -v want # 4. 开机自启动项 ls -la /etc/init.d/ cat /etc/rc.local在我这台机器上发现/etc/cron.d/下有一个随机文件名的任务内容是每两分钟执行一次/tmp/systemd-service.sh而/etc/systemd/system/下多了一个名为systemd-service.service的文件里面配置了ExecStart/tmp/.systemd-service.shRestartalways意思是进程即使被杀掉systemd也会立刻重启它。这两处就是CPU问题的“不死”根源。这里要特别留意一点很多攻击脚本会同时修改多个用户的crontab不只是root。如果你用crontab -l只看了当前登录用户其他用户的定时任务就会漏掉。我的建议是直接查看/var/spool/cron/目录看看里面有哪些文件文件名就是用户名逐个确认是不是业务上认识的账号。另外/etc/rc.local在一些旧的Linux版本里依然是默认启动项。攻击者如果权限够高会往这里塞一行/tmp/xxx.sh 。清理的时候不能只看crontab所有开机启动的路径都要过一遍。4. 清理实操从“止血”到“断根”的完整流程诊断清楚之后我按下面的顺序一步步执行清理。这个过程和在案发现场拆弹差不多一上来就乱动反而容易把线索弄丢节奏要稳。第一步隔离网络切断挖矿进程与外部的通信。这一步很多人会忽略但非常重要。挖矿程序如果还能连接矿池你杀掉进程后它也可能把已算好的份额提交出去或者从服务器再拉新的恶意代码。最直接的办法是先用防火墙规则封禁掉恶意连接不给它和外网继续通信的机会。# 可以在服务器上临时封禁已识别的矿池IP iptables -A OUTPUT -d 恶意IP -j DROP iptables -A INPUT -s 恶意IP -j DROP如果业务允许停机更干脆的做法是直接断开外网或关掉网卡让挖矿进程变成孤岛。但在实际生产环境里这是要评估的不能贸然断网。我当时的处理是封禁已发现的IP把对外通信先挡住。第二步停用systemd服务并删除服务文件。这一步是断根的第一步如果不先禁用systemd里的自启服务后面杀进程会立刻被拉起来所以顺序必须反着来。# 停止并禁用恶意服务 systemctl stop systemd-service.service systemctl disable systemd-service.service # 删除服务单元文件 rm -f /etc/systemd/system/systemd-service.service # 重新加载systemd配置让修改生效 systemctl daemon-reload执行完这一步相当于拆掉了它“定时复活”的机制之一。crontab里的定时重启任务会在下一步处理。第三步清理crontab中所有恶意定时任务。逐条查看/var/spool/cron/下的文件把指向/tmp或其他异常路径的任务删除。如果crontab里只有恶意任务可以直接用crontab -r清空但生产环境里crontab往往有正常业务任务所以逐条删除比整体清空更安全。删除时可以保留一份备份方便后续溯源或审计crontab -l /tmp/crontab_backup_$(date %F).txt # 然后编辑删除 crontab -e第四步杀掉挖矿进程并删除文件。进程和文件都不能留。如果只删文件不杀进程挖矿程序还在内存里跑着不断写新的文件出来如果只杀进程不删文件它靠持久化机制又会被拉起来。正确的做法是在前几步已经处理好重启机制的前提下立刻杀进程然后删文件。kill -9 PID # 确认没有同名进程残留 ps -ef | grep -i -E systemd-service|xrig|kworkerdb | grep -v grep # 清理已知恶意文件 rm -rf /tmp/systemd-service.sh /tmp/.systemd-service.sh /tmp/.rsync这里要说明一下/tmp下的文件并不是全部可以删除要先确认。很多程序运行时会往/tmp写临时文件业务上可能也有依赖所以删除前一定要用ls -la /tmp看看时间戳和文件名把可疑的列出来再逐个确认。第五步全盘搜索同类恶意文件。挖矿投放脚本为了提高攻击成功率通常不会只放一个文件。我建议全盘搜索以下特征隐藏目录、带矿池关键词的文件名、近期被修改的可疑二进制文件。find /tmp /var/tmp /dev/shm /var/spool -type f -mtime 1 -exec ls -la {} \; 2/dev/null | grep -v ^d find / -name *xrig* -o -name *systemd-service* -o -name *pools* 2/dev/null | grep -v -E ^/proc|^/sys第六步查看登录日志和确认识别入侵来源。清理干净之后我顺便查了一下历史登录记录和auth日志确认攻击者是从哪个IP进来的。虽然伤害已经造成但这个环节对我的安全加固非常有帮助——可以知道它是爆破SSH还是走了某个应用漏洞后续针对性地做防护。# 查看最近登录记录 last -20 # 查看认证日志 grep -E Failed|Accepted /var/log/secure* | tail -50 # 如果是CentOS/RedHat系secure日志是主要来源Ubuntu/Debian可以看 /var/log/auth.log这条日志给了比较明确的信息攻击者连续尝试了大批常见用户名和密码的组合最终在某个弱口令账号上试成功了然后通过SSH登录上来执行了一段下载命令植入挖矿程序。整个过程从爆破成功到植入完成不到一分钟。4.1 清理后的验证CPU降下来了不代表就安全了清理完之后我在三分钟内观察CPU负载的变化。正常情况下CPU使用率应当从百分之几百降到接近于0像这种业务本身流量不大的机器load average应该掉到0.5以下才算正常。但是CPU降下来只能说明挖矿进程没了不代表服务器是安全的。后续我做了两件事作为验证第一检查是否还有外联的可疑连接。等几分钟后用ss -tnp重新看一遍连接列表确认没有指向陌生IP的TCP连接。矿池地址的端口通常比较固定比如14444、3333、5555、8080等看到这些端口出现在非业务连接的列表里就要警惕。第二把系统里所有通过systemd自启的服务过了一遍列出那些不在我们部署清单里的服务单元逐个确认。这个动作平时也要养成习惯定期的自启项审计能让你在攻击者植入后第一时间发现异常。清理后观察了一整天CPU再没有异常飙升/tmp下也没有再产生可疑脚本整个事件算是暂时解决了。5. 安全加固处理完不代表结束重点是下一次别中招清理掉挖矿病毒只是治标接下来要治本。否则以这台服务器的暴露程度和薄弱配置大概率过几天又被扫到、再次中招甚至可能被植入更隐蔽的后门挖矿只是攻击者拿到权限后最常规的赚钱手段。5.1 修改所有账号密码强制使用强口令和密钥登录。既然日志明确指出弱口令爆破是入口第一步必须是改密码。所有系统账号、数据库账号、应用后台密码全部更新新密码至少要16位以上且不能由密码中的简单词拼接而成。更安全的方案是关闭密码登录只保留SSH密钥登录。编辑/etc/ssh/sshd_config设置PasswordAuthentication no PubkeyAuthentication yes然后重启sshd服务。这意味着没有密钥文件的人无论密码多正确都无法登录爆破手段直接失效。不过要小心一点在设置之前必须先把本机的公钥配置到目标用户的~/.ssh/authorized_keys里否则你自己也会被锁在外面。建议操作前多开一个SSH会话保持在线改完配置后另外开新窗口验证能登录再关闭旧会话。5.2 限制SSH暴露范围启用fail2ban做自动封禁。如果业务没有特殊要求不建议把22端口对全网开放。可以配置防火墙只允许公司出口IP或者跳板机的IP访问22端口。这样攻击者连端口都扫不到爆破成本大幅提高。对于不能限制来源IP的场景建议部署fail2ban它能实时监控认证日志发现同一个IP在短时间内多次认证失败就自动封禁一段时间。我自己的规则是10分钟内失败3次封禁1小时误封概率很低但对爆破的打击效果非常明显。5.3 收紧应用层面的漏洞面。很多挖矿投放不是靠SSH爆破而是利用Web应用或中间件的漏洞拿到的初始权限。比如Redis未授权访问、Nacos默认密钥、Elasticsearch未鉴权、Java反序列化漏洞等。如果你的服务器开放了这些服务建议确认以下几点Redis、MongoDB这类数据库服务不要对公网监听0.0.0.0能只监听内网就只监听内网。必须公网访问的服务加上认证。Redis至少要设置requirepass且密码要强。第一时间关注和部署官方安全补丁特别是中间件和开发框架的漏洞公告。最小化原则服务器上的软件能不多装就不多装很多挖矿病毒就是通过某个你根本想不起来的服务进入的。5.4 建立基本的监控和告警机制。这次如果不是监控系统告警在几分钟内发现CPU异常挖矿程序可能在机器上跑好几天才被发现账单和损失都会大得多。所以一套基础的监控告警对即使只有一两台服务器的运维者也很重要至少要做到CPU、内存、磁盘使用率的趋势监控CPU持续超过80%时告警。进程列表变化的审计新增的、名字可疑的进程能第一时间发现。对外网络连接数量变化以及请求境外IP的告警。SSH登录成功和失败的通知。实现方式有很多云平台自带的监控告警可以满足基本需求裸机环境可以用NodeExporter加Prometheus简单一些的也可以写脚本定期检查然后推送到企业微信或钉钉机器人。6. 复盘总结这台机器给我的几点教训处理完这台机器后我坐在电脑前复盘了整个经过。坦白说这次中招本质上是运维基础工作没做到位没有禁用密码登录、密码强度不符合要求、公网端口暴露面过大、也没有做基础的安全基线检查。攻击者的手法没有任何高级之处就是全互联网扫描SSH端口加字典爆破遇到弱口令就直接拿下。这台机器清理后的第三天我又登上去看了一眼安全日志果然又出现了几波针对22端口的爆破尝试但都因为已经改成密钥登录和限制IP而失败。这更加印证了一个观点安全不是靠某一次清理就能一劳永逸的它是一个持续维护的过程。如果你现在也在排查服务器CPU飙高的问题并且已经在进程列表里看到类似systemd-service这种可疑名字希望这篇文章能让你少走一些弯路。按着“看现场、查持久化、断根、加固”的顺序来即使不是同一个样本排查思路也完全适用。最后再强调一句任何时候在服务器上执行清理操作之前先备份必要的日志和文件否则溯源的线索很容易就断了。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

抖音X-Gorgon签名演进:0408到8408的设备注册协议解析 2026/9/15 16:28:34

抖音X-Gorgon签名演进:0408到8408的设备注册协议解析

看到标题里“0408”“8408”这两个编号,做客户端研究的朋友应该都会心一笑。这说的就是抖音请求签名里的X-Gorgon参数版本号,而它最常被讨论的使用场景,正是设备注册协议。很多朋友研究抖音的数据链路,第一步卡在设备注册上&#…

阅读更多 →
VisionPro九点标定实战:从像素坐标到机器人抓取坐标 2026/9/15 16:28:34

VisionPro九点标定实战:从像素坐标到机器人抓取坐标

做机器视觉这几年,经常被问到同一个问题:“相机已经拍到零件了,坐标也出来了,怎么让机器人稳稳地抓起来?”这个问题看着简单,实际上牵扯到两个坐标系之间怎么建立关系——图像里的像素坐标,和机…

阅读更多 →
H无穷加权灵敏度控制:从权重设计到仿真落地全解析 2026/9/15 16:28:34

H无穷加权灵敏度控制:从权重设计到仿真落地全解析

H无穷控制在现代鲁棒控制里是个绕不开的坎,而加权灵敏度问题又是入门H无穷最容易卡壳的地方。我当初学到这里时,拿着各种教材翻了半天,公式推导都能看懂,但一落到实际设计,权重函数不知道从哪下手、广义对象怎么拼装、…

阅读更多 →
Flink CDC实时同步Oracle全攻略:环境搭建与排障实战 2026/9/15 16:28:34

Flink CDC实时同步Oracle全攻略:环境搭建与排障实战

做数据实时同步这行当,Oracle绝对算得上最让人头疼的源端之一。商业数据库的封闭性、日志机制的复杂性、还有各种版本差异,让很多做实时数仓的团队在Oracle面前栽过跟头。我最近刚把一个核心订单库从离线T1切成实时同步,用的就是Flink CDC 实…

阅读更多 →
护网蓝队日志分析实战:从ELK搭建到攻击链研判 2026/9/15 16:28:34

护网蓝队日志分析实战:从ELK搭建到攻击链研判

第一次参加护网蓝队值班,看着大屏上每秒都在滚动的告警,脑子里其实一片空白。这是很多人都经历过的一幕:日志分析这四个字听起来简单,真正坐到工位上才发现,面对几百个日志源、几千万条记录,根本不知道第一…

阅读更多 →
STM32G070驱动CS5530高精度ADC:SPI时序、校准与噪声验证 2026/9/15 16:25:33

STM32G070驱动CS5530高精度ADC:SPI时序、校准与噪声验证

简介:STM32G070与CS5530联合开发资料包,面向嵌入式开发者、电子爱好者及需要实现高精度数据采集的工程师。该资源整合了电路原理图与配套C语言驱动代码,覆盖MCU初始化、SPI/I2C通信、数据处理等关键环节,可帮助读者快速理解两款芯…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞