总结CVE-2014-0094对Struts1的影响。除非特别说明,各版本均在java 1.7.0_02、struts 1.3.10、apache-tomcat-6.0.39、FreeBSD 8.2环境下进行确认。
此外,无论何种情况,均不对源代码、文档等内容作任何保证。并且,无论发生何种事件,我均不参与其中。特别是若滥用此内容,我亦不承担任何责任。(虽然这么说,但并没有什么新鲜事。)
本次参考了各种网站,提供了解决方案的具体示例。除已知事实外,在源代码等处注明了参考URL。感谢公开相关信息的人员。
尽量不使用专业术语,虽然可能存在歧义,但采用了易于理解的语言。
关于Struts1的本次漏洞,似乎存在CVE-2014-0094、S2-020等多种称呼,但暂且统称为CVE-2014-0094。
无需再次说明,CVE-2014-0094存在着非常严重的问题。
http://www.nta.go.jp/sonota/sonota/osirase/service.htm
根据“e-Tax软件(WEB版)”、“确定申告书等制作栏目”、“NISA(日本版ISA)栏目”服务停止通知(重要)平成26年4月25日,国税厅的web service使用了Struts1,并在发现漏洞的当天即停止了服务。
推测是为了将损害控制在最小限度而紧急停止。
在本方进行实证实验后,确认仅通过访问URL即可导致服务停止及任意文件泄露。
仅通过访问URL即可实现,因此使用匿名邮件地址将包含URL的邮件发送至邮件列表,很难特定犯人,可轻松实施服务停止。
这真是一个能如此简单攻击的问题。
这一点最为重要。至少当第三方机关公布可能产生影响时,首先应停止系统以防止损害扩大,这才是正确的做法。即使后续调查确认无影响,已泄露的信息也无法恢复。当然,这需要政治判断。对于企业而言,伦理观、日常的问题意识、风险应对能力等都会受到考验。
该问题源于系统持有的部分设置值可被改写。需要调查哪些设置值可以被改写。根据这些值,判断可能实施何种攻击。
这些设置值因Servlet容器而异。在Tomcat6中,似乎不太可能执行任意代码,但在Tomcat8中则可执行任意代码。此外,Jetty、WebSphere Application Server等,需根据使用环境确认存在哪些设置值。
在Tomcat6的情况下,据说有23个此类设置可被更改。若更改class.classLoader.resources.dirContext.docBase,则正常系统运行将变得不可能;同时,通过指定服务器上的文件替代JSP显示,可以获取(泄露)任意文件。
在Tomcat8的情况下,可以执行任意代码,这是因为相比Tomcat6,可设置的数值增加了。如果所使用的Servlet容器中不存在该设置值,目前认为问题不大。
本次的设置值更改,除了在URL中包含该字符串外,也可以通过普通请求的隐藏字段实现,另外还可在cookie中包含该值。
从访问日志中,无法得知通过隐藏字段设置的情况。
经常有在周日深夜重启的情况,但在此之前,若进行了docBase的改写及文件获取,之后因系统重启,系统管理员难以察觉异常。若在该时间段内大量出现状态码404、500等,则很可能某些文件已泄露。
Struts1已停止支持(先不谈“开源的支持是什么?”),因此不会发布安全补丁。需自行解决。
问题的根源在于BeanUtil,因此需要实现当接收到不适当的字符串时将其忽略的处理逻辑。BeanUtil是用于更改对象设置值的工具(这种说法存在很大歧义)。
实现示例如下:
com.haselab.struts.filter
web.xml
简单说明:在web.xml中,调用在系统启动时更改BeanUtil行为的程序。调用SafeResolverListener.java,之后BeanUtil将使用SafeResolver.java。SafeResolver.java中,若解析的字符串(忽略大小写)为'classLoader',则返回""(空字符串)。即阻止对classLoader设置任意值。此处的行为参考了 https://gist.github.com/nakamura-to/11347570 (程序简短,故直接引用)。
若应用程序需要更改名为classLoader的设置,则此方法将导致无法更改,因此无法应对。但通常不会将设置项命名为classLoader,因此首先问题不大。若不安,可对应用程序所有源代码执行 grep -r -i classLoader * 确认不存在即可。
对docBase的改写进行了验证。请在mvn部署后,通过浏览器查看struts目录。每次点击按钮都会进行docBase改写,并显示/etc/passwd文件。