服务器被入侵后,最忌讳的就是慌张地重装系统。重装虽然能清除恶意程序,但也会彻底破坏犯罪现场,导致你永远不知道攻击者是通过哪个漏洞进来的。应急响应的核心目标是在隔离威胁的同时,尽可能保留日志和痕迹,以便溯源。当收到安全告警或发现CPU异常飙高、陌生进程、异常外联时,第一件事不是杀进程,而是通过管理口或带外网络登录服务器,执行命令前先保存当前的内存快照和关键状态。因为很多后门是驻留在内存的无文件木马,一旦重启服务器,这条线索就断了。

第一步:高危端口与异常连接的快速排查

攻击者一旦拿到权限,往往会建立持久化的外联通道。直接查看网络连接是定位后门最快的手段。使用 netstat 或 ss 命令能直观看到谁在连接你的服务器。

# 查看所有监听端口及对应的进程
ss -tulnp

# 重点过滤已建立的连接,特别是非业务端口
ss -antp | grep ESTAB

执行上述命令时,要特别留意那些监听在 0.0.0.0 上的高端口,以及进程名看起来像系统进程(如 [kworker] 伪装)但 PID 奇怪的条目。如果发现陌生的 IP 地址,尤其是归属于境外或云服务商的 IP,立即使用 grep 命令在 /var/log/secure 或 /var/log/auth.log 中回溯该 IP 的登录记录,判断是暴力破解成功还是漏洞利用。

第二步:揪出隐藏的恶意进程与反弹Shell

高级的 Rootkit 会替换系统命令,比如替换 ps、top、lsof 等,让管理员看不到恶意进程。因此,不能只依赖系统自带的工具。推荐使用 busybox 这类静态编译的工具集进行交叉验证,或者直接读取 /proc 虚拟文件系统。

# 遍历 /proc 目录,查看所有进程的启动命令和状态
for pid in /proc/[0-9]*; do
  echo "PID: $(basename $pid)"
  cat $pid/cmdline | tr '\0' ' '
  echo
done

反弹Shell是攻击者最常用的手段,通常表现为 bash 或 sh 进程带有 -i 参数,或者出现了 /dev/tcp 的特征。通过查看进程树,可以清晰看到谁是父进程。如果发现一个 Web 服务进程(如 www-data)下竟然 fork 出了一个 bash 子进程,那几乎可以断定是 Webshell 执行了系统命令。此时不要急着 kill,先用 lsof -p [PID] 查看该进程打开了哪些文件,这能直接定位到黑客上传的脚本文件路径。

第三步:文件层面的深度扫描与特征提取

后门文件通常会修改时间戳来伪装。不要使用 ls -l 查看时间,因为攻击者可以用 touch -t 伪造。最有效的办法是寻找近期被修改的文件,并结合 Web 日志中的 404 或 200 状态码异常进行比对。

# 查找过去7天内被修改过的 PHP, JSP, ASPX, Py 等脚本文件
find /var/www -type f -name "*.php" -mtime -7

# 查找包含常见后门函数的文件,如 eval, base64_decode, assert
grep -r --include="*.php" "eval(" /var/www/
grep -r --include="*.php" "base64_decode" /var/www/

但要注意,很多正常的开源程序也会使用这些函数,所以单纯的关键词匹配会产生误报。更精准的做法是计算文件的哈希值,并与原始安装包进行对比。此外,攻击者喜欢将后门藏在图片目录、缓存目录或者以点号开头的隐藏目录中(如 .cache 或 .config)。Webshell 往往具备文件管理、命令执行功能,代码极短,可能只有一句:

<?php @eval($_POST['cmd']);?>

除了 Webshell,还要排查系统级的定时任务。很多挖矿木马和 DDoS 木马会写入 crontab。不仅要查看 /var/spool/cron/ 下的用户级任务,更要检查 /etc/crontab 和 /etc/cron.d/ 目录,因为有些木马会在这里写入随机命名的脚本来周期性执行。

第四步:无文件后门的排查与内存马检测

近两年的入侵趋势中,无文件攻击占比越来越高。攻击者通过利用漏洞注入内存,不落盘,传统杀毒软件完全失效。在 Linux 系统中,memfd_create 系统调用常被用来创建匿名内存文件执行恶意代码。排查时,可以检查进程的 maps 文件,寻找带有 deleted 标记的已加载库,或者路径为 memfd: 的匿名文件。

# 查看进程加载的内存映射,寻找可疑的匿名映射
cat /proc/[PID]/maps | grep -E "memfd|deleted"

对于 Java 应用,比如 Tomcat、Spring Boot,必须排查内存马。Filter 型或 Servlet 型内存马会动态注册,不生成实体文件。可以使用 arthas 这类 Java 诊断工具,通过 sc 命令查看所有 Filter 和 Servlet 列表,寻找那些没有对应磁盘文件、类名随机或命名奇怪的组件。如果发现未知的 javax.servlet.Filter 实现,直接通过 jad 命令反编译查看源码,通常会看到冰蝎、哥斯拉等工具的硬编码密钥特征。

第五步:日志分析与攻击溯源

定位并清理后门只是止血,溯源才能防止再次被入侵。Web 日志是核心突破口。不要只看 access.log,更要关注 POST 请求。攻击者上传 Webshell 或利用漏洞时,POST 包体中会包含明显的攻击载荷。使用 awk 和 sed 提取 POST 请求的 URI 和状态码,如果某个 IP 频繁访问一个不存在的路径且返回 200,那极有可能是隐藏的后门。

# 提取 POST 请求记录,并统计访问频率
grep "POST" /var/log/nginx/access.log | awk '{print $1, $7, $9}' | sort | uniq -c | sort -nr

系统认证日志同样关键。使用 lastb 命令查看失败的登录尝试,使用 last 查看成功的登录记录。如果发现原本不应该登录的账户(如 bin、daemon)突然有了登录记录,说明攻击者可能修改了系统账户权限。另外,history 命令不可全信,攻击者通常会执行 unset HISTORY 或直接删除 .bash_history。可以尝试恢复被删除的日志片段,或者分析 /var/log/journal/ 下的系统日志持久化记录。

第六步:建立快速隔离与恢复机制

在确认后门特征后,应急响应的收尾工作是阻断和清理。使用 iptables 临时封禁攻击源 IP,但要注意,现代攻击者会使用代理池,封禁单个 IP 效果有限。更有效的是通过 /etc/hosts.deny 限制 SSH 访问,或者临时关闭外网访问,仅保留维护通道。清理文件时,不要直接 rm,而是使用 chattr -i 去除不可修改属性后,将文件移动到一个隔离目录压缩加密保存,作为后续法律取证或深度分析的样本。最后,在重启业务前,务必修改所有密钥和密码,包括数据库密码、SSH 密钥对,并检查 SSH 的 authorized_keys 文件是否被写入了陌生的公钥。

总结:构建免疫系统比急救更重要

一次完整的应急响应,最终交付物不仅是一台干净的服务器,更应该是一份详细的入侵路径报告。报告中要明确指出:攻击者是通过哪个漏洞进来的(如 Log4j、Shiro 反序列化、弱口令),提权的手段是什么(如 DirtyPipe、SUID 提权),以及后门的具体存放路径和通信协议。只有基于这些信息去修补漏洞、加强口令策略、部署应用防火墙(WAF)和主机入侵检测(HIDS),才能将这次被入侵的经验转化为防御能力。记住,在攻防对抗中,已知威胁的排查是基础,未知威胁的感知能力才是安全团队的核心竞争力。