北京时间2018年8月22日,Apache官方发布通告公布了Struts2中一个远程代码执行漏洞(CVE-2018-11776,CNVD-2018-15894,CNNVD-201808-740)。该漏洞在两种情况下存在,第一,当xml配置中未设置namespace 值,且上层动作配置(action(s) configurations)中未设置或使用通配符namespace值时,可能导致远程代码执行漏洞的发生。第二,使用未设置 value和action值的url标签,且上层动作配置中未设置或使用通配符namespace值,同样可能导致远程代码执行。
受影响版本
不受影响版本
技术防护方案
通过配置文件检测
此漏洞产生于低版本的Struts组件,当应用系统引入相关组件时,将存在被攻击者远程攻击的风险。建议由应用开发人员排查引入组件的版本是否处于受影响范围之内。
查看Maven配置文件pom.xml中关于组件的版本。如:
<dependency><groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId> <version> 2.5.13 </version> </dependency> |
若红字所示版本在受影响范围内,则请用户尽快升级Struts2至最新版本,以保证长期有效的防护。
通过组件名检测
Linux系统下可使用以下命令查找当前使用的struts2-core包,通过查看其文件名,判断当前版本。
find / -name struts2-core-*.jar |
若红框处版本号在受影响范围内,则请用户尽快升级至最新版本。
官方已在最新版本中修复了此漏洞,请用户尽快将Struts升级至官方修复版本,2.3.*的用户请升级至2.3.35;2.5.*的用户请升级至2.5.17。下载链接如下所示:
Struts2.3.35:
http://mirrors.hust.edu.cn/apache/struts/2.3.35/struts-2.3.35-all.zip
Struts2.5.17:
http://mirrors.hust.edu.cn/apache/struts/2.5.17/struts-2.5.17-all.zip
排查所有Struts 2的配置文件,如struts.xml,为没有定义namespace命名空间的package节点添加命名空间配置。
<package name=”user” namespace=”/user” extends=”struts-default”><action name=”login”>
</action> </package> |
绿盟科技防护建议
手机端访问地址:
https://cloud.nsfocus.com/megi/holes/hole_struts2_2018_8_23.html
PC端访问地址:
https://cloud.nsfocus.com/#/krosa/views/initcdr/productandservice?service_id=1026
2、内网资产可以使用绿盟科技的入侵检测系统(IDS),远程安全评估系统(RSAS V5、V6)和Web应用漏洞扫描系统(WVSS)进行检测。
http://update.nsfocus.com/update/listIds
http://update.nsfocus.com/update/listAurora/v/5
http://update.nsfocus.com/update/listRsasDetail/v/vulweb
通过上述链接,升级至最新版本即可进行检测!
使用绿盟科技防护类产品进行防护
http://update.nsfocus.com/update/listIps
http://update.nsfocus.com/update/listNf
http://update.nsfocus.com/update/wafIndex
通过上述链接,升级至最新版本即可进行防护!
检测产品 |
升级包 / 规则版本号 |
IDS | 5.6.7.732、5.6.8.732、5.6.9.18479、5.6.10.18479 |
RSAS V5 web 插件包 | V051758 |
RSAS V6 web 插件包 | V6.0R02F00.1004 |
WVSS V6 web 插件包 | V6.0R03F00.113 |
防护产品 |
升级包 / 规则版本号 |
IPS | 5.6.7.732、5.6.8.732、5.6.9.18479、5.6.10.18479 |
NF | 5.6.7.732、6.0.1.732 |
WAF | v6.0.5.1.39591、v6.0.7.0.39590、v6.0.6.1.39589 |
具体配置详见附录
技术分析
如图所示,补丁主要添加了cleanNamespaceName方法,该方法通过白名单的方式来验证namespace是否合法,从官方描述和漏洞修复方式来看,该漏洞应该是一个Ognl的表达式注入漏洞。
漏洞发布几个小时之后,漏洞发现作者公布了整个发现过程,并且详细分析了一种漏洞情形: https://lgtm.com/blog/apache_struts_CVE-2018-11776 。按照该博客的说法,拉取struts2-showcase项目作为示例,修改struts-actionchaining.xml,具体如下:
在这种情况下,所有到actionChain1.action的请求的返回结果都会指向register2,并且执行链会到ServletActionRedirectResult.execute方法中,具体如下:
从上图可以看出,通过namespace字段,污染了tmpLocation字典,并且设置为了预期的执行的PoC,这也是补丁中为什么要净化namespace的原因,继续跟踪namespace的去向,执行链会到ServletActionRedirectResult的父类的父类StrutsResultSupport.execute方法中,具体如下图:
这里有个conditionParse方法,这个方式就是使用Ognl表达式来计算数据值,在系统中用得非常多,而且在一些历史漏洞中,也应该由它来背锅,当然最大的锅还是struts官方,每次漏洞出在哪就修在哪,典型的头痛医头,脚痛医脚。方法实现如下图所示:
在这个方法中会使用到TextParseUtil.translateVariables方法,继续跟踪,调用栈进入OgnlTextParser中的evaluate方法,首先会判断传入的表达式是否合法,比如是否能找到${}或者%{}对,接着调用evaluator.evaluate求值,求值过程非常复杂,总得来说就是链式执行过程,具体如下调用栈:
从上图也可以看出最顶层就是通过反射的方式来调用ProcessBuilder的构造函数,中间部分就是链式执行过程中牵涉到一些操作。
我们可以看下求值过程中参数的一些情况。来查看Ognl安全加固的一些变化,具体如下图:
主要是黑名单上又添加了一些类,分别是:
class ognl.DefaultMemberAccess
class com.opensymphony.xwork2.ognl.SecurityMemberAccess
class java.lang.ProcessBuilder
分析就结束了,计算器还是要弹的,如下图:
相关链接如下:
https://cwiki.apache.org/confluence/display/WW/S2-057
完整版防护方案下载