Featured image of post Linux 性能调试与应急排查:htop / sysdig / unhide 与挖矿病毒清理

Linux 性能调试与应急排查:htop / sysdig / unhide 与挖矿病毒清理

服务器出现 CPU 拉满、磁盘 IO 飙升、隐藏进程无法解释时,这一份应急排查清单会帮你从一团乱麻里抓到元凶

〇、2024 视角(写于 2024-06)

本篇首发于 2024-06,过去 2 年挖矿病毒、内核 Rootkit 形态发生了一些变化:

  • unhide 仍是 Linux 下找隐藏进程最轻量的工具,但部分 Rootkit 已经能 hook 掉 /proc 遍历,建议结合 sysdig / bpftrace 一起看。
  • sysdig 2023 起被 Sysdig 公司收为闭源商业版的一部分,但社区 fork draios/sysdig 仍可拉取旧版开源;2024 推荐用 bpftrace / opensnoop-bpftrace 替代做 syscall 级追踪。
  • 挖矿病毒命名:过去是 8 位随机名(f54e90d4),2024 已进化为伪装成系统服务名kthrotldsmigration/0),单看名字不再可靠,必须看 cmdline + 真实可执行路径
  • 应急 SOP 没变:先断网 → 看进程 → 看 cron → 杀进程 → 删 cron → 改密码 → 关密码登录 → 备份数据后重装。

下面进入正文。

一、为什么需要"应急排查"清单

线上服务器出现异常,最贵的成本不是 CPU 也不是磁盘,而是"不知道下一步该敲什么命令"。本文按"症状 → 第一条命令 → 深入分析 → 处置"的顺序,整理了 4 个最常见场景的应急清单:

  1. CPU 拉满但 top 看不出明显元凶(隐藏进程 / 多核分配)
  2. 磁盘 IO 飙高iostat / 临时压测复现)
  3. 登录用户可疑(踢人 / 改端口)
  4. 挖矿病毒unhide / sysdig 找进程 / 清理定时任务)

每个场景都给最小可运行命令,不讲空洞理论。

重要原则:发现入侵迹象后,先断网再排查,避免恶意进程远程"自删"破坏现场。

二、场景 1:CPU 拉满

2.1 一条命令把 CPU 吃满(用于复现 / 压测)

1
2
3
4
5
6
7
# 起 N 个 dd 占满所有核心(N = 物理 CPU 个数)
for i in $(seq 1 $(cat /proc/cpuinfo | grep "physical id" | wc -l)); do
  dd if=/dev/zero of=/dev/null &
done

# 收尾
pkill -9 dd

原理:dd if=/dev/zero of=/dev/null 不产生 IO,只用 CPU。N 个并行正好把 N 核打满。

2.2 内存打满(用于测试 OOM)

1
2
3
4
5
6
7
# 占 1G 内存 1 小时
mkdir /tmp/memory
mount -t tmpfs -o size=1024M tmpfs /tmp/memory
dd if=/dev/zero of=/tmp/memory/block
sleep 3600
umount /tmp/memory
rmdir /tmp/memory

2.3 磁盘 IO 打满(用于复现 IO 瓶颈)

1
2
3
while true; do
  dd if=/dev/urandom of=/burn bs=1M count=1024 iflag=fullblock
done

跑起来后用 iostat 观察:

1
iostat -d -x -k 1 1

关键列含义:

含义
r/s / w/s每秒读 / 写次数
rkB/s / wkB/s每秒读 / 写 KB
await平均每次 IO 等待时间(ms)
svctm平均每次 IO 服务时间(ms)
%util设备繁忙时间占比,接近 100% 就是瓶颈
avgqu-sz平均 IO 队列长度

2.4 CPU 满但 top 看不到凶手

很可能是进程被 Rootkit 隐藏了。ps 只能看到 /proc 里可见的进程,Rootkit 通过改系统调用 / 内核模块把进程从 /proc 抹掉。

