SpringMVC⽬录穿越漏洞(CVE-2018-1271)
Spring MVC ⽬录穿越漏洞(CVE-2018-1271)
SpringMVC介绍:
SpringMVC框架是以请求为驱动,围绕Servlet设计,将请求发给控制器,然后通过模型对象,分派器来展⽰请求结果视图。其中核⼼类是,它是⼀个Servlet,顶层是实现的Servlet接⼝。
漏洞简介:
2018年04⽉05⽇,Pivotal公布了Spring MVC存在⼀个⽬录穿越漏洞(CVE-2018-1271)。Spring Framework版本5.0到5.0.4,4.3到4.3.14以及较旧的不受⽀持的版本允许应⽤程序配置Spring MVC以提供静态资源(例如CSS,JS,图像)。当Spring MVC的静态资源存放在Windows系统上时,攻击可以通过构造特殊URL导致⽬录遍历漏洞。
漏洞影响:
Server运⾏于Windows系统上
要使⽤file协议打开资源⽂件⽬录
漏洞复现
操作系统Windows
web代码
中间件jetty
环境搭建
1.下载 spring-mvc-showcase
git clone github/spring-projects/spring-mvc-showcase.git
修改l,使⽤Spring Framework 5.0.0
2.修改 Spring MVC 静态资源配置,可参考
通过官⽅⽂档可知有两种⽅式配置,可⾃⾏选择配置。此处通过重写WebMvcConfigurer中的addResourceHandlers⽅法来添加新的资源⽂件路径。在org.springframework.fig.WebMvcConfig添加以下代码即可,使⽤file://协议指定resources为静态⽂件⽬录。
registry.addResourceHandler("/resources/**").addResourceLocations("file:./src/main/resources/","/resources/");
3.使⽤ jetty 启动项⽬
mvn jetty:run
⾄此复现环境搭建完毕。
复现过程及结果
访问以下链接
localhost:8080/spring-mvc-showcase/resources/%255c%255c..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/windows
可以看到成功读取到win.ini的内容了
当外部要访问静态资源时,会调
⽤org.springframework.source.ResourceHttpRequestHandler:handleRequest来处理,在这⾥下断点调试。
跟进org.springframework.source.ResourceHttpRequestHandler:getResource()。
在request中保存的路径是/spring-mvc-
showcase/resources/%255c%255c..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/windows/win.ini。
在Attribute()函数取值时会进⾏ url decode操作,此时path的值
为%5c%5c..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/windows/win.ini。接下来会对path进⾏两次校验,将path和path解码之后的值分别使⽤isInvalidPath函数检查。看下这个函数
当path包含有..的时候,会调⽤cleanPath函数对path处理。跟进
这个函数的作⽤是把包含..的这种相对路径转换成绝对路径。例如/foo/bar/../经过cleanPath处理后就会变成/foo/。
cleanPath的问题在于String[] pathArray = delimitedListToStringArray(pathToUse, "/");这个是允许空元素存在的,也就是说cleanPath会
把//当成⼀个⽬录,⽽操作系统是不会把//当成⼀个⽬录的。借⽤⼀张Orange⼤佬的图。
继续回到流程上,上⾯说到会对path进⾏两次校验,第⼀次调⽤isInvalidPath,path的值cve漏洞库
是%5c%5c..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/windows/win.ini,因为path以/分割之后没有元素等于..,所以path经
过cleanPath处理后的值不变,继续之后的判断,path⾥⾯也不包含../,所以最终返回false,也就是通过
了校验
后的值是//windows/win.ini,之后继续判断,path⾥⾯也不包含../,最终返回false,也通过了校验。
通过两次校验之后,继续向下执⾏。获取⼀个Resource对象
path的值还是之前,getLocations()获取到的就是之前在配置⽂件中配置的路径file:./src/main/resources/,继续跟进
跟进ResourceResolver类的resolveResource
跟进PathResourceResolver的resolveResourceInternal
进⼊到org.springframework.source.PathResourceResolver的getResource()
此时的resourcePath就是之前的path,location就是之前getLocations()获取到的值。继续跟进Resource

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。