def verify_request(self, flag, type="request"): """ Check whether the ceye interface has data :param flag: Input flag :param type: Request type (dns|request), the default is request :return: Boolean """ ret_val = False counts = 3 url = ( "http://api.ceye.io/v1/records?token={token}&type={type}&filter={flag}" ).format(token=self.token, type=type, flag=flag) while counts: try: time.sleep(1) resp = requests.get(url) if resp and resp.status_code == 200 and flag in resp.text: ret_val = True break except Exception as ex: logger.warn(ex) time.sleep(1) counts -= 1 return ret_val
def _set_user_pocs_path(): if conf.pocs_path: if check_path(conf.pocs_path): paths.USER_POCS_PATH = conf.pocs_path else: warm_msg = "User defined pocs path {0} is invalid".format(conf.pocs_path) logger.warn(warm_msg)
def verify_request(self, flag, type="request"): """ 校验ceye接口是否有数据 :param flag: 输入的flag :param type: 请求类型(dns|request),默认是request :return: Boolean """ if not self.check_account(): return False ret_val = False counts = 3 url = "http://api.ceye.io/v1/records?token={token}&type={type}&filter={flag}".format( token=self.token, type=type, flag=flag) while counts: try: time.sleep(1) resp = requests.get(url) if resp and resp.status_code == 200 and flag in resp.text: ret_val = True break except Exception as ex: logger.warn(ex) time.sleep(1) counts -= 1 return ret_val
def exact_request(self, flag, type="request"): """ Obtain relevant data by accessing the ceye interface :param flag: Input flag :param type: Request type (dns|request), the default is request :return: Return the acquired data """ counts = 3 url = ( "http://api.ceye.io/v1/records?token={token}&type={type}&filter={flag}" ).format(token=self.token, type=type, flag=flag) while counts: try: time.sleep(1) resp = requests.get(url) if resp and resp.status_code == 200 and flag in resp.text: data = json.loads(resp.text) for item in data["data"]: name = item.get("name", '') pro = flag suffix = flag t = get_middle_text(name, pro, suffix, 0) if t: return t break except Exception as ex: logger.warn(ex) time.sleep(1) counts -= 1 return False
def exact_request(self, flag, type="request"): """ 通过访问ceye接口获取相关数据 :param flag: 输入的flag :param type: 请求类型(dns|request),默认是request :return:返回获取的数据 """ if not self.check_account(): return "" counts = 3 url = "http://api.ceye.io/v1/records?token={token}&type={type}&filter={flag}".format( token=self.token, type=type, flag=flag) while counts: try: time.sleep(1) resp = requests.get(url) if resp and resp.status_code == 200 and flag in resp.text: data = json.loads(resp.text) for item in data["data"]: name = item.get("name", '') pro = "/" + flag suffix = flag t = get_middle_text(name, pro, suffix, 7 + len(flag)) if t: return t break except Exception as ex: logger.warn(ex) time.sleep(1) counts -= 1 return False
def save_history(completion = None): if not readline_available(): return if completion == AUTOCOMPLETE_TYPE.SQL: history_path = paths.SQL_SHELL_HISTORY elif completion == AUTOCOMPLETE_TYPE.OS: history_path = paths.OS_SHELL_HISTORY elif completion == AUTOCOMPLETE_TYPE.API: history_path = paths.API_SHELL_HISTORY elif completion == AUTOCOMPLETE_TYPE.CONSOLE: history_path = paths.POCSUITE_CONSOLE_HISTORY else: history_path = paths.POCSUITE_SHELL_HISTORY try: with open(history_path, "w+"): pass except Exception: pass readline.set_history_length(MAX_HISTORY_LENGTH) try: readline.write_history_file(history_path) except IOError as msg: warn_msg = "there was a problem writing the history file '{0}' ({1})".format(history_path, msg) logger.warn(warn_msg)
def update(): if not conf.update_all: return success = False if not os.path.exists(os.path.join(paths.POCSUITE_ROOT_PATH, "../", ".git")): warn_msg = "not a git repository. It is recommended to clone the 'knownsec/pocsuite3' repository " warn_msg += "from GitHub (e.g. 'git clone --depth 1 {} pocsuite3')".format( GIT_REPOSITORY) logger.warn(warn_msg) if VERSION == get_latest_revision(): logger.info("already at the latest revision '{}'".format( get_revision_number())) return else: info_msg = "updating pocsuite3 to the latest development revision from the " info_msg += "GitHub repository" logger.info(info_msg) debug_msg = "pocsuite3 will try to update itself using 'git' command" logger.debug(debug_msg) data_to_stdout("\r[{0}] [INFO] update in progress ".format( time.strftime("%X"))) cwd_path = os.path.join(paths.POCSUITE_ROOT_PATH, "../") try: process = subprocess.Popen( "git checkout . && git pull %s HEAD" % GIT_REPOSITORY, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd_path.encode(sys.getfilesystemencoding() or UNICODE_ENCODING)) poll_process(process, True) stdout, stderr = process.communicate() success = not process.returncode except (IOError, OSError) as ex: success = False stderr = str(ex) if success: logger.info("{0} the latest revision '{1}'".format( "already at" if b"Already" in stdout else "updated to", get_revision_number())) else: if "Not a git repository" in stderr: err_msg = "not a valid git repository. Please checkout the 'knownsec/pocsuite3' repository " err_msg += "from GitHub (e.g. 'git clone --depth 1 %s pocsuite3')" % GIT_REPOSITORY logger.error(err_msg) else: logger.error("update could not be completed ('%s')" % re.sub(r"\W+", " ", stderr).strip()) if not success: if IS_WIN: info_msg = "for Windows platform it's recommended " info_msg += "to use a GitHub for Windows client for updating " info_msg += "purposes (http://windows.github.com/) or just " info_msg += "download the latest snapshot from " info_msg += "https://github.com/knownsec/pocsuite3/downloads" else: info_msg = "for Linux platform it's recommended " info_msg += "to install a standard 'git' package (e.g.: 'sudo apt-get install git')" logger.info(info_msg)
def execute(self, target, headers=None, params=None, mode='verify', verbose=True): self.target = target self.url = parse_target_url(target) if self.current_protocol == POC_CATEGORY.PROTOCOL.HTTP else self.build_url() self.headers = headers self.params = str_to_dict(params) if params else {} self.mode = mode self.verbose = verbose self.expt = (0, 'None') # TODO output = None try: output = self._execute() except NotImplementedError as e: self.expt = (ERROR_TYPE_ID.NOTIMPLEMENTEDERROR, e) logger.log(CUSTOM_LOGGING.ERROR, 'POC: {0} not defined "{1}" mode'.format(self.name, self.mode)) output = Output(self) except ConnectTimeout as e: self.expt = (ERROR_TYPE_ID.CONNECTTIMEOUT, e) while conf.retry > 0: logger.debug('POC: {0} timeout, start it over.'.format(self.name)) try: output = self._execute() break except ConnectTimeout: logger.debug('POC: {0} time-out retry failed!'.format(self.name)) conf.retry -= 1 else: msg = "connect target '{0}' failed!".format(target) logger.error(msg) output = Output(self) except HTTPError as e: self.expt = (ERROR_TYPE_ID.HTTPERROR, e) logger.warn('POC: {0} HTTPError occurs, start it over.'.format(self.name)) output = Output(self) except ConnectionError as e: self.expt = (ERROR_TYPE_ID.CONNECTIONERROR, e) msg = "connect target '{0}' failed!".format(target) logger.error(msg) output = Output(self) except TooManyRedirects as e: self.expt = (ERROR_TYPE_ID.TOOMANYREDIRECTS, e) logger.debug(str(e)) output = Output(self) except Exception as e: self.expt = (ERROR_TYPE_ID.OTHER, e) # logger.debug(str(e)) logger.exception(e) output = Output(self) return output
def _set_user_pocs_path(): if conf.pocs_path: if check_path(conf.pocs_path): paths.USER_POCS_PATH = conf.pocs_path for root, dirs, files in os.walk(paths.USER_POCS_PATH): files = list(filter(lambda x: not x.startswith("__") and x.endswith(".py"), files)) conf.poc = [os.path.join(paths.USER_POCS_PATH, f) for f in files] else: warm_msg = "User defined pocs path {0} is invalid".format(conf.pocs_path) logger.warn(warm_msg)
def _set_network_timeout(): if conf.timeout: conf.timeout = float(conf.timeout) if conf.timeout < 3.0: warn_msg = "the minimum HTTP timeout is 3 seconds, pocsuite " warn_msg += "will going to reset it" logger.warn(warn_msg) conf.timeout = 3.0 else: conf.timeout = 30.0 socket.setdefaulttimeout(conf.timeout)
def search(self, dork): search_result = set() # create a browser instance browser = pychrome.Browser(url="http://127.0.0.1:9222") # create a tab tab = browser.new_tab() # start the tab tab.start() tab.Page.enable() # call method tab.Network.enable() tab.Runtime.enable() start = 1000 for step in range(0, start + 10, 10): url = "https://www.google.com/search?q={}".format(dork) url = url + "&start={}".format(step) # stepinfo="step:"+str(step) # logger.info(stepinfo) try: # call method with timeout tab.Page.navigate(url=url, _timeout=5) tab.wait(5) exp = 'document.getElementsByClassName("r").length' length = tab.Runtime.evaluate(expression=exp) # google就看报不报错,报错了的话document.getElementsByClassName("r").length是为0的 if length['result']['value'] == 0: logger.warn("[PLUGIN] Google Dork get 0, Exit") break # 从每一页上抓取url for l in range(0, length['result']['value']): # tab.wait(1) exp1 = 'document.getElementsByClassName("r")[{}].getElementsByTagName("a")[0].href'.format( l) res1 = tab.Runtime.evaluate(expression=exp1) logger.info(res1['result']['value']) search_result.add(res1['result']['value']) except Exception as ex: logger.error(str(ex)) tab.stop() browser.close_tab(tab) return search_result
def start(self): """ Routersploit main entry point. Starting interpreter loop. """ while True: try: self.input_command, self.input_args = self.parse_line(input(self.prompt)) command = self.input_command.lower() if not command: continue command_handler = self.get_command_handler(command) command_handler(self.input_args) except PocsuiteBaseException as warn: logger.warn(warn) except EOFError: logger.info("Pocsuite stopped") break except KeyboardInterrupt: logger.info("User Quit") break
def load_history(completion = None): if not readline_available(): return clear_history() if completion == AUTOCOMPLETE_TYPE.SQL: history_path = paths.SQL_SHELL_HISTORY elif completion == AUTOCOMPLETE_TYPE.OS: history_path = paths.OS_SHELL_HISTORY elif completion == AUTOCOMPLETE_TYPE.API: history_path = paths.API_SHELL_HISTORY elif completion == AUTOCOMPLETE_TYPE.CONSOLE: history_path = paths.POCSUITE_CONSOLE_HISTORY else: history_path = paths.POCSUITE_SHELL_HISTORY if os.path.exists(history_path): try: readline.read_history_file(history_path) except IOError as msg: warn_msg = "there was a problem loading the history file '{0}' ({1})".format(history_path, msg) logger.warn(warn_msg)
def run_threads(num_threads, thread_function, args: tuple = (), forward_exception=True, start_msg=True): threads = [] kb.multi_thread_mode = True kb.thread_continue = True kb.thread_exception = False try: if num_threads > 1: if start_msg: info_msg = "starting {0} threads".format(num_threads) logger.info(info_msg) if num_threads > MAX_NUMBER_OF_THREADS: warn_msg = "starting {0} threads, more than MAX_NUMBER_OF_THREADS:{1}".format( num_threads, MAX_NUMBER_OF_THREADS) logger.warn(warn_msg) else: thread_function() return # Start the threads for num_threads in range(num_threads): thread = threading.Thread(target=exception_handled_function, name=str(num_threads), args=(thread_function, args)) thread.setDaemon(True) try: thread.start() except Exception as ex: err_msg = "error occurred while starting new thread ('{0}')".format( str(ex)) logger.critical(err_msg) break threads.append(thread) # And wait for them to all finish alive = True while alive: alive = False for thread in threads: if thread.isAlive(): alive = True time.sleep(0.1) except (KeyboardInterrupt, PocsuiteUserQuitException) as ex: kb.thread_continue = False kb.thread_exception = True logger.info("user aborted (Ctrl+C was pressed multiple times") if forward_exception: return except (PocsuiteConnectionException, PocsuiteValueException) as ex: kb.thread_exception = True logger.error("thread {0}: {1}".format( threading.currentThread().getName(), str(ex))) if conf.verbose > 1: traceback.print_exc() except Exception as ex: kb.thread_exception = True logger.error("thread {0}: {1}".format( threading.currentThread().getName(), str(ex))) traceback.print_exc() finally: kb.multi_thread_mode = False kb.thread_continue = True kb.thread_exception = False
def task_run(): while not kb.task_queue.empty() and kb.thread_continue: target, poc_module = kb.task_queue.get() if not conf.console_mode: poc_module = copy.deepcopy(kb.registered_pocs[poc_module]) poc_name = poc_module.name if conf.pcap: # start capture flow import os import logging os.environ["MPLBACKEND"] = "Agg" logging.getLogger("scapy").setLevel(logging.ERROR) from pocsuite3.lib.utils.pcap_sniffer import Sniffer from scapy.utils import wrpcap sniffer = Sniffer(urlparse(target).hostname) if sniffer.use_pcap: if not sniffer.is_admin: logger.warn( "Please use administrator privileges, and the poc will continue to execute without fetching the packet" ) conf.pcap = False else: sniffer.start() # let scapy start for a while time.sleep(1) else: logger.warn( "No libpcap is detected, and the poc will continue to execute without fetching the packet" ) conf.pcap = False # for hide some infomations if conf.ppt: info_msg = "running poc:'{0}' target '{1}'".format( poc_name, desensitization(target)) else: info_msg = "running poc:'{0}' target '{1}'".format( poc_name, target) logger.info(info_msg) # hand user define parameters if hasattr(poc_module, "_options"): for item in kb.cmd_line: value = cmd_line_options.get(item, "") if item in poc_module.options: poc_module.set_option(item, value) info_msg = "Parameter {0} => {1}".format(item, value) logger.info(info_msg) # check must be option for opt, v in poc_module.options.items(): # check conflict in whitelist if opt in CMD_PARSE_WHITELIST: info_msg = "Poc:'{0}' You can't customize this variable '{1}' because it is already taken up by the pocsuite.".format( poc_name, opt) logger.error(info_msg) raise SystemExit if v.require and v.value == "": info_msg = "Poc:'{poc}' Option '{key}' must be set,please add parameters '--{key}'".format( poc=poc_name, key=opt) logger.error(info_msg) raise SystemExit try: result = poc_module.execute(target, headers=conf.http_headers, mode=conf.mode, verbose=False) except PocsuiteValidationException as ex: info_msg = "Poc:'{}' PocsuiteValidationException:{}".format( poc_name, ex) logger.error(info_msg) result = None if not isinstance(result, Output) and not None: _result = Output(poc_module) if result: if isinstance(result, bool): _result.success({}) elif isinstance(result, str): _result.success({"Info": result}) elif isinstance(result, dict): _result.success(result) else: _result.success({"Info": repr(result)}) else: _result.fail('target is not vulnerable') result = _result if not result: continue if not conf.quiet: result.show_result() result_status = "success" if result.is_success() else "failed" if result_status == "success" and kb.comparison: kb.comparison.change_success(target, True) output = AttribDict(result.to_dict()) if conf.ppt: # hide some information target = desensitization(target) output.update({ 'target': target, 'poc_name': poc_name, 'created': time.strftime("%Y-%m-%d %X", time.localtime()), 'status': result_status }) result_plugins_handle(output) kb.results.append(output) if conf.pcap: sniffer.join(20) if not sniffer.is_alive(): filename = urlparse(target).hostname + time.strftime( '_%Y_%m_%d_%H%M%S.pcap') logger.info(f"pcap data has been saved in: {filename}") wrpcap(filename, sniffer.pcap.results) else: logger.error("Thread terminates timeout. Failed to save pcap")