【漏洞公告】Spring WebFlow 远程代码执行漏洞(CVE-2017-8039)

漏洞简介

这个漏洞和之前披露的 Spring WebFlow 漏洞(CVE-2017-4971)基本类似,在形成条件上完全一样,需要是 Spring WebFlow 在 Model 的数据绑定上面,由于没有明确指定相关 Model 的具体属性导致从表单可以提交恶意的表达式,导致任意代码执行。两个漏洞的前置条件也是相同,一、默认配置,二、编码规范。

漏洞分析

根据之前 Spring WebFlow 漏洞分析文章,知道上次漏洞问题出现的点主要在 addEmptyValueMapping 函数 ,参数必须是_开头,具体原因看addDefaultMappings函数中的fieldMarkerPrefix变量。 官方修复的方式是使用 BeanWrapperExpressionParser 来解析传递进来表达式(不能执行任意代码),而在监控表达式执行过程中,发现执行 Spel 的并不需要 _ 开头,从代码上看,

参数不以下划线开头的变量走了 addDefaultMapping 的函数。

从代码上看,上次漏洞修复对 emptyValueExpressionParser 实现做替换,而这此的点是在 expressionParser 变量上。

通过监控 Spel 表达式执行可以清晰知道请求走过的函数的堆栈信息

org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression (SpelExpressionParser.java:-1)
org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression (SpelExpressionParser.java:32)
org.springframework.expression.common.TemplateAwareExpressionParser.parseExpression (TemplateAwareExpressionParser.java:76)
org.springframework.binding.expression.spel.SpringELExpressionParser.parseSpelExpression (SpringELExpressionParser.java:96)
org.springframework.binding.expression.spel.SpringELExpressionParser.parseExpression (SpringELExpressionParser.java:77)
org.springframework.webflow.mvc.view.AbstractMvcView.addDefaultMapping (AbstractMvcView.java:511)
org.springframework.webflow.mvc.view.AbstractMvcView.addDefaultMappings (AbstractMvcView.java:473)
org.springframework.webflow.mvc.view.AbstractMvcView.bind (AbstractMvcView.java:392)

对比上一个漏洞 CVE-2017-4971 的堆栈信息

org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression (SpelExpressionParser.java:-1) org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression (SpelExpressionParser.java:32) org.springframework.expression.common.TemplateAwareExpressionParser.parseExpression (TemplateAwareExpressionParser.java:76) org.springframework.binding.expression.spel.SpringELExpressionParser.parseSpelExpression (SpringELExpressionParser.java:96) org.springframework.binding.expression.spel.SpringELExpressionParser.parseExpression (SpringELExpressionParser.java:77) org.springframework.webflow.mvc.view.AbstractMvcView.addEmptyValueMapping (AbstractMvcView.java:485) org.springframework.webflow.mvc.view.AbstractMvcView.addDefaultMappings (AbstractMvcView.java:467) org.springframework.webflow.mvc.view.AbstractMvcView.bind (AbstractMvcView.java:389)…

可以发现两个漏洞除了在

org.springframework.webflow.mvc.view.AbstractMvcView.addDefaultMappings

往下走了不同分支,一个进入 addEmptyValueMapping ,另一个进入 addDefaultMapping ,其余函数流程是一样的。可以说两个漏洞的触发条件和流程是基本类似的。

漏洞利用

还是以 Spring Webflow 官方的 Example 来做例子

1.1、下载使用 spring webflow 官方例子

https://github.com/spring-projects/spring-webflow-samples/tree/master/booking-mvc

1.2、修改 org.springframework.webflow.samples.booking.config.WebFlowConfig.mvcViewFactoryCreator factoryCreator.setUseSpringBeanBinding(false);

这个值在默认配置中就是为 false;(为什么需要这个条件可参考上一个漏洞分析)

1.3、更新 pom.xml 的 webflow 版本为 <webflow-version>2.4.5.RELEASE</webflow-version> 官方针对 CVE-2017-4971 更新的就是2.4.5

1.4、因为触发点跟上一个漏洞基本类似,所以复现过程也一样,来到订阅图书这个功能页面,点击confirm 抓包然后增加一个参数

{T(org.springframework.web.context.request.RequestContextHolder).getRequestAttributes().getResponse().addHeader(“vulnerable”,“true”)}

解决方案

升级到2.4.6.