Struts2 s2-052 REST插件远程代码执行技术分析与防护方案
2017年9月5日,Apache Struts发布最新的安全公告,Apache Struts 2.5.x以及之前的部分2.x版本的REST插件存在远程代码执行的高危漏洞,漏洞编号为CVE-2017-9805(S2-052)。漏洞的成因是由于使用XStreamHandler反序列化XStream实例的时候没有任何类型过滤导致远程代码执行。 相关地址: https://struts.apache.org/docs/s2-052.html https://cwiki.apache.org/confluence/display/WW/S2-052
受影响的版本
- Struts 2.1.2 – Struts 2.3.33
- Struts 2.5 - Struts 2.5.12
不受影响的版本
- Struts 2.3.34
- Struts 2.5.13
漏洞分析
根据官方的描述信息来看,是REST插件使用到XStreamHandler处理xml数据的时候,由于未对xml数据做任何过滤,在进行反序列将xml数据转换成Object时导致的RCE。环境搭建
从官方地址(https://archive.apache.org/dist/struts/2.5/struts-2.5-all.zip)下载所有源码包,找到其中的struts2-rest-showcase.war直接部署到tomcat就行,当然我更喜欢手动编译,直接通过Maven编译即可。具体的部署过程这里就不详细描述,不过有点是需要注意的,由于javax.imageio的依赖关系,我们的环境的jdk版本需要是jdk8以上,jdk8某些低版本也是不行的,本文作者的版本是jdk8_102,后续的一些验证都是在这个版本上做的补丁分析
环境搭建好了之后,首先我们来看下rest插件的相关配置程序验证的生成
目前公开的程序验证是基于javax.imageio的,这是能直接本地执行命令,但是marshelsec提供了11个XStream反序列化库,其中大部分都是基于JNDI,具体包含:CommonsConfiguration, Rome, CommonsBeanutils, ServiceLoader, ImageIO, BindingEnumeration, LazySearchEnumeration, SpringAbstractBeanFactoryPointcutAdvisor, SpringPartiallyComparableAdvisorHolder, Resin, XBean, 从外部请求类完成反序列化。漏洞验证及简单分析
下图是一个简单的验证分析图,从Poc中可以看出,请求是PUT,请求的url后缀带xml,请求的Content-Type为delicious/bookmark+xml,请求的xml的前缀是<set>.官方临时缓解措施不起作用
官方给出的缓解措施<constant name="struts.action.extension" value="xhtml,,,json" />,从字面意思也能看出来,这个是针对action的后缀的,也就是说如果后缀不带xml也就可以绕过。操作方式如下: 将下图红框部分修改为:<constant name="struts.action.extension" value="xhtml,,json" />
技术防护方案
官方修复方案
Struts官方已经发布了最新版本,请受影响的受用尽快升级来进行防护。 参考链接:- Struts 2.3.34:
- Struts 2.5.13:
绿盟科技防护建议
绿盟科技检测类产品与服务
- 公网资产可使用绿盟云 紧急漏洞在线检测,检测地址如下:
使用绿盟科技防护类产品(IPS/IDS/NF/WAF)进行防护:
入侵防护系统(IPS) http://update.nsfocus.com/update/listIps 下一代防火墙系统(NF) http://update.nsfocus.com/update/listNf Web应用防护系统(WAF) http://update.nsfocus.com/update/wafIndex 通过上述链接,升级至最新版本即可进行防护!临时解决方案
添加xml过滤器,将所有的contentType为“application/xml”的请求全部过滤。该方案会导致所有contentType为application/xml的请求失效,为暂时性的防护方案。 具体过滤器代码如下:public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (request.getContentType() != null) { String contentType = request.getContentType().toLowerCase(Locale.ENGLISH); if (contentType != null && contentType.contains("application/xml")) { response.getWriter().write("Reject!"); } else { chain.doFilter(request, response); } } else { chain.doFilter(request, response); } }添加该过滤器后,使用POC测试,可以拦截:
声 明
本安全公告仅用来描述可能存在的安全问题,绿盟科技不为此安全公告提供任何保证或承诺。由于传播、利用此安全公告所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,绿盟科技以及安全公告作者不为此承担任何责任。绿盟科技拥有对此安全公告的修改和解释权。如欲转载或传播此安全公告,必须保证此安全公告的完整性,包括版权声明等全部内容。未经绿盟科技允许,不得任意修改或者增减此安全公告内容,不得以任何方式将其用于商业目的。关于绿盟科技
北京神州绿盟信息安全科技股份有限公司(简称绿盟科技)成立于2000年4月,总部位于北京。在国内外设有30多个分支机构,为政府、运营商、金融、能源、互联网以及教育、医疗等行业用户,提供具有核心竞争力的安全产品及解决方案,帮助客户实现业务的安全顺畅运行。 基于多年的安全攻防研究,绿盟科技在网络及终端安全、互联网基础安全、合规及安全管理等领域,为客户提供入侵检测/防护、抗拒绝服务攻击、远程安全评估以及Web安全防护等产品以及专业安全服务。 北京神州绿盟信息安全科技股份有限公司于2014年1月29日起在深圳证券交易所创业板上市交易,股票简称:绿盟科技,股票代码:300369。 如果您需要了解更多内容,可以 加入QQ群:570982169 直接询问:010-68438880查看原文:http://blog.nsfocus.net/struts2-s2-052-rest-plug-in-remote-code-execution-technical-analysis/