凌晨两点,某公司运维老张在监控群里甩了一张截图:一台业务服务器每个小时向外发起一次可疑TCP连接,CPU占用率飙到300%。组里刚转岗的小年轻第一反应是直接kill进程、重启服务器。我赶紧拦住他:先别动。服务器被入侵后的第一原则是保存现场、就地取证——这也是“应急响应”这门手艺真正值钱的地方。
这篇文章想用最白话的方式,把“服务器入侵排查”这件事讲清楚。不管你是运维、测试、刚入门的安全助理,还是单纯好奇的后端开发,都可以把这篇当作一张排查地图。我不会只丢命令,每条命令背后的判断逻辑也会一起拆开。你不一定能一夜精通,但下次报警弹出来时,至少知道自己该按什么顺序动手,哪些坑绝对不能踩。
1. 先说清楚:服务器入侵排查到底在查什么
1.1 应急响应不是杀毒,是“考古”
很多零基础的朋友对应急响应的想象还停留在“把病毒杀掉”。实际上,应急响应的核心不是消灭,而是还原。你面对的不只是一个木马文件,而是一个已经发生过的攻击事件。你要回答的也不是“病毒还在不在”,而是“病毒怎么进来、什么时候进来、已经造成了多大影响”。
服务器是这类事件最常出现的地方。线上服务器全年无休、对外暴露面大、承载业务数据,攻击者只要拿下一台,就可能横向移动、部署后门、窃取数据或挖矿。这也是为什么“服务器入侵排查”会成为应急响应里最基础也最重要的场景。对刚入行的人来说,练好服务器排查,基本就摸到了应急响应的门槛。
1.2 一套排查,本质上回答三个问题
不管日志堆了多大一坨,排查最终都归结为三个问题:
- 攻击者是什么时间进来的?——这是时间线
- 从哪个点进来的?——这是攻击入口
- 进来后做了什么、留下了什么?——这是痕迹与影响
三个问题一个都不能少。时间线帮你锁定日志范围,入口帮你定位修复点,痕迹帮你判断数据泄露面。后面所有的命令、工具、分析动作,本质上都是围绕这三个问题展开的。理解这一点,你在现场就不会慌:即使某个命令不熟,你也知道下一步该往哪个方向走。
2. 排查前的基本功:建立正确的时间线与现场保护
2.1 拿到告警先做这四件事
我最想强调的事情恰恰不是“查得快”,而是“不要动得太快”。初学者最容易犯的错误也在这里。
第一,不要急着重启服务器。攻击者植入的进程一旦被重启,内存里的证据就全部消失,而且很多持久化脚本会在开机后重新落盘,你等于刚杀完又亲手把它复活了。除非业务已经完全不可用,否则先别碰重启键。
第二,保存现场快照。有条件的话优先做内存镜像和磁盘快照。对零基础来说,最实用的做法是先把正在运行的进程列表、网络连接、所有登录会话用命令导出来存到本地。这个动作花不了几分钟,却能保住最关键的“活证据”。
第三,隔离不等于断网。可以在防火墙层限制可疑外联,只封掉攻击者相关的IP和端口,业务网段照常互通。这么做的目的是防止攻击者发现暴露后销毁痕迹,同时也给你保留继续观察、反向追踪的空间。如果内网已经出现横向扩散迹象,再考虑把该主机对外的出口彻底封掉。
第四,记录初始状态。比如你的第一反应是“这个进程看起来可疑”,那就把它当时的状态、路径、PID、CPU和内存占用全部记下来。后续分析中,你记忆里那个“好像不太对”的点,往往就是最关键的突破口。
注意:现场处置的第一原则是“少动手、多记录”。每一条输入的命令都有可能改变系统状态,所以在明确判断之前,先记录,再操作。顺序反了,证据就没了。
2.2 时间线还原:让案发过程自己“说话”
时间线是整个排查的中轴。你要把系统日志、应用日志、文件修改时间、进程启动时间放在同一个时间轴上看。
举例来说,某个WebShell文件的时间戳是昨天14:02,而应用访问日志里同一分钟正好有一条来自陌生IP的POST请求,那基本就能确定案发时间窗口。再顺着这个点去看,这个时间前后还有哪些账号登录、哪些文件被修改,完整入侵路径就串起来了。
零基础阶段,我建议用一个最简单的表格整理时间线:时间、事件、来源、证据来源。看起来简陋,但它能让你在分析中保持清醒。复杂的工具可以以后再学,用表格把时间线拉直,比把信息都记在脑子里稳得多。
3. 新手可以照着抄:服务器入侵排查的完整流程
3.1 第一步:收集系统基本事实
先拿一组命令快速摸清你面对的系统。这一步不复杂,但很多人容易跳过,觉得浪费时间。实际上,你连系统版本都不知道,后续怎么判断攻击者可能利用了哪些漏洞?很多老漏洞的利用条件都跟内核版本、软件版本强相关。
uname -a # 内核版本与架构 cat /etc/redhat-release # 发行版版本(CentOS等) lsb_release -a # 通用发行版信息 uptime # 运行时长与负载 date # 确认当前时间,后续对时间线要用 last | head -50 # 最近登录记录 cat /etc/passwd # 系统用户列表看到一台被入侵的服务器,先别急着深挖。把系统底数摸清,才能把后续发现的所有异常放到正确的上下文里判断。比如一台CentOS 6老机器和一台刚装好的Debian 12,同样的异常现象,指向的排查方向很可能完全不同。
3.2 第二步:账号层排查
攻击者进入系统后做的第一件事,往往是给自己留一个账号,这样即使你改了他的临时入口,他还是能通过账号直接登录。账号排查的重点有四个:
# 查看所有UID为0的用户(UID 0代表root权限) awk -F: '$3==0 {print $1}' /etc/passwd # 查看可登录用户(最后一个字段不是nologin/false的用户) cat /etc/passwd | grep -v nologin # 查看sudo权限组成员 getent group sudo # 查看近期登录与失败登录 last lastb判断标准很简单:查新增账号,比对创建时间。如果某个账号出现在入侵时间点前后,且它的shell不是nologin,那基本可以确定是后门账号。
这里有个容易忽略的隐蔽手法:攻击者会给用户名加上不可见字符,或者在用户名后面加空格,肉眼扫过去很难发现问题。所以不要只看用户名好不好看,直接用条件过滤“可登录用户”和“UID为0用户”,比肉眼靠谱得多。
3.3 第三步:进程与网络排查
进程是攻击者在服务器里的“落脚点”。挖矿程序、远控木马、反向连接Shell,最终都会以进程形式出现,并产生网络连接。排查命令如下:
top # 看CPU和内存占用排行 ps aux --sort=-cpu # 按CPU占用排序进程 ps -ef # 看完整进程树和执行路径 netstat -antlp # 看所有TCP连接对应的PID ss -antlp # netstat的现代替代品 lsof -p PID # 查看某个进程打开的连接和文件排查重点有三个:
第一,进程名和实际执行路径是否匹配。很多攻击者会把木马改成看起来像系统服务的名字,比如伪装成/usr/lib/systemd-networkd或者合法的php-cgi,但你要是仔细看它的完整路径,会发现它在/tmp或/var/tmp下,这就非常可疑。正常系统服务不会从临时目录运行。
第二,父进程是否正常。正常业务进程的父进程一般是systemd或某个应用父进程。如果一个bash进程的父进程是nginx,或者一个可疑进程的父进程是空的,都是危险信号。
第三,外联IP是否正常。注意看主动连接到外部IP的进程,尤其是目的端口不是常见的80、443,而是高位随机端口,高度可疑。挖矿程序通常连的都是矿池地址,远控木马连的是攻击者的C2服务器,这些连接在ss -antlp里藏不住。
3.4 第四步:文件与后门排查
攻击者想要让权限一直可控,一定会留下文件。重点看以下几个方向:
# 最近几天被修改过的敏感目录文件 find /etc /tmp /usr/lib /root -mtime -3 -type f # 查看计划任务 crontab -l ls -la /etc/cron.d/ /etc/cron.daily/ /var/spool/cron/ # 查看开机自启动项 cat /etc/rc.local ls -la /etc/systemd/system/*.service # 查看SSH免密登录里是否混入了陌生公钥 cat ~/.ssh/authorized_keys # 针对Web业务,查找近期新建的可疑PHP/JSP文件 find /var/www -name "*.php" -mtime -3这里有一个必须强调的坑:攻击者可以修改文件的mtime来迷惑你。文件的时间戳只能作为引导,最终还是要回到日志里去交叉验证。如果发现某个可执行文件在业务完全没有变更的时间段内被修改,哪怕文件名再正常,也要列入重点怀疑对象。
很多后门就藏在看似无害的配置文件里。比如有的木马会往/etc/profile里追加一段启动代码,每次用户登录时都会执行;有的会修改/etc/ld.so.preload实现隐藏进程。这些位置不在常规目录里,但一旦被植入,清理难度极大。检查时要把这些文件也过一遍。
3.5 第五步:日志排查与还原
日志排查是整个流程中最花时间、也最有价值的一步。系统日志、应用日志和访问日志是你还原攻击路径的主要信息来源。
# 登录认证日志,看SSH登录与sudo记录 cat /var/log/secure | grep -i "accepted\|failed" | tail -200 # 查看登录会话记录 last -a /var/log/wtmp # 查看失败登录记录 lastb -a /var/log/btmp # Web访问日志,搜攻击特征 grep -E "eval|base64|\.\.\/" /var/log/nginx/access.log | tail -100排查技巧:先根据时间线锁一个时间窗口,然后grep这个窗口前后的所有异常条目,再把来源IP统一汇总。比如你判断入侵发生在昨晚20:00左右,那就在访问日志里搜这个时间段内的所有POST请求,尤其是以.php、.jsp、.aspx结尾的POST请求,往往就是攻击载荷入口。
日志被清掉的情况也不少见。如果secure、btmp这些文件缺失或者大小明显异常,这本身就是一条重要线索——说明攻击者有意掩盖痕迹,也说明这是一次有准备的控制行为。这个状态是要记录在报告里的。
4. 一个真实场景复盘:CPU飙高+外联告警
讲完流程,我用一个模拟案例把这些步骤串起来,你会更直观。
某公司一台部署了Nginx+PHP的Web业务服务器,某天下午监控系统报CPU占用率长期在280%-350%之间,同时有一条到境外IP的持续TCP连接。运维提出的要求是业务不能停,尽量在线排查。
我按上面的流程走了一遍:
第一步,收集系统基本事实。uptime显示服务器已运行231天,系统是老版本CentOS,内核版本较旧。这一步就大致判断:系统超过一年没有重启过,补丁更新大概率滞后,存在被利用的条件。
第二步,账号排查。/etc/passwd里没有发现新账号,但没有排除账号后门。排除法看下来还算干净。
第三步,进程与网络排查。执行top后看到一个进程占用CPU约260%,进程名是php-cgi。这个进程的完整路径显示在/tmp/.php-cgi。这里可疑点已经很重了:正常的PHP-CGI进程应该跑在/usr/sbin或/opt/php路径下,出现在/tmp里几乎可以断定是恶意程序。再执行ss -antlp,确认这个/tmp/.php-cgi进程在持续连接境外IP的高位端口。
第四步,文件与计划任务排查。ls /etc/cron.d/时多了一个文件名看起来很随机的配置,内容指向/tmp/.update.sh。脚本内容是从指定URL下载一个程序并执行。到这里,持久化机制已经找到:攻击者通过定时任务保证后门掉线后会自动重新拉取。
第五步,日志回溯。grepNginx访问日志后,发现前天晚上有一个IP对某个PHP上传接口反复请求,触发了一个特定参数。这个上传接口存在文件上传漏洞,攻击者先上传了一个WebShell到/tmp目录,再通过WebShell下载了远控程序。
整个攻击链就这样清晰了:上传接口漏洞 → WebShell落地 → 下载远控 → 写入cron持久化 → 伪装php-cgi进程挖矿并外联。
处置动作包括:删除可疑文件、清理定时任务、封禁来源IP、修补上传接口、强制重设密码、在边界防火墙封堵外联目标IP。
这个案例最典型的教训是:如果只是把所有可疑进程kill掉,不查入口和定时任务,三个小时后,后门会从cron里再次复活。这也是应急响应和普通杀毒之间的核心区别——杀毒是治标,应急响应是治本。
5. 入侵留下的典型后门,排查时重点看这几类
5.1 账号类后门
账号后门是攻击者留“大门钥匙”最直接的方式。常见形式有三种:一是新增一个完全陌生的用户;二是修改已有用户的UID为0,让普通用户获得root权限;三是创建隐藏账号,在用户名里加入不可见字符。
排查办法前面提过,核心就是两条命令:awk -F: '$3==0 {print $1}' /etc/passwd查UID,cat /etc/passwd | grep -v nologin查可登录用户。再用时间戳和备份文件对比,新增的基本就跑不掉。
5.2 计划任务与开机启动类后门
这是最普遍、也最“耐用”的持久化后门。攻击者在crontab、/etc/rc.local、systemd服务、甚至/etc/profile里写入一段下载脚本,让后门在特定时间或开机时自动运行。
排查这类后门,没有捷径,只能逐个位置检查。重点目录包括:/etc/cron.d/、/var/spool/cron/、/etc/rc.local、/etc/sysconfig/、/etc/profile.d/、/etc/systemd/system/。判断规则很简单:每一行都要能解释清楚是干什么的,解释不清的,先备份再停用,别贸然删除。
5.3 SSH密钥后门
这类后门最隐蔽。攻击者把公钥写入目标主机某个用户的authorized_keys文件后,就能用私钥直接登录,不需要密码。排查时要检查root和其他业务账号的~/.ssh/authorized_keys,以及/etc/ssh/sshd_config里是否配置了异常的AuthorizedKeysCommand、PermitRootLogin等项。
5.4 WebShell的排查思路
Web业务被攻破后,WebShell几乎必到。它可以是PHP、JSP、ASP,也可以是各种高度混淆的一句话变种。排查思路是“时间优先,特征跟进”。
先看目录修改时间。重点查Web根目录下近期被创建或修改过的脚本文件。然后做特征扫描,grepeval(、assert(、base64_decode(这类高危函数。最后看请求日志里是否有可疑参数名。
如果服务器上文件非常多,直接全盘grep效率很低。我建议优先扫描目录并排除框架自带文件,或者用文件系统层面的全盘扫描工具,让工具先筛一遍可疑文件,再人工复核。这里送给新手一句话:WebShell查不出来不丢人,丢人的是明明有时间戳异常,还漫无目的地全盘扫。
6. 日志与命令速查:三张表直接贴给团队看
6.1 系统日志位置速查
| 日志文件 | 记录内容 | 常用读取方式 |
|---|---|---|
| /var/log/secure | SSH登录、sudo等人机认证记录 | cat、grep |
| /var/log/messages | 系统内核与运行的通用日志 | cat、grep |
| /var/log/wtmp | 所有成功登录会话记录 | last -a |
| /var/log/btmp | 所有失败登录尝试 | lastb -a |
| /var/log/lastlog | 所有用户最近登录时间 | lastlog |
| /var/log/nginx/access.log | Web访问日志 | grep、tail |
| /var/log/nginx/error.log | Web异常请求与脚本报错 | grep、tail |
| /var/log/mysql/error.log | 数据库报错与慢查询线索 | grep、tail |
6.2 常用排查命令速查
| 排查维度 | 命令 | 判断要点 |
|---|---|---|
| 账号 | awk -F: '$3==0 {print $1}' /etc/passwd | 是否有异常UID为0的用户 |
| 计划任务 | crontab -l、cat /etc/cron.d/* | 是否有陌生脚本路径 |
| 进程 | ps aux --sort=-cpu | CPU高、路径位于/tmp |
| 网络 | ss -antlp | 活跃外联、异常高位端口 |
| 文件 | find /tmp /var/tmp -mtime -3 | 近期新增的可疑文件 |
| 登录历史 | last、lastb | 陌生IP的登录记录 |
| 历史命令 | cat ~/.bash_history、~/.mysql_history | 攻击者执行过哪些指令 |
6.3 异常判断速查表
| 异常现象 | 可能含义 | 下一步价值 |
|---|---|---|
| CPU持续高于200% | 挖矿木马或恶意爬虫 | 定位高占用进程路径 |
| 进程路径在/tmp、/var/tmp下 | 大概率是恶意程序 | 提取并分析该文件 |
| 外联IP端口非80/443 | 木马回连C2服务器 | 封禁并IOC入库 |
| /etc/shadow或passwd被修改 | 账号后门或提权行为 | 对比备份,处理异常账号 |
| authorized_keys出现陌生公钥 | SSH密钥后门 | 删除公钥并重置SSH配置 |
| Web日志出现大量POST到脚本 | WebShell上传或激活 | 拉取完整攻击payload |
7. 常见问题与踩坑实录
7.1 攻击者把日志清了怎么办
日志被清不等于没有证据。bash历史文件、进程残留、内存镜像都可能留有线索。而且“清理动作”本身也是一条重要信息——它说明攻击者具备一定的反取证意识,同时证明系统被深度控制,已经不能盲目信任。后续处理要按照“最坏情况”来做:全面重置账号密码、重新审计应用、找不到确切入口就全盘备份后重装。
7.2 服务器已经重启了还有救吗
有救,但难度会增大。重启之后,内存和进程层面的证据没了,分析重心要转移到磁盘持久化上:计划任务、开机启动项、SSH信任关系、账号变更,这些设计在重启后依然存在。靠这些也能定位多数后门,只是对WebShell和内存马这类无持久化攻击,难度会高很多,需要使用原始流量和日志来还原。
7.3 被入侵后直接重装系统行不行
重装系统是可选方案,但前提是搞清楚入侵入口,否则你重装完依然会在同一个口子被攻破。常见误区是重装前不做横向排查,攻击者通过同网段另一台机器又能进来。所以重装是手段而不是终点,入口不封堵,重装一百次也没意义。
7.4 事后加固,这五件事必须做
- 禁止root远程登录,改用普通账号加sudo
- SSH尽量改用密钥登录,并考虑更换默认端口
- 应用层重点加固上传接口,做好文件类型与内容校验
- 日志集中采集,送日志平台实时告警,避免被单独清理
- 漏洞管理形成闭环,关注组件安全公告并及时进行小版本更新
最后再说两句
这些年排查过不少服务器,我最大的体会是:真正拉开新手和老手差距的,不是工具用得多花哨,而是有没有形成一套稳定的排查节奏。上面这些命令和流程,你只要亲手在真实环境里跑过几次,就会形成肌肉记忆。到那时候,你不再是背命令,而是在跟攻击者隔空对话,从他留下的每个痕迹里判断他下一步可能去哪儿。
给你留一个顺手就能用的口诀:一看账号,二看进程,三看文件,四看日志。入口不修,后门不断。下次再有告警弹出来,别急着重启,先深呼吸,按这个顺序来。