1
2
3
4
5
6
# 安装
apt install unhide    # Debian / Ubuntu
yum install unhide    # CentOS

# 扫描隐藏进程
unhide proc

输出示例(节选):

1
2
3
4
5
6
7
8
Found HIDDEN PID: 8627
        Cmdline: "<none>"
        Executable: "<no link>"

Found HIDDEN PID: 8631
        Cmdline: "/tmp/ntools"
        Executable: "/tmp/ntools (deleted)"
        Command: "ntools"

"<no link>"(deleted) 几乎可以肯定是被替换的可执行文件。这种进程ps 看不到,但 unhide 跑遍 /proc 就能揪出来

2.5 sysdig:高级武器

1
2
3
4
5
# 装
apt install sysdig    # 或 yum install sysdig

# CPU Top
sysdig -c topprocs_cpu

输出形如:

1
2
3
4
CPU%                Process             PID
--------------------------------------------------------------------------------
1986.02%            Discord             3225098
1800.44%            f54e90d4            1806

1986.02% 出现在普通命令里几乎肯定是异常——单进程超过 100% 表示它多线程用了多核,但 Discord 一般不该这样。如果看到 f54e90d4 这种 8 位随机名字的可执行文件,就是挖矿木马

定位 PID 后用下面这套"五连":

1
2
3
4
5
cat /proc/1806/cmdline          # 命令行(已抹掉的看不到)
which f54e90d4                  # 找不到说明不在 PATH
find / -name f54e90d4 2>/dev/null
ls -l /proc/1806/exe            # 真实可执行路径
cat /proc/1806/status          # 进程状态、内存、权限

pwdx 1806 找进程工作目录:

1
2
root@host:~# pwdx 1806
1806: No such process    # 进程可能已经"自删"

No such process 是典型的"恶意进程"——它在被查询的瞬间就已经退出了,只留下 /proc 里的残骸。

三、场景 2:磁盘清理与排查

1
2
3
4
5
6
# 看各目录占用
du -h -x --max-depth=1 /

# ncdu 交互式
apt install ncdu
ncdu / --exclude /home --exclude /nfs

ncdu 快捷键:

作用
n按文件名排序
s按大小排序
r重新计算
g显示百分比
q退出

四、场景 3:SSH 登录用户异常

1
2
3
4
5
# 查看当前在线用户
who

# 踢掉某个用户
pkill -9 -t pts/2

注意 pkill -9 -t pts/2 会强杀该终端所有进程,包括用户正在跑的服务。生产环境慎用,最好先 wall 警告。

/var/log/auth.log 异常增长是被 SSH 暴力破解的信号:

1
2
3
4
5
6
7
8
# Ubuntu
tail -f /var/log/auth.log

# CentOS
tail -f /var/log/secure

# 文件超过 1M 多半是被打了
du -h /var/log/auth.log

应对:

  1. 改 SSH 端口
  2. 关闭密码登录,只允许密钥
  3. 装 fail2ban 自动封禁
  4. 内网机器直接禁外网 SSH

五、场景 4:挖矿病毒应急 SOP

本节基于实际处置过的案例整理,所有"客户信息"已脱敏。

5.1 症状

  • top 看到 f54e90d4ntoolskthrotlds 等奇怪名字
  • CPU 长期 100%,但业务进程正常
  • /etc/cron.d/ 下出现随机名字的文件

5.2 排查流程

1
2
3
4
5
6
7
8
# 1. 找隐藏进程
unhide proc

# 2. 看可疑 crontab
crontab -l
cd /etc/cron.d
ls -l
cat /etc/cron.d/<可疑文件>

示例输出:

1
2
3
root@host:/etc/cron.d# ls -l
-rw-r--r-- 1 root root 201 Jan  8  2022 e2scrub_all
-rw-r--r-- 1 root root  35 Dec 10  2011 F6tfV3LP

F6tfV3LP 这种随机 8 位字母几乎肯定是恶意 cron。e2scrub_all 是 ext 文件系统自带工具,不要删

