Struts2漏洞笔记之S2-004
漏洞原理
以/srtuts
最为访问路径前缀能够进行目录穿越造成任意tomcat容器文件读取或任意目录读取.
版本影响
测试环境:struts2 2.1.2 tomcat 8.5.0
Struts 2.0.0 - 2.0.11.2
Struts 2.1.0 - 2.1.2
https://cwiki.apache.org/confluence/display/WW/S2-004
漏洞原理
漏洞点发生在过滤器FilterDispatcher::doFilter中,也是struts2执行Action操作的入口。当匹配的mapping为null,如果用户以”/struts”路由开头去访问web服务,会找寻静态文件。分析mapping返回的执行逻辑,DefaultActionMapper::dropExtension
中只要当前用户访问中在末尾不带有符号/
就能够返回null
.
if语句满足mapping==null
就能够进文件读取,满足路由以/struts
开头,进入FilterDispatcher::findStaticResource
读取静态文件。findInputStream为读取路径内容,该处文件读取会对路径进行一次URL解码.最后调用ClassLoaderUtil.getResourceAsStream
读取文件内容.
需要注意最后会对ifModifiedSince
字段判断,这里可以由于直接获取http头可控,可以直接构造http头If-Modified-Since: 0
绕过
所以最后POC构造需要对/
进行二次URL编码,第一次tomcat解码获得/ => %2f
,利用%2f
能够绕过mapping对象路由判断逻辑中的indexof
对/
匹配,也能够绕过对结尾.class
匹配,最后在文件读取之前被再一次解码,成功读取目录或文件内容,
目录读取
/Struts2_004_war_exploded/struts/..%252f..%252f..%252f..%252f..%252fclasses%252f
由于getResource限制了tomcat容器目录,只能读取当前容器目录下的文件,如class文件读取
具体可见:https://www.bbsmax.com/A/KE5Q6PRLdL/
/Struts2_004_war_exploded/struts/..%252f..%252f..%252f..%252f..%252fclasses%252fAction%252fLoginAction.class%252f
漏洞修复
修复版本:Struts 2.0.12 or Struts 2.1.6
DefaultStaticContentLoader::findStaticResource
新版修复中会先获取一次resourceUrl(返回可读取的资源路径),调用endWith
匹配路径末尾是否和resourceUrl
可读资源路径末尾匹配,防御了路径穿越.
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!