class HostsBruteThread(HttpThread): """ Thread class for HostsBrute modules """ queue = None method = None url = None mask_symbol = None counter = None retested_words = None last_action = 0 def __init__( self, queue, protocol, host, template, mask_symbol, false_phrase, retest_codes, delay, ignore_words_re, counter, result): threading.Thread.__init__(self) self.retested_words = {} self.queue = queue self.protocol = protocol.lower() self.host = host self.template = template self.mask_symbol = mask_symbol self.counter = counter self.result = result self.done = False self.false_phrase = false_phrase self.retest_codes = list(set(retest_codes.split(','))) if len(retest_codes) else [] self.delay = int(delay) self.retest_delay = int(Registry().get('config')['hosts_brute']['retest_delay']) self.http = copy.deepcopy(Registry().get('http')) self.logger = Registry().get('logger') self.method = 'get' self.ignore_words_re = False if not len(ignore_words_re) else re.compile(ignore_words_re) self.retest_limit = int(Registry().get('config')['hosts_brute']['retest_limit']) def run(self): """ Run thread """ req_func = getattr(self.http, self.method) need_retest = False word = False while not self.done: self.last_action = int(time.time()) if self.delay: time.sleep(self.delay) try: if not need_retest: word = self.queue.get() self.counter.up() if not len(word.strip()) or (self.ignore_words_re and self.ignore_words_re.findall(word)): continue try: hostname = self.template.replace(self.mask_symbol, word) except UnicodeDecodeError: self.logger.log( "URL build error (UnicodeDecodeError) with word '{0}', skip it".format(pprint.pformat(word)), _print=False ) continue try: resp = req_func(self.protocol + "://" + self.host, headers={'host': hostname}) except ConnectionError: need_retest = True self.http.change_proxy() continue if self.is_retest_need(word, resp): time.sleep(self.retest_delay) need_retest = True continue search_scope = "" for header in resp.headers: search_scope += "{0}: {1}\r\n".format(header.title(), resp.headers[header]) search_scope += '\r\n\r\n' + resp.text positive_item = False if resp is not None and not search_scope.count(self.false_phrase): self.result.append(hostname) positive_item = True self.log_item(word, resp, positive_item) self.check_positive_limit_stop(self.result) need_retest = False except Queue.Empty: self.done = True break except ChunkedEncodingError as e: self.logger.ex(e) except BaseException as e: try: if str(e).count('Cannot connect to proxy'): need_retest = True else: self.logger.ex(e) except UnicodeDecodeError: pass except UnboundLocalError: self.logger.ex(e) finally: pass
class DafsThread(HttpThread): """ Thread class for Dafs modules """ queue = None method = None template = None mask_symbol = None counter = None retested_words = None last_action = 0 ignore_words_re = None def __init__( self, queue, protocol, host, template, method, mask_symbol, not_found_re, not_found_size, not_found_codes, retest_codes, delay, ignore_words_re, counter, result): threading.Thread.__init__(self) self.retested_words = {} self.queue = queue self.protocol = protocol.lower() self.host = host self.template = template self.mask_symbol = mask_symbol self.counter = counter self.result = result self.done = False self.ignore_words_re = False if not len(ignore_words_re) else re.compile(ignore_words_re) self.not_found_re = False if not len(not_found_re) else re.compile(not_found_re) self.not_found_size = int(not_found_size) self.method = method if method == 'head' and (len(not_found_re) or self.not_found_size != -1): self.method = 'get' not_found_codes = not_found_codes.split(',') not_found_codes.append('404') self.not_found_codes = list(set(not_found_codes)) self.retest_codes = list(set(retest_codes.split(','))) if len(retest_codes) else [] self.delay = int(delay) self.retest_delay = int(Registry().get('config')['dafs']['retest_delay']) self.http = copy.deepcopy(Registry().get('http')) self.logger = Registry().get('logger') self.retest_limit = int(Registry().get('config')['dafs']['retest_limit']) def run(self): """ Run thread """ req_func = getattr(self.http, self.method) need_retest = False word = False while not self.done: self.last_action = int(time.time()) if self.delay: time.sleep(self.delay) try: if not need_retest: word = self.queue.get() if not len(word.strip()) or (self.ignore_words_re and self.ignore_words_re.findall(word)): continue self.counter.up() try: url = self.template.replace(self.mask_symbol, word) except UnicodeDecodeError: self.logger.log( "URL build error (UnicodeDecodeError) with word '{0}', skip it".format(pprint.pformat(word)), _print=False ) continue rtime = int(time.time()) try: resp = req_func(self.protocol + "://" + self.host + url) except ConnectionError: need_retest = True self.http.change_proxy() continue if self.is_retest_need(word, resp): time.sleep(self.retest_delay) need_retest = True continue positive_item = False if self.is_response_right(resp): self.result.append({ 'url': url, 'code': resp.status_code, 'time': int(time.time()) - rtime }) positive_item = True self.log_item(word, resp, positive_item) self.check_positive_limit_stop(self.result) need_retest = False except Queue.Empty: self.done = True break except ChunkedEncodingError as e: self.logger.ex(e) except BaseException as e: try: if str(e).count('Cannot connect to proxy'): need_retest = True else: self.logger.ex(e) except UnicodeDecodeError: pass except UnboundLocalError: self.logger.ex(e) finally: pass
class CmsThread(threading.Thread): """ Thread class for CMS module """ queue = None method = None url = None counter = None last_action = 0 def __init__(self, queue, domain, url, protocol, method, not_found_re, not_found_codes, delay, counter, result): threading.Thread.__init__(self) self.queue = queue self.method = method if not (len(not_found_re) and method.lower() == 'head') else 'get' self.domain = domain self.url = url self.result = result self.counter = counter self.protocol = protocol self.not_found_re = False if not len(not_found_re) else re.compile(not_found_re) not_found_codes = not_found_codes.split(',') not_found_codes.append('404') self.not_found_codes = list(set(not_found_codes)) self.delay = int(delay) self.done = False self.http = Registry().get('http') self.logger = Registry().get('logger') def run(self): """ Run thread """ req_func = getattr(self.http, self.method) need_retest = False while not self.done: self.last_action = int(time.time()) if self.delay: time.sleep(self.delay) try: if not need_retest: path = self.queue.get() try: url = "{0}://{1}{2}".format(self.protocol, self.domain, clear_double_slashes(self.url + path)) except UnicodeDecodeError: self.logger.log( "URL build error (UnicodeDecodeError) with path '{0}', skip it".format(pprint.pformat(path)), _print=False ) continue except UnicodeEncodeError: self.logger.log( "URL build error (UnicodeEncodeError) with path '{0}', skip it".format(pprint.pformat(path)), _print=False ) continue try: resp = req_func(url) except ConnectionError: need_retest = True self.http.change_proxy() continue binary_content = resp is not None and is_binary_content_type(resp.headers['content-type']) if resp is not None \ and str(resp.status_code) not in(self.not_found_codes) \ and not (not binary_content and self.not_found_re and self.not_found_re.findall(resp.content)): self.result.append({ 'path': path, 'code': resp.status_code, }) self.logger.item( path, resp.content if not resp is None else "", binary_content ) self.counter.up() self.queue.task_done() need_retest = False except Queue.Empty: self.done = True break except ChunkedEncodingError as e: self.logger.ex(e) except UnicodeDecodeError as e: self.logger.ex(e) self.queue.task_done() except BaseException as e: try: self.queue.put(path) if not str(e).count('Timed out waiting for page load'): self.logger.ex(e) except UnicodeDecodeError: pass self.queue.task_done()
class WSModule(object): """ Kernel class of modules """ log_path = None log_width = 60 description = "module description" done = False options = [] time_count = False logger = None logger_enable = False options_sets = {} counter = None queue = None result = [] DNS_ZONE_CNAME = 'CNAME' DNS_ZONE_A = 'A' POSSIBLE_DNS_ZONES = [DNS_ZONE_A, DNS_ZONE_CNAME] def __init__(self, kernel): self.kernel = kernel if self.log_path is None: raise WSException('Module must have log path!') def prepare(self): """ Preparing module to run :return: """ self.enable_logger() self.validate_main() self.pre_start_inf() self.load_proxies() def work_end_error(self): """ Exit by error :return: """ exit(1) def is_critical_stop(self): """ Is we has critical sign for immidiately stop? :return: """ return Registry().get('proxy_many_died') or Registry().get( 'positive_limit_stop') or ErrorsCounter.is_limit() def output(self): """ Print output in the end of work :return: """ if Registry().get('proxy_many_died'): self.logger.log("Proxy many died, stop scan") self.work_end_error() if Registry().get('positive_limit_stop'): self.logger.log( "\nMany positive detections. Please, look items logs") self.logger.log("Last items:") for i in range(1, 5): self.logger.log(self.result[-i]) self.work_end_error() if ErrorsCounter.is_limit(): self.logger.log("\nToo many errors") self.work_end_error() def load_proxies(self): """ Load proxies if we has it in options :return: """ for option_key in ['proxies', 'http-proxies']: if option_key in self.options.keys( ) and self.options[option_key].value: Registry().get('proxies').load(self.options[option_key].value) def load_objects(self, queue): """ Method for prepare test objects, here abstract """ raise WSException("This method must be described in child-class") def make_queue(self): """ Abstract method for queue make """ raise WSException("This method must be described in child-class") def start_pool(self): """ Abstract method for make threads pool """ raise WSException("This method must be decsribed in child-class") def enable_logger(self): """ Turn on logger """ self.logger = Registry().get('logger') def pre_start_inf(self): """ Show options values before work start """ log_str = "" log_str += "---------------------------------\n" for option in self.options: log_str += "Option '{0}': {1}\n".format(option, self.options[option].value) log_str += "Logs dir: {0}\n".format(self.logger.logs_dir) log_str += "---------------------------------" self.logger.log(log_str) if int(Registry().get('config')['main']['confirm']): tmp = raw_input("Do you have continue? [Y/n]") if len(tmp.strip()) and tmp.lower() != 'y': self.logger.log("Aborted...") self.work_end_error() def finished(self): """ Is module finished? """ return self.done def do_work(self): """ Scan action of module """ self.prepare() self.make_queue() self.start_pool() self.output() self.done = True def validate_main(self): """ Common user params validate functions """ if 'selenium' in self.options.keys( ) and self.options['selenium'].value: if ('not-found-re' in self.options.keys() and 'not-found-size' in self.options.keys()) and \ (not len(self.options['not-found-re'].value) and self.options['not-found-size'].value == "-1"): raise WSException( "Selenium enabled, module need a not found phrase (--not-found-re) or not found size (--not-found-size) for work!" ) threads_count = int(self.options['threads'].value) if threads_count == 10: threads_count = int(Registry().get('config')['selenium'] ['default_threads_count']) self.options['threads'].value = int(Registry().get( 'config')['selenium']['default_threads_count']) if threads_count != 10 and threads_count > int( Registry().get('config')['selenium']['max_threads']): raise WSException( "Selenium enabled, very many threads value ({0}), see docs." .format(self.options['threads'].value)) if ('method' in self.options.keys() and self.options['method'].value.lower() != 'get') or \ ('params-method' in self.options.keys() and self.options['params-method'].value.lower() != 'get'): raise WSException("In Selenium mode only GET method allowed") if 'not-found-codes' in self.options.keys( ) and self.options['not-found-codes'].value != "404": raise WSException( "In Selenium mode param --not-found-codes not allowed") if 'headers-file' in self.options.keys( ) and self.options['headers-file'].value != "": raise WSException( "In Selenium mode param --headers-file not allowed") if 'protocol' in self.options.keys( ) and self.options['protocol'].value.lower() not in ['http', 'https']: raise WSException( "Protocol param must be 'http' or 'https', but have value '{0}' !" .format(self.options['protocol'].value)) if 'params-method' in self.options.keys( ) and self.options['params-method'].value.lower() not in [ 'get', 'post', 'cookies', 'files' ]: raise WSException( "Method param must be only 'get', 'post', 'cookies', 'files', but have value '{0}' !" .format(self.options['params-method'].value)) if 'method' in self.options.keys( ) and self.options['method'].value.lower() not in [ 'head', 'get', 'post' ]: raise WSException( "Method param must be only 'head', 'get' or 'post', but have value '{0}' !" .format(self.options['method'].value)) if 'not-found-codes' in self.options.keys() and len( self.options['not-found-codes'].value): for code in self.options['not-found-codes'].value.strip().split( ","): if len(code.strip()) and not re.match(r'^(\d+)$', code.strip()): raise WSException( "Not-found code must be digital, but it is '{0}'". format(code.strip())) if 'retest-codes' in self.options.keys() and len( self.options['retest-codes'].value): for code in self.options['retest-codes'].value.strip().split(","): if len(code.strip()) and not re.match(r'^(\d+)$', code.strip()): raise WSException( "Retest code must be digital, but it is '{0}'".format( code.strip())) for proxies_params in ['proxies', 'http-proxies']: if proxies_params in self.options.keys() and len(self.options[proxies_params].value) and \ not os.path.exists(self.options[proxies_params].value): raise WSException("Proxy list not found: '{0}'".format( self.options[proxies_params].value)) if 'not-found-re' in self.options.keys() and len( self.options['not-found-re'].value): try: re.compile(self.options['not-found-re'].value) except re.error: raise WSException("Invalid regex: '{0}'".format( self.options['not-found-re'].value)) if 'browser-recreate-re' in self.options.keys() and len( self.options['browser-recreate-re'].value): try: re.compile(self.options['browser-recreate-re'].value) except re.error: raise WSException("Invalid regex: '{0}'".format( self.options['browser-recreate-re'].value)) if 'dict' in self.options.keys() and not os.path.exists( self.options['dict'].value): raise WSException( "Dictionary '{0}' not exists or not readable!".format( self.options['dict'].value)) if 'delay' in self.options.keys( ) and self.options['delay'].value != '0': if not re.match(r'^(\d+)$', self.options['delay'].value): raise WSException( "Delay param must be digital, but it is '{0}'".format( self.options['delay'].value.strip())) if 'parts' in self.options.keys( ) and self.options['parts'].value != '0': if not re.match(r'^(\d+)$', self.options['parts'].value): raise WSException( "Parts param must be digital, but it is '{0}'".format( self.options['parts'].value.strip())) if 'part' in self.options.keys() and self.options['part'].value != '0': if not re.match(r'^(\d+)$', self.options['part'].value): raise WSException( "Part param must be digital, but it is '{0}'".format( self.options['part'].value.strip())) if 'parts' in self.options.keys( ) and self.options['parts'].value != '0': if 'part' not in self.options.keys( ) or self.options['part'].value == '0': raise WSException( "If you use '--parts' param, you must specify '--part'") if int(self.options['part'].value) > int( self.options['parts'].value): raise WSException( "Number of part ({0}) more than parts count ({1})".format( self.options['part'].value.strip(), self.options['parts'].value.strip())) if 'part' in self.options.keys() and self.options['part'].value != '0': if 'parts' not in self.options.keys( ) or self.options['parts'].value == '0': raise WSException( "If you use '--part' param, you must specify '--parts'") if 'template' in self.options.keys( ) and 'msymbol' in self.options.keys(): if self.options['template'].value.find( self.options['msymbol'].value) == -1: raise WSException( "Symbol of object position ({0}) not found in template ({1}) " .format(self.options['msymbol'].value, self.options['template'].value)) if 'zone' in self.options.keys() and self.options['zone'].value.upper( ) not in self.POSSIBLE_DNS_ZONES: raise WSException("Wrong DNS zone - '{0}', allowed: {1}".format( self.options['zone'].value, ", ".join(self.POSSIBLE_DNS_ZONES))) if 'dns-protocol' in self.options.keys( ) and self.options['dns-protocol'].value not in ['tcp', 'udp', 'auto']: raise WSException( "DNS Protocol mast be 'tcp', 'udp' or 'auto', but it is '{0}'". format(self.options['dns-protocol'].value))
class SCmsThread(SeleniumThread): """ Thread class for CMS module (selenium) """ queue = None method = None url = None counter = None last_action = 0 def __init__( self, queue, domain, url, protocol, method, not_found_re, delay, ddos_phrase, ddos_human, recreate_re, counter, result ): super(SCmsThread, self).__init__() self.queue = queue self.method = method if not (len(not_found_re) and method.lower() == 'head') else 'get' self.domain = domain self.url = url self.result = result self.counter = counter self.protocol = protocol self.not_found_re = False if not len(not_found_re) else re.compile(not_found_re) self.done = False self.http = Registry().get('http') self.delay = int(delay) self.ddos_phrase = ddos_phrase self.ddos_human = ddos_human self.recreate_re = False if not len(recreate_re) else re.compile(recreate_re) self.logger = Registry().get('logger') Registry().set('url_for_proxy_check', url) self.browser_create() def run(self): """ Run thread """ need_retest = False while not self.done: self.last_action = int(time.time()) if self.delay: time.sleep(self.delay) try: path = self.queue.get() self.counter.up() try: url = "{0}://{1}{2}".format(self.protocol, self.domain, clear_double_slashes(self.url + path)) except UnicodeDecodeError: self.logger.log( "URL build error (UnicodeDecodeError) with path '{0}', skip it".format(pprint.pformat(path)), _print=False ) continue self.browser.get(url) if self.recreate_re and self.recreate_re.findall(self.browser.page_source): self.queue.put(path) self.browser_close() self.browser_create() continue if not self.not_found_re.findall(self.browser.page_source): self.result.append({ 'path': path, 'code': 0, }) self.logger.item( path, self.browser.page_source, True ) self.queue.task_done() except Queue.Empty: self.done = True break except TimeoutException as e: self.queue.put(path) self.browser_close() self.browser_create() continue except UnicodeDecodeError as e: self.logger.ex(e) self.queue.task_done() except BaseException as e: try: self.queue.put(path) if len(e.args) and e.args[0] == 111: self.browser_close() self.browser_create() elif not str(e).count('Timed out waiting for page load'): self.logger.ex(e) except UnicodeDecodeError: pass self.queue.task_done() self.up_requests_count() self.browser_close()
class WSModule(object): """ Kernel class of modules """ log_path = None log_width = 60 description = "module description" result = None done = False options = [] time_count = False logger = None logger_enable = False options_sets = {} action = None def __init__(self, kernel): self.kernel = kernel if self.log_path is None: raise WSException('Module must have log path!') def enable_logger(self): """ Turn on logger """ self.logger = Registry().get('logger') def pre_start_inf(self): """ Show options values before work start """ log_str = "" log_str += "---------------------------------\n" for option in self.options: log_str += "Option '{0}': {1}\n".format(option, self.options[option].value) log_str += "---------------------------------" print log_str if int(Registry().get('config')['main']['confirm']): tmp = raw_input("Do you have continue? [Y/n]") if len(tmp.strip()) and tmp.lower() != 'y': print "Aborted..." exit(0) self.logger.log(log_str + '\n', new_str=False, _print=False) def run(self, action): """ Run module """ getattr(self, action + "_action")() def help(self): """ Display module help """ pass def finished(self): """ Is module finished? """ return self.done def prepare(self, action): """ Prepare module for work """ if action not in self.options_sets: raise WSException( "Action '{0}' not exists! See help for actions list of this module." .format(action)) self.options = self.options_sets[action] self.action = action def validate_main(self): """ Common user params validate functions """ options = self.options_sets[self.action].keys() if 'selenium' in self.options.keys( ) and self.options['selenium'].value: if 'not-found-re' in options and not self.options[ 'not-found-re'].value: raise WSException( "Selenium enabled, module need a not found phrase (--not-found-re) for work!" ) if int(self.options['threads'].value) > int( Registry().get('config')['selenium']['max_threads']): raise WSException( "Selenium enabled, very many threads value ({0}), see docs." .format(self.options['threads'].value)) if 'protocol' in self.options.keys( ) and self.options['protocol'].value.lower() not in ['http', 'https']: raise WSException( "Protocol param must be 'http' or 'https', but have value '{0}' !" .format(self.options['protocol'].value)) if 'method' in self.options.keys( ) and self.options['method'].value.lower() not in [ 'head', 'get', 'post' ]: raise WSException( "Method param must be only 'head', 'get' or 'post', but have value '{0}' !" .format(self.options['method'].value)) if 'not-found-codes' in self.options.keys() and len( self.options['not-found-codes'].value): for code in self.options['not-found-codes'].value.strip().split( ","): if len(code.strip()) and not re.match(r'^(\d+)$', code.strip()): raise WSException( "Not-found code must be digital, but it is '{0}'". format(code.strip())) if 'retest-codes' in self.options.keys() and len( self.options['retest-codes'].value): for code in self.options['retest-codes'].value.strip().split(","): if len(code.strip()) and not re.match(r'^(\d+)$', code.strip()): raise WSException( "Retest code must be digital, but it is '{0}'".format( code.strip())) if 'proxies' in self.options.keys() and len(self.options['proxies'].value) and \ not os.path.exists(self.options['proxies'].value): raise WSException("Proxy list not found: '{0}'".format( self.options['proxies'].value)) if 'not-found-re' in self.options.keys() and len( self.options['not-found-re'].value): try: re.compile(self.options['not-found-re'].value) except re.error: raise WSException("Invalid regex: '{0}'".format( self.options['not-found-re'].value)) if 'browser-recreate-re' in self.options.keys() and len( self.options['browser-recreate-re'].value): try: re.compile(self.options['browser-recreate-re'].value) except re.error: raise WSException("Invalid regex: '{0}'".format( self.options['browser-recreate-re'].value)) if 'host' in self.options.keys() and \ not HostsModel().exists(Registry().get('pData')['id'], self.options['host'].value): raise WSException("Host '{0}' not found in this project!".format( self.options['host'].value)) if 'dict' in self.options.keys() and not os.path.exists( self.options['dict'].value): raise WSException( "Dictionary '{0}' not exists or not readable!".format( self.options['dict'].value)) if 'delay' in self.options.keys( ) and self.options['delay'].value != '0': if not re.match(r'^(\d+)$', self.options['delay'].value): raise WSException( "Delay param must be digital, but it is '{0}'".format( self.options['delay'].value.strip())) if 'parts' in self.options.keys( ) and self.options['parts'].value != '0': if not re.match(r'^(\d+)$', self.options['parts'].value): raise WSException( "Parts param must be digital, but it is '{0}'".format( self.options['parts'].value.strip())) if 'part' in self.options.keys() and self.options['part'].value != '0': if not re.match(r'^(\d+)$', self.options['part'].value): raise WSException( "Part param must be digital, but it is '{0}'".format( self.options['part'].value.strip())) if 'parts' in self.options.keys( ) and self.options['parts'].value != '0': if self.options['part'].value == '0': raise WSException( "If you use '--parts' param, you must specify '--part'") if int(self.options['part'].value) > int( self.options['parts'].value): raise WSException( "Number of part ({0}) more than parts count ({1})".format( self.options['part'].value.strip(), self.options['parts'].value.strip())) if 'part' in self.options.keys() and self.options['part'].value != '0': if self.options['parts'].value == '0': raise WSException( "If you use '--part' param, you must specify '--parts'")
class FormBruterThread(HttpThread): """ Thread class for FormBruter module """ queue = None method = None url = None mask_symbol = None counter = None last_action = 0 logger = None retested_words = None last_action = 0 def __init__( self, queue, protocol, host, url, false_phrase, true_phrase, retest_codes, delay, confstr, first_stop, login, pass_min_len, pass_max_len, pass_found, counter, result ): threading.Thread.__init__(self) self.retested_words = {} self.queue = queue self.protocol = protocol.lower() self.host = host self.url = url self.false_phrase = false_phrase self.true_phrase = true_phrase self.delay = int(delay) self.confstr = confstr self.first_stop = first_stop self.login = login self.counter = counter self.result = result self.retest_codes = list(set(retest_codes.split(','))) if len(retest_codes) else [] self.pass_found = pass_found self.done = False self.logger = Registry().get('logger') self.http = copy.deepcopy(Registry().get('http')) self.http.every_request_new_session = True self.pass_min_len = int(pass_min_len) self.pass_max_len = int(pass_max_len) self.retest_delay = int(Registry().get('config')['form_bruter']['retest_delay']) self.retest_limit = int(Registry().get('config')['form_bruter']['retest_limit']) def _make_conf_from_str(self, confstr): result = {} tmp = confstr.split("&") for tmp_row in tmp: field, value = tmp_row.split("=") result[field] = value return result def _fill_conf(self, conf, login, password): for field in conf.keys(): conf[field] = conf[field].replace("^USER^", login).replace("^PASS^", password) return conf def run(self): """ Run thread """ need_retest = False word = False conf = self._make_conf_from_str(self.confstr) while not self.pass_found and not self.done: try: self.last_action = int(time.time()) if self.pass_found: self.done = True break if self.delay: time.sleep(self.delay) if not need_retest: word = self.queue.get() self.counter.up() if (self.pass_min_len and len(word) < self.pass_min_len) or \ (self.pass_max_len and len(word) > self.pass_max_len): continue work_conf = self._fill_conf(dict(conf), self.login, word) try: resp = self.http.post( self.protocol + "://" + self.host + self.url, data=work_conf, allow_redirects=True ) except ConnectionError: need_retest = True self.http.change_proxy() continue if self.is_retest_need(word, resp): time.sleep(self.retest_delay) need_retest = True continue positive_item = False if (len(self.false_phrase) and not resp.content.count(self.false_phrase)) or \ (len(self.true_phrase) and resp.content.count(self.true_phrase)): self.result.append({'word': word, 'content': resp.content}) positive_item = True self.check_positive_limit_stop(self.result) self.log_item(word, resp, positive_item) if positive_item and int(self.first_stop): self.done = True self.pass_found = True break need_retest = False except Queue.Empty: self.done = True break except ChunkedEncodingError as e: self.logger.ex(e) except BaseException as e: try: if str(e).count('Cannot connect to proxy'): need_retest = True else: self.logger.log(str(word) + " " + str(e)) except UnicodeDecodeError: pass except UnboundLocalError: self.logger.ex(e) finally: pass
class WSModule(object): """ Kernel class of modules """ log_path = None log_width = 60 description = "module description" result = None done = False options = [] time_count = False logger = None logger_enable = False options_sets = {} action = None def __init__(self, kernel): self.kernel = kernel if self.log_path is None: raise WSException('Module must have log path!') def enable_logger(self): """ Turn on logger """ self.logger = Registry().get('logger') def pre_start_inf(self): """ Show options values before work start """ log_str = "" log_str += "---------------------------------\n" for option in self.options: log_str += "Option '{0}': {1}\n".format(option, self.options[option].value) log_str += "---------------------------------" print log_str if int(Registry().get('config')['main']['confirm']): tmp = raw_input("Do you have continue? [Y/n]") if len(tmp.strip()) and tmp.lower() != 'y': print "Aborted..." exit(0) self.logger.log(log_str + '\n', new_str=False, _print=False) def run(self, action): """ Run module """ getattr(self, action + "_action")() def help(self): """ Display module help """ pass def finished(self): """ Is module finished? """ return self.done def prepare(self, action): """ Prepare module for work """ if action not in self.options_sets: raise WSException("Action '{0}' not exists! See help for actions list of this module.".format(action)) self.options = self.options_sets[action] self.action = action def validate_main(self): """ Common user params validate functions """ options = self.options_sets[self.action].keys() if 'selenium' in self.options.keys() and self.options['selenium'].value: if 'not-found-re' in options and not self.options['not-found-re'].value: raise WSException("Selenium enabled, module need a not found phrase (--not-found-re) for work!") if int(self.options['threads'].value) > int(Registry().get('config')['selenium']['max_threads']): raise WSException( "Selenium enabled, very many threads value ({0}), see docs.".format(self.options['threads'].value) ) if 'protocol' in self.options.keys() and self.options['protocol'].value.lower() not in ['http', 'https']: raise WSException( "Protocol param must be 'http' or 'https', but have value '{0}' !". format(self.options['protocol'].value) ) if 'method' in self.options.keys() and self.options['method'].value.lower() not in ['head', 'get', 'post']: raise WSException( "Method param must be only 'head', 'get' or 'post', but have value '{0}' !". format(self.options['method'].value) ) if 'not-found-codes' in self.options.keys() and len(self.options['not-found-codes'].value): for code in self.options['not-found-codes'].value.strip().split(","): if len(code.strip()) and not re.match(r'^(\d+)$', code.strip()): raise WSException( "Not-found code must be digital, but it is '{0}'". format(code.strip()) ) if 'retest-codes' in self.options.keys() and len(self.options['retest-codes'].value): for code in self.options['retest-codes'].value.strip().split(","): if len(code.strip()) and not re.match(r'^(\d+)$', code.strip()): raise WSException( "Retest code must be digital, but it is '{0}'". format(code.strip()) ) if 'proxies' in self.options.keys() and len(self.options['proxies'].value) and \ not os.path.exists(self.options['proxies'].value): raise WSException( "Proxy list not found: '{0}'". format(self.options['proxies'].value) ) if 'not-found-re' in self.options.keys() and len(self.options['not-found-re'].value): try: re.compile(self.options['not-found-re'].value) except re.error: raise WSException( "Invalid regex: '{0}'". format(self.options['not-found-re'].value) ) if 'browser-recreate-re' in self.options.keys() and len(self.options['browser-recreate-re'].value): try: re.compile(self.options['browser-recreate-re'].value) except re.error: raise WSException( "Invalid regex: '{0}'". format(self.options['browser-recreate-re'].value) ) if 'host' in self.options.keys() and \ not HostsModel().exists(Registry().get('pData')['id'], self.options['host'].value): raise WSException("Host '{0}' not found in this project!".format(self.options['host'].value)) if 'dict' in self.options.keys() and not os.path.exists(self.options['dict'].value): raise WSException("Dictionary '{0}' not exists or not readable!".format(self.options['dict'].value)) if 'delay' in self.options.keys() and self.options['delay'].value != '0': if not re.match(r'^(\d+)$', self.options['delay'].value): raise WSException( "Delay param must be digital, but it is '{0}'". format(self.options['delay'].value.strip()) ) if 'parts' in self.options.keys() and self.options['parts'].value != '0': if not re.match(r'^(\d+)$', self.options['parts'].value): raise WSException( "Parts param must be digital, but it is '{0}'". format(self.options['parts'].value.strip()) ) if 'part' in self.options.keys() and self.options['part'].value != '0': if not re.match(r'^(\d+)$', self.options['part'].value): raise WSException( "Part param must be digital, but it is '{0}'". format(self.options['part'].value.strip()) ) if 'parts' in self.options.keys() and self.options['parts'].value != '0': if self.options['part'].value == '0': raise WSException( "If you use '--parts' param, you must specify '--part'" ) if int(self.options['part'].value) > int(self.options['parts'].value): raise WSException( "Number of part ({0}) more than parts count ({1})". format(self.options['part'].value.strip(), self.options['parts'].value.strip()) ) if 'part' in self.options.keys() and self.options['part'].value != '0': if self.options['parts'].value == '0': raise WSException( "If you use '--part' param, you must specify '--parts'" )
class DafsThread(threading.Thread): """ Thread class for Dafs modules """ queue = None method = None url = None mask_symbol = None counter = None retested_words = None last_action = 0 retest_limit = int(Registry().get('config')['dafs']['retest_limit']) def __init__( self, queue, protocol, host, url, method, mask_symbol, not_found_re, not_found_codes, retest_codes, delay, counter, result): threading.Thread.__init__(self) self.retested_words = {} self.queue = queue self.protocol = protocol.lower() self.host = host self.method = method if not (len(not_found_re) and method.lower() == 'head') else 'get' self.url = url self.mask_symbol = mask_symbol self.counter = counter self.result = result self.done = False self.not_found_re = False if not len(not_found_re) else re.compile(not_found_re) not_found_codes = not_found_codes.split(',') not_found_codes.append('404') self.not_found_codes = list(set(not_found_codes)) self.retest_codes = list(set(retest_codes.split(','))) if len(retest_codes) else [] self.delay = int(delay) self.http = copy.deepcopy(Registry().get('http')) self.logger = Registry().get('logger') def run(self): """ Run thread """ req_func = getattr(self.http, self.method) need_retest = False word = False while not self.done: self.last_action = int(time.time()) if self.delay: time.sleep(self.delay) try: if not need_retest: word = self.queue.get() self.counter.up() try: url = self.url.replace(self.mask_symbol, word) except UnicodeDecodeError: self.logger.log( "URL build error (UnicodeDecodeError) with word '{0}', skip it".format(pprint.pformat(word)), _print=False ) continue rtime = int(time.time()) try: resp = req_func(self.protocol + "://" + self.host + url) except ConnectionError: need_retest = True self.http.change_proxy() continue binary_content = resp is not None \ and 'content-type' in resp.headers \ and is_binary_content_type(resp.headers['content-type']) if resp is not None and len(self.retest_codes) and str(resp.status_code) in self.retest_codes: if word not in self.retested_words.keys(): self.retested_words[word] = 0 self.retested_words[word] += 1 if self.retested_words[word] <= self.retest_limit: need_retest = True time.sleep(int(Registry().get('config')['dafs']['retest_delay'])) continue if resp is not None \ and str(resp.status_code) not in self.not_found_codes \ and not (not binary_content and self.not_found_re and self.not_found_re.findall(resp.content)): self.result.append({ 'url': url, 'code': resp.status_code, 'time': int(time.time()) - rtime }) self.logger.item(word, resp.content if not resp is None else "", binary_content) if len(self.result) >= int(Registry().get('config')['main']['positive_limit_stop']): Registry().set('positive_limit_stop', True) need_retest = False except Queue.Empty: self.done = True break except ChunkedEncodingError as e: self.logger.ex(e) except BaseException as e: try: if str(e).count('Cannot connect to proxy'): need_retest = True else: self.logger.ex(e) except UnicodeDecodeError: pass except UnboundLocalError: self.logger.ex(e) finally: pass
class DnsBruteThread(threading.Thread): """ Thread class for DnsBrute* modules """ done = False def __init__(self, queue, domains, template, proto, msymbol, ignore_ip, dns_srv, delay, http_nf_re, ignore_words_re, result, counter): threading.Thread.__init__(self) self.queue = queue self.domains = domains self.proto = proto self.dns_srv = dns_srv self.counter = counter self.msymbol = msymbol self.template = template self.result = result self.delay = int(delay) self.done = False self.logger = Registry().get('logger') self.ignore_ip = ignore_ip self.http_nf_re = re.compile(http_nf_re) if len(http_nf_re) else None self.ignore_words_re = False if not len(ignore_words_re) else re.compile(ignore_words_re) def run(self): """ Run thread """ ip_re = re.compile(r"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})") ns_resp_re = re.compile(r";ANSWER\s(?P<data>(.|\s)*)\s;AUTHORITY", re.M) req_func = getattr(dns.query, self.proto.lower()) need_retest = False while True: if self.delay: time.sleep(self.delay) try: if not need_retest: host = self.queue.get() if not len(host.strip()) or (self.ignore_words_re and self.ignore_words_re.findall(host)): continue self.counter.up() for domain in self.domains: check_name = self.template.replace(self.msymbol, host.decode('utf8', 'ignore')) + '.' + domain query = dns.message.make_query(check_name, 'A') try: result = req_func(query, self.dns_srv, timeout=5) except EOFError: time.sleep(3) need_retest = True break except BaseException as e: if str(e).count("Connection refused") or\ str(e).count("Connection reset by peer") or\ str(e).count("[Errno 104]"): time.sleep(3) need_retest = True break else: raise e response = ns_resp_re.search(result.to_text()) if response is not None: for ip in ip_re.findall(response.group('data')): if not len(self.ignore_ip) or ip != self.ignore_ip: if self.http_nf_re is not None: resp = Registry().get('http').get( "http://{0}/".format(ip), headers={'Host': check_name}, allow_redirects=False) if not self.http_nf_re.findall(resp.text): self.result.append({'name': check_name, 'ip': ip, 'dns': self.dns_srv}) else: resp = Registry().get('http').get( "https://{0}/".format(ip), headers={'Host': check_name}, allow_redirects=False, verify=False) if not self.http_nf_re.findall(resp.text): self.result.append({'name': check_name, 'ip': ip, 'dns': self.dns_srv}) else: self.result.append({'name': check_name, 'ip': ip, 'dns': self.dns_srv}) break if len(self.result) >= int(Registry().get('config')['main']['positive_limit_stop']): Registry().set('positive_limit_stop', True) need_retest = False except Queue.Empty: self.done = True break except dns.exception.Timeout: need_retest = True time.sleep(1) except BaseException as e: self.logger.ex(e) self.logger.log("Exception with {0}".format(self.dns_srv)) time.sleep(5)
class SDafsThread(SeleniumThread): """ Thread class for Dafs modules (selenium) """ queue = None method = None template = None mask_symbol = None counter = None last_action = 0 def __init__( self, queue, protocol, host, template, method, mask_symbol, not_found_re, delay, ddos_phrase, ddos_human, recreate_re, ignore_words_re, counter, result ): super(SDafsThread, self).__init__() self.queue = queue self.protocol = protocol.lower() self.host = host self.method = method if not (len(not_found_re) and method.lower() == 'head') else 'get' self.template = template self.mask_symbol = mask_symbol self.counter = counter self.result = result self.done = False self.not_found_re = False if not len(not_found_re) else re.compile(not_found_re) self.recreate_re = False if not len(recreate_re) else re.compile(recreate_re) self.http = Registry().get('http') self.delay = int(delay) self.ddos_phrase = ddos_phrase self.ddos_human = ddos_human self.ignore_words_re = False if not len(ignore_words_re) else re.compile(ignore_words_re) Registry().set('url_for_proxy_check', "{0}://{1}".format(protocol, host)) self.browser_create() self.logger = Registry().get('logger') def run(self): """ Run thread """ need_retest = False word = None while not self.done: self.last_action = int(time.time()) if self.delay: time.sleep(self.delay) try: if not need_retest: word = self.queue.get() if not len(word.strip()) or (self.ignore_words_re and self.ignore_words_re.findall(word)): continue self.counter.up() try: url = self.template.replace(self.mask_symbol, word) except UnicodeDecodeError: self.logger.log( "URL build error (UnicodeDecodeError) with word '{0}', skip it".format(pprint.pformat(word)), _print=False ) continue rtime = int(time.time()) self.browser.get(self.protocol + "://" + self.host + url) if self.recreate_re and self.recreate_re.findall(self.browser.page_source): need_retest = True self.browser_close() self.browser_create() continue positive_item = False if not self.not_found_re.findall(self.browser.page_source): self.result.append({ 'url': url, 'code': 0, 'time': int(time.time()) - rtime }) positive_item = True self.logger.item(word, self.browser.page_source, False, positive_item) if len(self.result) >= int(Registry().get('config')['main']['positive_limit_stop']): Registry().set('positive_limit_stop', True) need_retest = False except Queue.Empty: self.done = True break except UnicodeDecodeError as e: self.logger.ex(e) need_retest = False except TimeoutException as e: need_retest = True self.browser_close() self.browser_create() continue except BaseException as e: try: need_retest = True if len(e.args) and e.args[0] == 111: self.browser_close() self.browser_create() elif not str(e).count('Timed out waiting for page load'): self.logger.ex(e) except UnicodeDecodeError: need_retest = False self.up_requests_count() self.browser_close()
class FormBruterThread(threading.Thread): """ Thread class for FormBruter module """ queue = None method = None url = None mask_symbol = None counter = None last_action = 0 logger = None retested_words = None last_action = 0 retest_limit = int(Registry().get('config')['dafs']['retest_limit']) def __init__(self, queue, protocol, host, url, false_phrase, true_phrase, retest_codes, delay, confstr, first_stop, login, pass_found, counter, result): threading.Thread.__init__(self) self.retested_words = {} self.queue = queue self.protocol = protocol.lower() self.host = host self.url = url self.false_phrase = false_phrase self.true_phrase = true_phrase self.delay = int(delay) self.confstr = confstr self.first_stop = first_stop self.login = login self.counter = counter self.result = result self.retest_codes = list(set( retest_codes.split(','))) if len(retest_codes) else [] self.pass_found = pass_found self.done = False self.logger = Registry().get('logger') self.http = copy.deepcopy(Registry().get('http')) self.http.every_request_new_session = True def _make_conf_from_str(self, confstr): result = {} tmp = confstr.split("&") for tmp_row in tmp: field, value = tmp_row.split("=") result[field] = value return result def _fill_conf(self, conf, login, password): for field in conf.keys(): conf[field] = conf[field].replace("^USER^", login).replace( "^PASS^", password) return conf def run(self): """ Run thread """ need_retest = False word = False conf = self._make_conf_from_str(self.confstr) while not self.pass_found and not self.done: try: self.last_action = int(time.time()) if self.pass_found: self.done = True break if self.delay: time.sleep(self.delay) if not need_retest: word = self.queue.get() self.counter.up() work_conf = self._fill_conf(dict(conf), self.login, word) try: resp = self.http.post(self.protocol + "://" + self.host + self.url, data=work_conf, allow_redirects=True) except ConnectionError: need_retest = True self.http.change_proxy() continue if resp is not None and len(self.retest_codes) and str( resp.status_code) in self.retest_codes: if word not in self.retested_words.keys(): self.retested_words[word] = 0 self.retested_words[word] += 1 if self.retested_words[word] <= self.retest_limit: need_retest = True time.sleep( int(Registry().get('config')['dafs'] ['retest_delay'])) continue self.logger.item(word, resp.content if not resp is None else "") if (len(self.false_phrase) and not resp.content.count(self.false_phrase)) or \ (len(self.true_phrase) and resp.content.count(self.true_phrase)): self.result.append({'word': word, 'content': resp.content}) #self.logger.log("Result: {0}".format(word)) if len(self.result) >= int(Registry().get('config')['main'] ['positive_limit_stop']): Registry().set('positive_limit_stop', True) if int(self.first_stop): self.done = True self.pass_found = True break need_retest = False except Queue.Empty: self.done = True break except ChunkedEncodingError: self.logger.ex(e) except BaseException as e: try: if str(e).count('Cannot connect to proxy'): need_retest = True else: self.logger.log(str(word) + " " + str(e)) except UnicodeDecodeError: pass except UnboundLocalError: self.logger.ex(e) finally: pass