CVE-2017-4971源码分析与漏洞复现
漏洞概述
CVE-2017-4971 是 Spring Web Flow 框架中的一个高危远程代码执行(RCE)漏洞,影响版本为 Spring Web Flow 2.4.0–2.4.4。攻击者通过构造包含恶意 SpEL(Spring Expression Language)表达式的 HTTP 请求参数,利用数据绑定过程中的表达式注入漏洞,触发任意命令执行。
技术细节分析
1. 漏洞成因
- SpEL 表达式注入:
Spring Web Flow 在处理视图状态(view-state
)的数据绑定时,未对用户输入的字段名(field
)进行安全过滤。攻击者可通过构造恶意字段名(如_(恶意表达式)
),将 SpEL 表达式注入到数据绑定流程中,触发远程代码执行。 - 默认配置缺陷:
若应用未显式配置binder
节点(即binderConfiguration
为空),框架会默认绑定所有请求参数,导致攻击者可控制field
参数。
2. 源码分析
关键代码 1:demo中booking-flow.xml配置问题
1 |
|
binder
节点为空触发漏洞
关键代码 2:数据绑定触发流程
1 |
|
漏洞触发路径:
- 当
binderConfiguration
为空时,框架调用addDefaultMappings
处理所有请求参数。 - 攻击者提交形如
_(T(java.lang.Runtime).exec("calc"))
的参数,触发addEmptyValueMapping
方法中的表达式解析。
关键代码 3:AbstractMvcView.java
的 addEmptyValueMapping
方法
1 |
|
问题点:
field
参数直接来自用户请求,未进行过滤,导致 SpEL 表达式注入。expressionParser
默认使用SpelExpressionParser
,允许执行任意表达式(如T(java.lang.Runtime).exec()
)。
3. 补丁分析
官方修复方案通过以下方式限制漏洞利用:
1. 替换表达式解析器:
将 SpelExpressionParser
替换为 BeanWrapperExpressionParser
,后者仅支持基础属性绑定,禁止执行复杂表达式。
2. 路径校验强化:
在 addEmptyValueMapping
方法中增加字段名合法性检查,阻止非法字符(如 T()
、.
)注入。
漏洞复现
环境搭建
1.使用 Vulhub 环境启动漏洞靶机:
1 |
|
2.访问访问 http://target:8080,确认服务正常运行
攻击步骤
1.登录网站(用户名和密码在网站给出,随便填一个)
2.随便订购一个,并在最后要点击confirm
的时候用bp抓包
3.构造payload
1 |
|
4.kali开启监听
5.发送恶意请求包
- 将
payload
添加到之前抓取的POST
请求包里
6.验证成功
修复方案
- 升级版本:
升级至 **Spring Web Flow 2.4.5+**,修复了表达式解析逻辑。 - 输入过滤:
在数据绑定配置中显式声明允许的字段名,拒绝未经验证的参数:1
2
3<binder>
<binding property="allowedField"/>
</binder> - 禁用默认绑定:
避免在view-state
中省略binder
配置,防止框架自动绑定所有请求参数。
总结
CVE-2017-4971 的根源在于 Spring Web Flow 对用户输入的过度信任与 SpEL 表达式解析的开放性设计。其修复方案通过限制表达式执行权限和强化输入校验,有效降低了攻击面。
参考链接
CVE-2017-4971源码分析与漏洞复现
https://spinage.top/2025/09/05/CVE-2017-4971源码分析与漏洞复现/