1
2
3
4
# 看内容
cat F6tfV3LP
# */1 * * * * root /bin/WbeGGvQK 1 1
# 每分钟执行一次 /bin/WbeGGvQK(已删除的可执行)

5.3 清理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 1. 删二进制
rm -rf /bin/WbeGGvQK

# 2. 删 cron 文件
rm -rf /etc/cron.d/F6tfV3LP

# 3. 杀进程
pkill -9 -f WbeGGvQK
# 或按 PID
kill -9 <PID>

5.4 后续加固

  1. 改所有弱密码
  2. 关闭 SSH 密码登录
  3. 查 /etc/passwd 是否有可疑新用户
  4. 检查开机启动项:systemctl list-unit-files --state=enabled
  5. 重装系统(如果已经渗透很深)

经验上重装比清理快。挖矿病毒经常会留后门,清理成本远高于备份数据 → 重装 → 加固。

六、sysdig 进阶使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 查某个进程的系统调用
strace -p 1806

# 查网络连接最多的进程
sysdig -c topprocs_net

# 查写入文件最多的进程
sysdig -c topprocs_file

# 监听特定事件
sysdig evt.type=open and fd.name contains /tmp

更多 sysdig chisel(内置的分析命令):

Chisel用途
topprocs_cpuCPU 占用 Top
topprocs_net网络流量 Top
topprocs_file读写文件 Top
topfiles_bytes文件读写字节数 Top
spy_users用户行为跟踪
spy_ipIP 维度流量
list_login_shells登录历史

七、SSH 日志监控

1
2
3
4
5
# Ubuntu
tail -f /var/log/auth.log

# CentOS
tail -f /var/log/secure

日志格式:

1
Jun 13 02:54 internal.example.com sshd[12345]: Accepted publickey for root from <攻击者IP> port <端口> ssh2

日志暴增多半是 SSH 暴力破解,可以装 fail2ban 自动封禁。

八、常见 5 个坑

  1. unhide 报很多 Found HIDDEN先看 CmdlineExecutable 两列"<no link>" + (deleted) 才是真可疑;内核线程、kthreadd 的子进程是正常的。
  2. pkill -9 -t pts/2 把自己踢下线:远程终端执行前确认 pts 号是自己的(who 第一行)。
  3. crontab 里的"正常任务"删错e2fsprogse2scrub_all 看起来像可疑脚本,是合法的——别删。
  4. dd if=/dev/zero 把磁盘打满of=/dev/null 不会写盘;of=/burn(不存在)会真的写满磁盘,小心。
  5. 入侵后只杀进程不清理 cron:挖矿病毒的核心是 cron 里的回连脚本,不删 cron 杀 100 次也会复活。

九、应急排查清单(建议收藏)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
[ ] top / htop  CPU
[ ] ps aux --sort=-%cpu | head
[ ] unhide proc 找隐藏进程
[ ] sysdig -c topprocs_cpu
[ ] who / w 查在线用户
[ ] cat /etc/passwd 查可疑账户
[ ] ls -l /etc/cron.d/ + cat 每个文件
[ ] crontab -l 查用户级定时任务
[ ] systemctl list-unit-files --state=enabled
[ ] last / lastb 查登录历史
[ ] /var/log/auth.log 查异常登录
[ ] iostat -d -x -k 1  IO
[ ] netstat -antp 查可疑连接
[ ] 备份数据后重装(最后手段)

十、总结

  • CPU 满先 top 看不见再 unhide,别忘了 sysdig 是终极武器。
  • 挖矿病毒的根在 /etc/cron.d/ 随机名文件,不删 cron 杀 100 次也复活
  • 入侵后清理 = 找 → 杀 → 删 cron → 改密码 → 关密码登录 → 重装。
  • 预防 > 应急:SSH 密钥 + fail2ban + 最小开放端口。

参考资料

使用 Hugo 构建
主题 StackJimmy 设计