4月23日消息,近日安全研究人员指出Apache Struts2在漏洞公告S2-020里,在处理修复CVE-2014-0094的漏洞修补方案存在漏洞,导致补丁被完全绕过。目前官方在GitHub上对该问题做出了修正。该问题被曝光后,估计又有很多网站要遭殃。
代码修复详情:
https://github.com/apache/struts/commit/aaf5a3010e3c11ae14e3d3c966a53ebab67146be#diff-710b29900cea21e85893cae43dd08c92
- ^class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.* + (.*\.|^)class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*
根据github上代码修改历史,这个问题应该是在2014.3.31日修复的,2014.04.06合并到代码的主分支,且提供Struts 2.3.17 版本,但是不清楚为什么官方没有通知更新,同时也没有人及时关注这个代码修改。
2014.05.03更新:
http://struts.apache.org/release/2.3.x/docs/s2-022.html
http://struts.apache.org/announce.html#a20140503
推荐升级到2.3.16.3
2014.04.29更新:
官方修复方案:http://struts.apache.org/release/2.3.x/docs/s2-021.html
相关官方声明:http://struts.apache.org/announce.html#a20140424
推荐升级到2.3.16.2
目前官网(http://struts.apache.org/release/2.3.x/)可下载到的struts2-core文件还是有漏洞的文件:
struts2-core-2.3.16.1.jar
通过jar命令解压,或者下载到windows电脑上使用winrar解压,找到struts-default.xml文件,搜索excludeParams,
存在多处匹配结果:
^class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*
根据github中修改记录,可以看到^class需要修改为(.*\.|^)class,很明显(.*\.)class这种情况被忽略掉了。
2014.04.29更新:
官方修复方案:http://struts.apache.org/release/2.3.x/docs/s2-021.html
推荐升级到2.3.16.2
紧急修复方法:
1.代码修复:
解压struts2-core-2.3.16.1.jar 文件,找到struts-default.xml文件
在struts-default.xml文件里面,将
^class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*
替换为
(.*\.|^)class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*。
将修改后的struts-default.xml 覆盖原来的struts-default.xml文件,然后重新打包,上线。
2.在边界设备上添加拦截规则:
将class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:等关键词过滤掉,但是需要密切关注误伤情况,同时此方案无法拦截编码后的***案例。
根本解决方法:
时刻关注官方修复方案应该是升级到Struts 2.3.18(截至2014.04.23,github上提供的是最新release版本为2.3.17,snapshot最新是2.3.18,根据http://markmail.org/message/6wmiu7cphcn2jfav 邮件内容,GA版本应该目前还是延后发布中 )版本,同时对官方修复内容进行审核。
换框架,成本有点高了。
个人思考:
目前这种不断添加拦截字符的方式无法完全解决这个漏洞问题,在网上看到了一篇外文关于此漏洞的修复:
推荐用 .*classLoader.*替换(.*\.|^)class 进行拦截。
不过个人感觉,此次修复后还会再有漏洞出来,或者说本次修复本身就是无效可被利用的。
【Struts2 S2-020绕过漏洞解决方案】对于今天预警的“Struts2 S2-020绕过漏洞”知道创宇研究人员联合阿里云安全著名安全专家 “空虚浪子心”推出解决方案:
修改struts源码中的struts-default.xml
替换所有的 ^dojo\..*
改为(.*\.|^)class\..*,.*'class'.*,(.*\.|^)class\[.*,^dojo\..*
注意,此文件有多处地方要修改
[终极解决方案 2014.04.24 14:00]
【2014.04.24】Struts2 S2-020绕过漏洞及最新解决方案[更新]
http://bbs.anquan.org/forum.php?mod=viewthread&tid=40548
事实证明之前公布的所有解决方案[包括其他公司及组织公布的]再次被无情的bypass了,我们最终选择了修改底层代码来实现防御。阿里云安全的安全专家‘空虚浪子心’再次分享了他的方法:
修改struts源码
com.opensymphony.xwork2.interceptor.ParametersInterceptor
搜索下面方法:
public void setExcludeParams(String commaDelim) {
Collection
excludePatterns = ArrayUtils.asCollection(commaDelim); if (excludePatterns != null) {
excludeParams = new HashSet
(); for (String pattern : excludePatterns) {
excludeParams.add(Pattern.compile(pattern));
}
}
}
修改为:
public void setExcludeParams(String commaDelim) {
Collection
excludePatterns = ArrayUtils.asCollection(commaDelim); if (excludePatterns != null) {
excludeParams = new HashSet
(); for (String pattern : excludePatterns) {
excludeParams.add(Pattern.compile(pattern));
}
}
//s021 zhenzheteng
Pattern s021_1 = Pattern.compile("(.*\\.|^)class\\..*",Pattern.CASE_INSENSITIVE);
Pattern s021_2 = Pattern.compile(".*'class'.*",Pattern.CASE_INSENSITIVE);
Pattern s021_3 = Pattern.compile("(.*\\.|^)class\\[.*",Pattern.CASE_INSENSITIVE);
excludeParams.add(s021_1);
excludeParams.add(s021_2);
excludeParams.add(s021_3);
}