漏洞簡介
這個(gè)漏洞和之前披露的 Spring WebFlow 漏洞(CVE-2017-4971)基本類似,在形成條件上完全一樣,需要是 Spring WebFlow 在 Model 的數(shù)據(jù)綁定上面,由于沒有明確指定相關(guān) Model 的具體屬性導(dǎo)致從表單可以提交惡意的表達(dá)式,導(dǎo)致任意代碼執(zhí)行。兩個(gè)漏洞的前置條件也是相同,一、默認(rèn)配置,二、編碼規(guī)范。
漏洞分析
根據(jù)之前 Spring WebFlow 漏洞分析文章,知道上次漏洞問題出現(xiàn)的點(diǎn)主要在 addEmptyValueMapping 函數(shù) ,參數(shù)必須是_開頭,具體原因看addDefaultMappings函數(shù)中的fieldMarkerPrefix變量。 官方修復(fù)的方式是使用 BeanWrapperExpressionParser 來解析傳遞進(jìn)來表達(dá)式(不能執(zhí)行任意代碼),而在監(jiān)控表達(dá)式執(zhí)行過程中,發(fā)現(xiàn)執(zhí)行 Spel 的并不需要 _ 開頭,從代碼上看,
參數(shù)不以下劃線開頭的變量走了 addDefaultMapping 的函數(shù)。
從代碼上看,上次漏洞修復(fù)對 emptyValueExpressionParser 實(shí)現(xiàn)做替換,而這此的點(diǎn)是在 expressionParser 變量上。
通過監(jiān)控 Spel 表達(dá)式執(zhí)行可以清晰知道請求走過的函數(shù)的堆棧信息
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)
對比上一個(gè)漏洞 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)…
可以發(fā)現(xiàn)兩個(gè)漏洞除了在
org.springframework.webflow.mvc.view.AbstractMvcView.addDefaultMappings
往下走了不同分支,一個(gè)進(jìn)入 addEmptyValueMapping ,另一個(gè)進(jìn)入 addDefaultMapping ,其余函數(shù)流程是一樣的??梢哉f兩個(gè)漏洞的觸發(fā)條件和流程是基本類似的。
漏洞利用
還是以 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);
這個(gè)值在默認(rèn)配置中就是為 false;(為什么需要這個(gè)條件可參考上一個(gè)漏洞分析)
1.3、更新 pom.xml 的 webflow 版本為 <webflow-version>2.4.5.RELEASE</webflow-version> 官方針對 CVE-2017-4971 更新的就是2.4.5
1.4、因?yàn)橛|發(fā)點(diǎn)跟上一個(gè)漏洞基本類似,所以復(fù)現(xiàn)過程也一樣,來到訂閱圖書這個(gè)功能頁面,點(diǎn)擊confirm 抓包然后增加一個(gè)參數(shù)
{T(org.springframework.web.context.request.RequestContextHolder).getRequestAttributes().getResponse().addHeader(“vulnerable”,“true”)}
解決方案
升級(jí)到2.4.6.