漏洞描述:
In Spring Framework versions 5.2.0 - 5.2.8, 5.1.0 - 5.1.17, 5.0.0 - 5.0.18, 4.3.0 - 4.3.28, and older unsupported versions, the protections against RFD attacks from CVE-2015-5211 may be bypassed depending on the browser used through the use of a jsessionid path parameter.
初步分析:
RFD漏洞原理略过,从漏洞描述可知CVE-2020-5421是针对CVE-2015-5211修复方式的一个绕过,绕过方式是通过一个jsessionid路径参数
CVE-2015-5211:
CVE-2015-5211是针对Spring内容协商机制(content-negotiation)的滥用导致的RFD漏洞。
写一个简单的demo:
@Controller @RequestMapping(value = "/spring") public class springRFD { @RequestMapping("rfd") @ResponseBody public String Index(String content, HttpServletResponse response){ return content; } }
正常访问此请求:
http://x.x.x.x/spring/rfd?content=calc
响应中Content-Type为text/html
URL结尾加.json
http://x.x.x.x/spring/rfd.json?content=calc
响应中Content-Type为application/json
URL结尾改为.bat
http://x.x.x.x/spring/rfd.bat?content=111
此时通过浏览器访问,浏览器会将响应内容保存为文件,在响应头未指定Content-Disposition的情况下,根据URL保存文件名为rfd.bat,此时若用户点击下载的文件,将执行rfd.bat中的命令。RFD漏洞即通过钓鱼诱骗的方式,以可信的网站地址欺骗用户下载执行恶意脚本。
Spring针对CVE-2015-5211的修复方式是指定一个后缀的白名单,白名单外的后缀文件类型将统一添加一个响应头Content-Disposition: inline;filename=f.txt,此时下载文件后将保存为文件名f.txt,即使用户点击该文件也不会执行恶意脚本
CVE-2020-5421:
CVE-2020-5421是针对CVE-2015-5211修复方式的绕过,定位到CVE-2015-5211的修复代码
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor. addContentDispositionHeader
跟进rawUrlPathHelper.getOriginatingRequestUri方法,一路跟进定位到org.springframework.web.util.removeJsessionid方法中会将请求url中;jsessionid=字符串开始进行截断(或者下一个;前)
此时关注spring另一个特性,URL路径中添加;开头字符串的path仍可正常访问请求,如
http://x.x.x.x/spring/rfd?content=111
http://x.x.x.x/spring/;xxx/rfd?content=111
是可以得到同样响应的
结合上述删除;jsessionid=的代码片段,删除;jsessionid=之后CVE-2015-5211的后续防御代码即将获取不到请求的真实后缀文件名,得到CVE-2020-5421的绕过payload
http://x.x.x.x/spring/;jsessionid=/rfd.bat?content=calc
修复后版本spring5.2.9测试,cve-2020-5421的payload情况下仍将添加Content-Disposition: inline;filename=f.txt头
参考资料:
https://tanzu.vmware.com/security/cve-2020-5421