1. 漏洞描述
- 漏洞编号: CVE-2017-4971
- 漏洞简述: 由于Spring的框架越来越多,而且后面引入了SpringEl作为默认的表达式解析方式,所以一旦引入了类似于OGNL的表达式,很可能会带来一些安全问题,本次漏洞就是由于Spring WebFlow的数据绑定问题带来的表达式注入,从而导致任意代码执行。
- 影响版本: Spring Web Flow 2.4.0 to 2.4.4
2. 漏洞简介
该漏洞在2017年5月31号被提交到https://pivotal.io/security/cve-2017-4971平台,官方并没有详细的信息,通过官方描述和补丁的对比,我们可以大致推断应该是Spring WebFlow在Model的数据绑定上面,由于没有明确指定相关model的具体属性导致从表单可以提交恶意的表达式从而被执行,导致任意代码执行的漏洞,这个漏洞利用除了版本的限制之外还有两个前置条件,这两个前置条件中有一个是默认配置,另外一个就是编码规范了,漏洞能不能利用成功主要就取决于后面的条件。
整体来说这个漏洞危害应该还是有一些的,如果满足2个前置条件,那么直接RCE是没什么问题的。在分析这个漏洞之前需要一些Spring Webflow的基础知识,给大家推荐这篇文章https://www.ibm.com/developerworks/cn/education/java/j-spring-webflow/index.html。
3. 漏洞原理分析
3.1 源码补丁分析
首先我们可以从Spring Web Flow官网找到Spring Web Flow源码github地址,然后通过找到补丁提交的源代码主要在spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcView.java文件中修改,查看和上一个版本的源码比较:
3.2 源码分析
我们发现这里对 addEmptyValueMapping(DefaultMapper mapper, String field, Object model) 这个方法里面表达式解析的实现类进行了替换,直接使用了BeanWrapperExpressionParser来解析,关于这个类我们后面再详细说,那么知道触发漏洞的函数后,我们就可以用MyEclipse来跟踪下函数调用栈,具体如下:
通过调用关系我们可以发现一共有一下两个函数调用了addEmptyValueMapping方法
- addDefaultMappings(DefaultMapper mapper, Set parameterNames, Object model)
- addModelBindings(DefaultMapper mapper, Set parameterNames, Object model)
这里通过调用关系我们可以大概的搞明白Spring WebFlow的执行顺序