起因

故事始于寻常的一天,某业务的 login 服务器上出现了一条异常命令执行告警:

cd /xxxx/tomcat/xxxx; whoami

从进程链信息来看,该命令由 java 进程触发,这通常是 JSP WebShell 被执行的典型特征。

排查过程

调查严格遵循着线索,但过程却充满了意外。

  1. 告警分析:定位 WebShell 访问

我的第一反应是立即分析产生告警的 login 服务器的访问日志和网络流量。很快,发现了一些指向 /login/ 目录下某个可疑 JSP 文件的访问请求,这证实了初步判断:确实有一个 WebShell 通过 login 服务的路径被触发了。后续日志情况表明,攻击者又通过这个 JSP 入口注入了内存马,极力想伪装成正常的请求。

  1. 溯源入口:发现上传漏洞

下一个关键问题是:这个 WebShell 是如何被上传到服务器上的?

为了找到最初的入口点,排查范围从单个 login 服务器扩大到该服务所使用的整个域名。通过对全量访问日志进行筛选和分析,注意到访问 WebShell 的 IP 在早些时候有访问同域名下的 /upload/ 路径。对这个 /upload/ 路径进行了重点排查,最终确认其后端服务存在一个严重的漏洞,和直接上传JSP文件差不多的那种(这里我就直接称之为 upload 服务)。

  1. 梳理架构:看似清晰的流量分发

为了验证我的发现,并理清 upload 和 login 两个服务之间的关系,我检查了入口网关的 Nginx 配置。配置清晰地印证了我的判断:

server {
    # ... 其他配置 ...
    location /upload/ {
        proxy_pass http://upload_service_cluster; # 流量转发至 upload 服务
    }
    location /login/ {
        proxy_pass http://login_service_cluster; # 流量转发至 login 服务
    }
}

至此,我有了一个看似完整的攻击路径:攻击者利用 upload 服务的漏洞上传文件,然后通过 login 服务的路径来执行它。 从架构上看,两个服务在应用层是隔离的。

  1. 清理现场与诡异的谜题

根据“漏洞在 upload 服务”这一发现,我登陆了对应的 upload 服务器。在 Web 目录下,我果然找到了攻击者上传的 WebShell 文件,并立即对其进行了清理。

然而,在我清理完现场,并回头整理所有信息时,一个无法解释的矛盾浮出水面:

主机 IP属性发现
XX.XX.XX.1upload发现了 WebShell 并已手动清理。但主机本身无任何命令执行告警。
XX.XX.XX.2login主机有明确的命令执行告警。但在我排查时,其 Web 目录下找不到任何 WebShell 文件。

这便是本次事件最核心的疑点: 告警发生在 login 服务器上,但 WebShell 实体却是在 upload 服务器上被发现和清理的。而当我去检查 login 服务器时,并未发现存在 WebShell 文件,让调查一度陷入了僵局,我认为可能出现了玄学问题

水落石出:NFS 的“功劳”

我重新审视了这个看似矛盾的现场,并在GPT的帮助下提出了一个关键假设:login 服务器上找不到 WebShell,会不会正是因为我已经在 upload 服务器上将它删除了?

这个想法让我将焦点从应用层转向了基础设施层。我深入检查了两台服务器的底层挂载配置,最终发现,upload 和 login 两组服务器虽然通过 Nginx 在应用层进行了职责分离,但它们的 Web 应用目录实际上是通过 NFS 挂载了同一个网络存储路径。

至此,整个攻击链条和我的困惑都有了完美的解释:

上传: 攻击者利用 upload 服务的漏洞,将 WebShell 文件写入了共享的 Web 目录。

同步: 由于 NFS 的存在,这个文件被实时同步到了所有挂载该目录的服务器上,自然也包括了 login 服务器。

执行: 攻击者随后访问 login 服务的 URL (/login/webshell.jsp) 来触发木马,命令因此在 login 服务器 (XX.XX.XX.2) 上被执行,从而产生了告警。

消失: 我在 upload 服务器上删除了 WebShell,这个删除操作通过 NFS 同步到了 login 服务器,导致我后续在 login 服务器上排查时找不到该文件。

残留: JSP WebShell 在首次执行时,会在服务器上编译生成 .java 和 .class 文件。这也解释了为何我在 login 服务器上发现了这些编译后的残留文件,为“命令曾在此处执行”提供了铁证。

谜底揭晓: 这并非什么“玄学事件”,而是一个典型的由共享存储引发的“攻击面扩大”问题。漏洞虽在一处,但其影响却因架构设计而扩散到了其他看似独立的系统之上。

攻击者利用一处漏洞上传了 WebShell,但其执行动作却“穿越”到了另一台服务器上。最终发现,是 NFS 共享挂载导致了这次看似诡异的“权限扩散”。

其他

本文内容部分通过艺术化加工,以及AI润色。涉及的真实架构信息已隐去。