结论: 服务器中病毒(主机层恶意程序)的处理顺序是"隔离 → 保全 → 清除 → 重装加固":先断网隔离防止横向扩散,再打包保留现场,随后按进程、持久化、动态库劫持三条线排查清除,最后重装系统并只恢复数据不恢复配置。勒索软件一律不建议支付赎金,靠离线备份恢复。
"CPU 长期 100% 但 top 里找不到占资源的进程""云厂商发来违规外联告警""文件莫名其妙被加密、后缀变成奇怪的字符串"——这些都是主机层恶意程序的典型信号。它和网站被挂马不是一回事:挂马寄生在 Web 目录里靠 HTTP 触发,而病毒是常驻系统的独立进程,往往已经拿到了 root 权限。
本文只讲主机层恶意程序的处置。命令以 Ubuntu 24.04 LTS 与 Rocky Linux 9 为例(截至 2026 年)。若你的症状是"网站目录多了陌生 .php 文件",请看本站《服务器被挂马怎么办》。
一、先定性:四类主机层恶意程序与识别特征
结论:先判断是哪一类,再决定处置力度。 挖矿木马可以边查边清,rootkit 必须重装,蠕虫要立即隔离防扩散,勒索软件要先止损再谈恢复。判断错了会浪费大量时间。
| 类型 | 典型行为 | CPU / 流量特征 | 常见驻留位置 | 处置力度 |
|---|---|---|---|---|
| 挖矿木马(Miner) | 连接矿池提交算力,常带守护进程与互锁机制 | CPU 长期 90%~100%(多线程占满所有核心),对外连接 3333/8333/8080 等端口 | /tmp、/dev/shm、/root/.systemd-*、/usr/lib/systemd/system/、crontab | 可清除,但必须同时清守护与持久化 |
| rootkit | 替换系统命令(ps/top/ls/netstat)、隐藏进程与文件、hook 内核 | CPU 未必高,但命令输出"自相矛盾"、文件被 chattr +i 锁定 | 内核模块 /lib/modules/、LD_PRELOAD、/etc/ld.so.preload | 必须重装,本机已不可信 |
| 蠕虫(Worm) | 扫描内网与公网其他主机,暴力破解 SSH、利用漏洞横向传播 | outbound 流量异常、SSH 失败日志暴涨、/var/log/secure 大量 Failed password | /tmp、系统 bin 目录、crontab、SSH authorized_keys | 立即隔离,防止扩散到内网 |
| 勒索软件(Ransomware) | 遍历文件用公钥加密,留勒索信(README/HOW_TO_DECRYPT),删除快照与备份 | 加密阶段磁盘 IO 与 CPU 双高,事后 CPU 回落 | 进程本体在 /tmp 或用户目录,密文带统一后缀(如 .locked、.enc) | 断网取证,不建议付赎金,靠离线备份恢复 |
一个实用的快速判断法:
- CPU 高 + 有异常外连 + 进程可见 → 大概率挖矿木马。
- CPU 高但找不到进程 / 命令输出矛盾 → 高度怀疑 rootkit 或进程隐藏。
- SSH 登录失败日志暴涨 + 内网其他机器也中招 → 蠕虫。
- 文件内容变乱码、后缀统一改变、出现勒索信 → 勒索软件,立刻断网。
二、CPU 异常却找不到进程怎么办?
结论:top 里看不到高 CPU 进程,只有三种可能——进程被隐藏、进程被改名成系统名、或者你看的是被 hook 过的 ps/top。 绕过被污染的命令,直接读 /proc 是最可靠的办法。
# 1. 绕过被替换的 ps/top,直接从 /proc 读所有进程的 CPU 占用
for p in /proc/[0-9]*; do
pid=${p#/proc/}
[ -r "$p/stat" ] || continue
# utime(14) + stime(15) 之和粗略代表 CPU 时间
awk '{print $1, $2, $14+$15}' "$p/stat" 2>/dev/null
done | sort -k3 -rn | head -20
# 2. 用 ps auxf 看进程树(父子关系常能暴露守护进程)
ps auxf | head -60
# 3. 核对进程名与真实可执行文件的对应关系(改名木马必现形)
PID=1234
ls -l /proc/$PID/exe # 真实二进制路径,被改名也能看出真身
cat /proc/$PID/cmdline | tr '\0' ' '; echo
cat /proc/$PID/cwd # 工作目录,常在 /tmp 或 /dev/shm
ls -l /proc/$PID/fd 2>/dev/null | head
# 4. 对比 ps 与 /proc 的进程数,差额即隐藏进程数
ls -d /proc/[0-9]* | wc -l
ps -e --no-headers | wc -l关键点解释:
/proc/PID/exe是内核维护的符号链接,指向该进程实际运行的二进制文件。木马把文件名改成kworker/2:1或systemd-daemon也没用,ls -l /proc/PID/exe会显示真实路径(常见为/tmp/.X11-unix/...、/dev/shm/...),删掉二进制时还能看到(deleted)标记。- 若
ps auxf与/proc列表数量不一致,说明ps已被替换或内核态做了过滤,此时本机所有命令都不可信,应立刻进入重装流程。 - 辅助工具:
apt install unhide rkhunter chkrootkit,用unhide proc和rkhunter --check做交叉验证;但它们依赖本机二进制,rootkit 场景下结论只能作为参考。
处置挖矿进程的注意点:直接 kill -9 后十有八九会复活,因为守护进程或 crontab 会把它拉起来。正确顺序是先杀守护、再清持久化、最后杀本体,或者反过来——先清持久化再杀进程,两者任选其一但必须成套执行。
三、持久化排查:定时任务、开机项与动态库劫持
结论:清除病毒的关键不在杀进程,而在清持久化。 挖矿木马几乎都配了"守护 + 定时拉取 + 开机启动"三重保险,少清一项就会复活。而其中最容易漏掉的是 /etc/ld.so.preload 动态库劫持——它能让恶意代码注入到系统几乎所有命令里,包括你用来查杀的工具。
# 1. 定时任务(重点看 root 与 Web 用户,以及 /etc/cron.d 下的陌生文件)
crontab -l -u root
crontab -l -u www-data 2>/dev/null
ls -la /etc/cron.d/ /etc/cron.hourly/ /etc/cron.daily/ /var/spool/cron/crontabs/
grep -rE "curl|wget|bash -i|/dev/shm|/tmp/" /etc/cron.d/ /var/spool/cron/ 2>/dev/null
# 2. systemd 服务与开机项
systemctl list-unit-files --state=enabled | grep -viE "systemd|dbus|ssh|cron|nginx|php|ufw|getty|cloud|snap|containerd|docker|auditd|rsyslog"
ls -la /etc/systemd/system/ /lib/systemd/system/ | grep -viE "multi-user|default|@\."
systemctl cat suspicious.service # 看 ExecStart 指向哪里
# 3. 传统开机项与 shell 启动脚本
cat /etc/rc.local 2>/dev/null
grep -rE "curl|wget|/dev/shm|/tmp/" /etc/profile /etc/profile.d/ /root/.bashrc /root/.profile /etc/bash.bashrc 2>/dev/null
# 4. SSH 公钥与账号(蠕虫常写公钥留后门)
cat /root/.ssh/authorized_keys /home/*/.ssh/authorized_keys 2>/dev/null
awk -F: '$3==0 {print $1}' /etc/passwd # 检查是否多出 UID 0 的账号
last -20 # 最近登录记录
# 5. 【最容易漏】动态库劫持:LD_PRELOAD 与 /etc/ld.so.preload
echo "--- /etc/ld.so.preload ---"; cat /etc/ld.so.preload 2>/dev/null
echo "--- 环境变量 ---"; env | grep -i preload
grep -ri "LD_PRELOAD" /etc/environment /etc/profile /etc/profile.d/ /root/.bashrc 2>/dev/null/etc/ld.so.preload 劫持的识别与清除(重点)
结论:/etc/ld.so.preload 里只要列出一个 .so 文件,系统上几乎所有动态链接的程序在启动时都会先加载它。 木马正是利用这一点实现"进程隐藏、命令过滤、杀不掉",它比 crontab 隐蔽得多,也是人工排查中漏检率最高的一项。
正常状态下这个文件应当不存在或为空。清除步骤:
# 1. 先看内容(正常为空或不存在)
cat /etc/ld.so.preload
# 2. 木马常给这个文件加 immutable 属性,需先解除(busybox 的 chattr 更可信)
lsattr /etc/ld.so.preload
chattr -i /etc/ld.so.preload
chattr -a /etc/ld.so.preload
# 3. 备份后清空(不要直接删,先改名,避免部分程序瞬间崩溃)
cp /etc/ld.so.preload /root/incident/ld.so.preload.bak
: > /etc/ld.so.preload
# 或直接移除
rm -f /etc/ld.so.preload
# 4. 定位并隔离恶意 so 文件
lsof +D /usr/lib 2>/dev/null | grep -i "\.so" | head -20
find /usr/lib /usr/local/lib /lib -name "*.so*" -newermt "2026-01-01" -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -20
# 5. 用静态编译工具验证(不依赖动态库,最可信)
apt install -y busybox-static
busybox ps aux
busybox ls -l /proc/1234/exe三条实战提醒:
- 清空
ld.so.preload前先确认该文件里的 so 不是业务依赖(正常环境基本不会有内容,个别监控 agent 会写入,需核对)。 - 清除后立刻用
busybox ps重新看进程——此前"消失"的挖矿进程往往会瞬间现身,这就是它一直藏着的证据。 - 若
chattr、lsattr本身也没反应,说明常用命令已被替换,此时不要再在这台机器上挣扎,直接进入重装流程。
四、挖矿与勒索软件的专项处置
挖矿木马:断矿池连接、清守护、堵入口
# 1. 找出与矿池通信的连接(Stratum 协议常见端口 3333/4444/8333/8888/18080,也有走 80/443 伪装的)
ss -antp | grep -E ":3333|:4444|:8333|:8888|:18080|:25$|stratum"
# 2. 按外连 IP 聚合,找出异常目标(境外 IP、非业务端口)
ss -antp | awk 'NR>1 { p=$5; sub(/:[0-9]+$/,"",p); print p, $6 }' \
| sort | uniq -c | sort -rn | head -20
# 3. 临时封禁矿池域名与 IP(止血,防止继续消耗 CPU 与带宽)
iptables -I OUTPUT -p tcp --dport 3333 -j DROP
iptables -I OUTPUT -d 203.0.113.50 -j DROP
# 或用 /etc/hosts 把矿池域名指向 127.0.0.1
# 4. 清理顺序(必须成套执行)
# ① 先停定时任务内容(crontab -e 删除可疑行 / 移除 /etc/cron.d 下陌生文件)
# ② 停守护服务:systemctl stop suspicious.service && systemctl disable suspicious.service
# ③ 杀本体:kill -9
# ④ 删除二进制:ls -l /proc/PID/exe 定位路径后 rm -f
# ⑤ 检查是否还有残留:ls -l /proc/*/exe 2>/dev/null | grep -E "/tmp|/dev/shm"
# 5. 堵入口:改 SSH 密码与密钥、修漏洞组件、限制安全组
grep -c "Failed password" /var/log/auth.log 挖矿木马的入口其实就那几类:弱口令 SSH、Redis/MySQL/Elasticsearch 未授权访问、Web 中间件与 CMS 漏洞、Docker Remote API 未鉴权(2375 端口)。用 lastb 与 auth.log 反查首次成功登录的时间与来源 IP,基本就能确定入口。
勒索软件:断网、取证、不付赎金、离线恢复
结论:勒索软件的正确应对是"立即断网 + 保留现场 + 用离线备份恢复",支付赎金既不保证解密,还会把自己列入再次勒索名单。
处置要点:
- 立即断网但不要关机:关机可能丢失内存中的密钥线索;断网是为了阻止加密继续扩散到共享存储与其他机器。
- 保留勒索信与样本:勒索信里的 ID、邮箱、比特币地址是后续溯源与报案的关键信息;不要删除加密文件。
- 隔离共享存储:检查挂载的 NFS/SMB、对象存储、备份目录是否也被加密,先把它们卸载。
- 用离线备份恢复:前提是备份与生产隔离(离线、异地、不可被生产机写入)。很多团队"有备份"却被一起加密,原因就是备份目录在生产机上可写可见。
- 更换全部凭证:恢复后全量轮换 SSH 密钥、数据库口令、面板账号,因为攻击者很可能已拿到凭证。
# 检查是否还有文件正在被加密(CPU/IO 高 + 文件持续变动)
iostat -x 1 5
find /data -type f -newermt "-10 minutes" -printf '%TH:%TM %p\n' | head -20
# 统计被加密文件的后缀分布,确认影响范围
find /data -type f | sed -n 's/.*\.\([a-z0-9]\{2,8\}\)$/\1/p' | sort | uniq -c | sort -rn | head -10
# 查看共享存储挂载情况,优先卸载防止扩散
mount | grep -E "nfs|cifs|smb"五、处置顺序:隔离 → 保全 → 重装 → 加固
结论:对 rootkit 和已提权到 root 的失陷,唯一可靠的收尾是重装系统,并且只恢复数据、不恢复配置。 试图在已被污染的机器上"清理干净",往往留下看不见的后门。
- 隔离:在云控制台用安全组把该实例的所有入/出方向临时拒绝(注意保留你的运维通道),或直接解绑公网 IP,阻断横向扩散与外联。
- 保全:打包
/var/log、/etc、crontab、systemd 单元、/etc/ld.so.preload、可疑二进制样本到隔离目录;云上先打快照再操作,快照本身就是证据。 - 重装:使用官方公共镜像重建实例,不要使用"被攻陷时的自定义镜像"。
- 加固:只恢复业务数据与代码(代码必须经
git diff或官方包比对确认干净),配置重新写;全量轮换密钥与口令;补齐入口漏洞。
# 保全现场(在隔离目录集中归档,方便后续复盘与报案)
INC=/root/incident-$(date +%F-%H%M)
mkdir -p $INC
cp -a /var/log $INC/log
cp -a /etc $INC/etc
crontab -l -u root > $INC/crontab-root.txt 2>/dev/null
systemctl list-unit-files --state=enabled > $INC/systemd-enabled.txt
ps auxf > $INC/ps.txt
ss -antp > $INC/ss.txt
ls -l /proc/*/exe 2>/dev/null > $INC/proc-exe.txt
cp /etc/ld.so.preload $INC/ld.so.preload 2>/dev/null
tar czf /root/incident-$(date +%F).tar.gz $INC重装后的加固清单:禁 root 密码登录改用密钥、SSH 改非 22 端口或仅允许堡垒机 IP、安全组默认拒绝只放必要端口、开启自动安全更新、安装 fail2ban、所有服务不以 root 运行、日志与备份分离且备份不可被生产机删除(对象存储用"只追加"权限 + 版本控制)。
常见误区 / 排错提示
- 误区一:CPU 高了就重启。 重启会让挖矿木马的守护进程随开机项再次启动,同时丢掉
/proc里的现场证据。正确做法是先查持久化再杀进程。 - 误区二:只
kill -9不清理持久化。 这是挖矿木马"杀不死"的唯一原因。crontab、systemd、/etc/rc.local、~/.bashrc四处都要查,缺一处就会在几分钟内复活。 - 误区三:忽略
/etc/ld.so.preload。 这是本文最想强调的一条:它被写入后,ps、top、netstat的输出都会被过滤,你会以为"没有异常进程",从而误判为干净。每次排查都要先cat /etc/ld.so.preload。 - 误区四:用被感染机器上的命令做结论。 rootkit 场景下本机
ps、ls、netstat都可能是替换过的版本,结论不可信。应使用busybox-static这类静态工具交叉验证,或直接重装。 - 误区五:支付赎金换解密。 实际案例中付钱后拿到可用解密器的比例并不高,且会被标记为"愿意付款"的目标而遭到二次勒索。正确路径是离线备份恢复 + 报案。
- 排错提示:
chattr -i提示 Operation not permitted —— 可能是文件属性被锁或命令被替换,尝试busybox chattr;若仍失败说明内核层已被控制,直接重装。 - 排错提示:
ls -l /proc/PID/exe显示(deleted)—— 进程本体二进制已被删除但仍在运行,先用cp /proc/PID/exe /root/incident/sample保存样本再kill -9,否则样本丢失无法溯源。 - 排错提示:清完后 CPU 正常但云厂商仍报违规外联 —— 检查是否还有其他机器被同一蠕虫横向感染,用内网扫描排查同网段主机的 22/6379/2375 端口暴露情况。
常见问题(FAQ)
服务器中病毒和服务器被挂马有什么区别?
结论:中病毒是主机层,被挂马是 Web 层。 病毒指挖矿木马、rootkit、蠕虫、勒索软件这类常驻系统的独立进程,落在 /tmp、系统目录、crontab、systemd,表现为 CPU 异常、进程隐藏、文件被加密;挂马是后门脚本被放进网站目录,靠 HTTP 请求触发,表现为陌生 .php 文件与诡异访问日志。前者用 ps、/proc、rkhunter 排查并通常需要重装,后者用 find、grep、diff 排查并侧重堵上传与解析入口。
CPU 占用 100% 但 top 里看不到进程是怎么回事?
结论:通常是进程被隐藏或被改名,最可能是 rootkit 或 /etc/ld.so.preload 动态库劫持。 排查方法是绕过 ps/top 直接读 /proc:遍历 /proc/[0-9]/stat 统计 CPU 时间,用 ls -l /proc/PID/exe 看真实二进制路径,并对比 ls -d /proc/[0-9] | wc -l 与 ps -e | wc -l 的数量差。同时务必 cat /etc/ld.so.preload,若非空则先清空再用 busybox ps 复查,隐藏的进程通常会立刻现身。
挖矿木马杀掉进程后马上又起来怎么办?
结论:说明持久化没清干净,必须先清守护与定时任务再杀进程。 按顺序检查四处:crontab -l -u root 与 /etc/cron.d/ 下的陌生文件、systemctl list-unit-files --state=enabled 里的可疑服务、/etc/rc.local 与 /root/.bashrc、/etc/ld.so.preload 与 LD_PRELOAD 环境变量。清完这些再 kill -9,并用 ss -antp | grep -E ":3333|:8888" 确认矿池连接已断开,最后删除 /proc/PID/exe 指向的二进制本体。
服务器中了勒索软件要不要付赎金?
结论:不建议支付赎金,应优先用离线备份恢复。 付赎金既不能保证拿到可用解密器,还会被标记为"愿意付款"的目标导致二次勒索,部分团伙收款后直接失联。正确处置是:立即断网但不关机、保留勒索信与加密样本作为报案材料、卸载共享存储防止扩散、用与生产隔离的离线备份恢复数据,恢复后全量轮换 SSH 密钥与口令。
服务器中病毒后一定要重装系统吗?
结论:rootkit、已提权到 root 或系统命令被替换时必须重装;普通挖矿木马清干净持久化后可不清。 判断依据三条:/etc/ld.so.preload 是否被写入、ps 与 /proc 进程数是否不一致、系统命令行为是否异常,任一命中即视为本机不可信。重装用官方镜像,只恢复数据与确认干净的代码,不恢复 /etc 配置,并全量轮换密钥。
怎么防止服务器再次中病毒?
结论:堵住入口比事后查杀更有效,入口主要是弱口令与未授权服务。 必做六项:SSH 禁密码登录改密钥并限制来源 IP、Redis/MySQL/Elasticsearch 不监听公网且设置强口令、Docker Remote API(2375)禁止对公网开放、系统与中间件保持安全更新、安全组默认拒绝只放必要端口、备份与生产隔离且开启版本控制。再加一条监控:CPU 持续超过 80% 与异常外联自动告警,能把发现时间从"几天"压到"几分钟"。
企业QQ咨询




