漏洞描述
在基于struts2开发的应用中如果使用convention插件则可以实现远程代码执行(不需要S2-057的类似的需要特定的result才能触发)。该漏洞只需要在lib包中存在convention插件即可。
限制条件
启用convention插件
危害等级
严重(可以实现远程代码执行,SecurityMemberAccess限制绕过)
影响版本
Struts 2.3.20 - Struts 2.3.34,Struts 2.5.0 - Struts 2.5.16
修复方案
更新最新版的struts2,Struts2.3.x则可以更新至2.3.35
http://apache.mirrors.hoobly.com/struts/2.3.35/struts-2.3.35-lib.zip
struts2.5.x则可以更新至2.5.17
http://apache.mirrors.hoobly.com/struts/2.5.17/struts-2.5.17-lib.zip
如果您的应用中使用了Convention插件则尽快升级以上对应版本。
漏洞分析
struts2在处理不存在的action时候会调用ConventionUnknownHandler,从而导致result的location属性可控,而location属性会被ognl处理导致任意代码执行。
在启用Convention插件之后默认会设置alwaysSelectFullNamespace 属性为true,如下图所示:
设置该属性为true的时候可以控制struts2的namespace
可控的url——实现跨目录搜索资源
在struts2中DefaultActionMapper类主要是用来解析url ,将url封装成ActionMapping。首先通过RequestUtils.getUri(request)来获取对应的url。
如下图所示:
在RequestUtils.getUri(request)的代码实现有个servletPath获取存在一定问题。
在tomcat8以下是允许特殊字符进入url的。
其中request.getServletPath为获取请求的servletPath
request.getRequestURI为获取请求的URI
例如:
url为:
http://target.com/admin/admin.action
那么获取到的servletPath为/admin,url为/admin/admin.action
如果url为:
http://target.com/..action/../..action;
对应的servletPath:..action
对应的URI为..action/../..action;
从而根据RequestUtils.getServletPath方法获取到的结果就是/../..action;
如果需要多级跨目录则可以构造类似url为
http://target.com/strut2case/demo/demo/..action/../../../..action;
从而根据RequestUtils.getServletPath方法获取到的结果就是/../../../..action;
从而为后面的跨目录寻找资源文件作铺路。
进入解析namespace方法:
从上图可以看到alwaysSelectFullNamespace为true的时候namespace属性可控(为什么要控制namespace属性,因为只有namespace在下面不会被校验,其他的name属性都会被剔除一些特殊字符)
在创建DefaultActionProxy的时候会调用prepare来查找对应配置文件中的action
如果未找到对应的action映射,则会调用
unknownHandlerManager.handleUnknownAction(namespace, actionName)来处理。
其中unknownHandlerManager为Convention plugin配置文件中定义的
跟入ConventionUnknownHandler的handleUnknownAction方法
其中redirectSlash在convention plugin中的配置文件中默认设置为true
跟入buildActionConfig
参数path可控而defaultResultParam为result的location属性。
所以result的location属性可控,而reulst在执行的时候会调用ognl来处理location属性从而导致rce
原文发布时间为:2018-09-4