漏洞简介
漏洞是由于Spring Web Flow的数据绑定问题带来的表达式注入,从而导致任意代码执行。 Spring Web Flow是Spring的一个子项目,主要目的是解决跨越多个请求的、用户与服务器之间的、有状态交互问题,提供了描述业务流程的抽象能力,具体可以参考Spring Web Flow 2.0 入门。
触发漏洞需要满足两个条件:
MvcViewFactoryCreator
对象的useSpringBeanBinding
参数需要设置为false
(默认值)。- flow
view
对象中设置BinderConfiguration
对象为空
影响版本:
- Spring Web Flow 2.4.0 to 2.4.4
- Older unsupported versions are also affected
漏洞复现
漏洞测试源码为 https://github.com/spring-projects/spring-webflow-samples/tree/master/booking-mvc, 来源于Spring Web Flow官方的Example中的例子,booking-mvc中的某个流满足漏洞触发的条件
- flow
view
对象中设置BinderConfiguration
对象为空
path: src/main/webapp/WEB-INF/hotels/booking/booking-flow.xml
可以看出booking model中的confirm没有设置binder,也就是说在confirm阶段是可以触发漏洞的。
useSpringBeanBinding
参数设置为false
参数默认是false, 但是在官方例子中设置为true
了, 需要改源码如下:
path: src/main/java/org/springframework/webflow/samples/booking/config/WebFlowConfig.java
修改源码后,部署环境,然后访问,随便选取一个酒店进行预定。
预定第二步拦截确认请求,增加post参数_T(org.springframework.web.context.request.RequestContextHolder).getRequestAttributes().getResponse().addHeader("vulnerable","True").aaa=n1nty
如下,返回响应头中包含vulnerable: True
, 验证漏洞。
1 | POST /hotels/booking?execution=e1s2 HTTP/1.1 |
弹个计算器试试, payload:_(new+java.lang.ProcessBuilder("/usr/bin/open", "/Applications/Calculator.app")).start()=iswin
漏洞流程
view对象处理用户事件,会根据HTTP参数绑定相应的model。
如果model没有设置BinderConfiguration
, 则会调用addDefaultMappings
函数。
进一步查看addDefaultMappings
函数,可以发现输入参数以fieldMarkerPrefix
(“_”)开头,则会调用addEmptyValueMapping
函数。
若useSpringBeanBinding
参数设置为false
,则 expressionParser
将设置为SpelExpressionParser
对象的实例,而不是BeanWrapperExpressionParser
对象的实例。当调用getValueType
函数时,SpelExpressionParser
对象将执行表达式,触发任意代码执行。
补丁分析
从补丁可以看出,直接将ExpressionParser
设置为BeanWrapperExpressionParser
对象的实例, 默认是执行不了表达式的。