def __run_attacks( url, sqlmap=False, nmap=False, intel=False, xss=False, verbose=False, admin=False, given_path=None, auto=False, batch=False ): """ run the attacks if any are requested """ if not batch: question = prompt( "would you like to process found URL: '{}'".format(url), opts=["y", "N"] ) else: question = "y" if question.lower().startswith("y"): if sqlmap: return sqlmap_scan.sqlmap_scan_main(url.strip(), verbose=verbose, opts=__create_arguments(sqlmap=True), auto_search=auto, given_path=given_path) elif nmap: url_ip_address = replace_http(url.strip()) return nmap_scan.perform_port_scan(url_ip_address, verbose=verbose, opts=__create_arguments(nmap=True)) elif intel: url = get_true_url(url) return intel_me.main_intel_amt(url, agent=agent_to_use, proxy=proxy_to_use) elif admin: main(url, show=opt.showAllConnections, verbose=verbose) elif xss: main_xss(url, verbose=verbose, proxy=proxy_to_use, agent=agent_to_use, tamper=opt.tamperXssPayloads) else: pass else: logger.warning(set_color( "skipping '{}'...".format(url), level=30 ))
def __run_attacks(url, sqlmap=False, verbose=False, nmap=False, given_path=None, auto=False, batch=False): """ run the attacks if any are requested """ if not batch: question = prompt( "would you like to process found URL: '{}'".format(url), opts=["y", "N"]) else: question = "y" if question.lower().startswith("y"): if sqlmap: return sqlmap_scan.sqlmap_scan_main( url.strip(), verbose=verbose, opts=__create_sqlmap_arguments(), auto_search=auto, given_path=given_path) elif nmap: url_ip_address = replace_http(url.strip()) return nmap_scan.perform_port_scan(url_ip_address, verbose=verbose) else: pass else: logger.warning(set_color("skipping '{}'...".format(url)))
def __run_attacks( url, sqlmap=False, nmap=False, intel=False, xss=False, verbose=False, admin=False, given_path=None, auto=False, batch=False ): """ run the attacks if any are requested """ __enabled_attacks = { "sqlmap": opt.runSqliScan, "port": opt.runPortScan, "xss": opt.runXssScan, "admin": opt.adminPanelFinder, "intel": opt.intelCheck } enabled = set() for key in __enabled_attacks.keys(): if __enabled_attacks[key] is True: enabled.add(key) if len(enabled) > 1: logger.error(set_color( "it appears that you have enabled multiple attack types, " "as of now only 1 attack is supported at a time, choose " "your attack and try again. You can use the -f flag if " "you do not want to complete an entire search again...", level=40 )) shutdown() if not batch: question = prompt( "would you like to process found URL: '{}'".format(url), opts=["y", "N"] ) else: question = "y" if question.lower().startswith("y"): if sqlmap: return sqlmap_scan.sqlmap_scan_main(url.strip(), verbose=verbose, opts=__create_arguments(sqlmap=True), auto_search=auto, given_path=given_path) elif nmap: url_ip_address = replace_http(url.strip()) return nmap_scan.perform_port_scan(url_ip_address, verbose=verbose, opts=__create_arguments(nmap=True)) elif intel: url = get_true_url(url) return intel_me.main_intel_amt(url, agent=agent_to_use, proxy=proxy_to_use) elif admin: main(url, show=opt.showAllConnections, verbose=verbose) elif xss: main_xss(url, verbose=verbose, proxy=proxy_to_use, agent=agent_to_use, tamper=opt.tamperXssPayloads) else: pass else: logger.warning(set_color( "skipping '{}'...".format(url), level=30 ))
def create_wordlist(warning=True, verbose=False, add=False): """ Create a bruteforcing wordlist > :param max_length: max amount of words to have > :param max_word_length: how long the words should be > :param warning: output the warning message to say that BF'ing sucks > :return: a wordlist """ max_length, max_word_length, dirname = 10000000, 10, "bf-dicts" if add: max_word_length += 2 warn_msg = ( "It is highly advised to use a dictionary attack over bruteforce. " "Bruteforce requires extreme amounts of memory to accomplish and " "it is possible that it could take a lifetime to successfully " "crack your hash. To run a dictionary attack all you need to do is" " pass the wordlist switch ('-w/--wordlist PATH') with the path to " "your wordlist. (IE: --bruteforce -w ~/dicts/dict.txt)") if warning: LOGGER.warning(warn_msg) if verbose: LOGGER.debug( "Creating {} words with a max length of {} characters".format( max_length, max_word_length)) create_dir(dirname, verbose=verbose) with open(dirname + "/" + WORDLIST_NAME, "a+") as lib: word = Generators().word_generator(length_max=max_word_length) lib.seek(0, 0) line_count = len(lib.readlines()) try: for _ in range(line_count, max_length): lib.write(next(word) + "\n") except StopIteration: # SHOULD NEVER GET HERE # if we run out of mutations we'll retry with a different word length lib.seek(0, 0) err_msg = ( "Ran out of mutations at {} mutations. You can try upping " "the max length or just use what was processed. If you " "make the choice not to continue the program will add +2 " "to the max length and try to create the wordlist again.." ).format(len(lib.readlines())) LOGGER.error(err_msg) q = prompt("Would you like to continue", "y/N") if not q.startswith(("y", "Y")): lib.truncate(0) create_wordlist(warning=False, add=True) LOGGER.info( "Wordlist generated, words saved to: {}. Please re-run the application, exiting.." .format(WORDLIST_NAME)) shutdown()
def create_wordlist(max_length=10000000, max_word_length=10, warning=True, perms=""): """ Create a bruteforcing wordlist > :param max_length: max amount of words to have > :param max_word_length: how long the words should be > :param warning: output the warning message to say that BF'ing sucks > :return: a wordlist """ warn_msg = "It is highly advised to use a dictionary attack over bruteforce. " warn_msg += "Bruteforce requires extreme amounts of memory to accomplish and " warn_msg += "it is possible that it could take a lifetime to successfully crack " warn_msg += "your hash. To run a dictionary attack all you need to do is pass " warn_msg += "the wordlist switch ('--wordlist PATH') with the path to your wordlist. " warn_msg += "(IE: --bruteforce --wordlist ~/dicts/dict.txt)" if warning is True: LOGGER.warning(warn_msg) with open(WORDLIST_NAME, "a+") as lib: word = word_generator(length_max=max_word_length, perms=perms) lib.seek(0, 0) line_count = len(lib.readlines()) try: for _ in range(line_count, max_length): lib.write(next(word) + "\n") except StopIteration: # if we run out of mutations we'll retry with a different word length lib.seek(0, 0) err_msg = "Ran out of mutations at {} mutations. You can try upping the max length ".format( len(lib.readlines())) err_msg += "or just use what was processed. If you make the choice not to continue " err_msg += "the program will add +2 to the max length and try to create the wordlist again.." LOGGER.error(err_msg) q = prompt("Would you like to continue", "y/N") if q.lower().startswith("y"): pass else: lib.truncate(0) create_wordlist(max_word_length=max_length + 2, warning=False) LOGGER.info( "Wordlist generated, words saved to: {}. Please re-run the application, exiting.." .format(WORDLIST_NAME)) shutdown()
def bruteforce_main(verf_hash, algorithm=None, wordlist=None, salt=None, placement=None, all_algs=False): """ Main function to be used for bruteforcing a hash """ wordlist_created = False if wordlist is None: for item in os.listdir(os.getcwd()): if WORDLIST_RE.match(item): wordlist_created = True wordlist = item if wordlist_created is True: pass else: LOGGER.info("Creating wordlist..") create_wordlist() else: LOGGER.info("Reading from, {}..".format(wordlist)) if algorithm is None: hash_type = verify_hash_type(verf_hash, least_likely=all_algs) LOGGER.info("Found {} possible hash types to run against {} ".format(len(hash_type), hash_type)) for alg in hash_type: LOGGER.info("Starting bruteforce with {}..".format(alg.upper())) bruteforcing = hash_words(verf_hash, wordlist, alg, salt=salt, placement=placement) if bruteforcing is None: LOGGER.warning("Unable to find a match for '{}', using {}..".format(verf_hash, alg.upper())) else: match_found(bruteforcing) break else: LOGGER.info("Using algorithm, {}..".format(algorithm.upper())) results = hash_words(verf_hash, wordlist, algorithm, salt=salt, placement=placement) if results is None: LOGGER.warning("Unable to find a match using {}..".format(algorithm.upper())) verifiy = prompt("Would you like to attempt to verify the hash type automatically and crack it", "y/N") if verifiy.lower().startswith("y"): bruteforce_main(verf_hash, wordlist=wordlist, salt=salt, placement=placement) else: LOGGER.warning("Unable to produce a result for given hash '{}' using {}.. Exiting..".format( verf_hash, algorithm.upper())) else: match_found(results)
def request_issue_creation(): question = prompt( "would you like to create an anonymous issue and post it to Zeus's Github", opts="yN") if question.lower().startswith("n"): logger.error( set_color( "Zeus has experienced an internal error and cannot continue, shutting down...", level=40)) shutdown() fix_log_file() logger.info( set_color( "Zeus got an unexpected error and will automatically create an issue for this error, please wait..." )) def __extract_stacktrace(file_data): logger.info(set_color("extracting traceback from log file...")) retval, buff_mode, _buffer = [], False, "" with open(file_data, "r+") as log: for line in log: if "Traceback" in line: buff_mode = True if line and len(line) < 5: buff_mode = False retval.append(_buffer) _buffer = "" if buff_mode: if len(line) > 400: line = line[:400] + "...\n" _buffer += line return "".join(retval) logger.info(set_color("getting authorization...")) encoded = __get_encoded_string() n = get_decode_num(encoded) token = decode(n, encoded) current_log_file = get_latest_log_file(CURRENT_LOG_FILE_PATH) stacktrace = __extract_stacktrace(current_log_file) issue_title = stacktrace.split("\n")[-2] issue_data = { "title": issue_title, "body": "Zeus version:\n`{}`\n\n" "Error info:\n```{}````\n\n" "Running details:\n`{}`\n\n" "Commands used:\n`{}`\n\n" "Log file info:\n```{}```".format(VERSION, str(stacktrace), str(platform.platform()), " ".join(sys.argv), open(current_log_file).read()), } _json_data = json.dumps(issue_data) if sys.version_info > (3, ): _json_data = _json_data.encode("utf-8") try: req = urllib2.Request( url="https://api.github.com/repos/ekultek/zeus-scanner/issues", data=_json_data, headers={"Authorization": "token {}".format(token)}) urllib2.urlopen(req, timeout=10).read() logger.info( set_color( "issue has been created successfully with the following name '{}'..." .format(issue_title))) except Exception as e: logger.exception( set_color("failed to auto create the issue, got exception '{}', " "you may manually create an issue...".format(e), level=50))
elif opt.spiderWebSite: if not URL_REGEX.match(opt.spiderWebSite): err_msg = "URL did not match a true URL{}..." if "www" in opt.spiderWebSite: err_msg = err_msg.format(" issue seems to be that 'www' is in the URL, " "replace with http(s)://") else: err_msg = err_msg.format("") raise InvalidInputProvided( err_msg ) else: if URL_QUERY_REGEX.match(opt.spiderWebSite): is_sure = prompt( "it is recomened to not use a URL that has a GET(query) parameter in it, " "would you like to continue", "yN" ) if is_sure.lower().startswith("y"): pass else: shutdown() blackwidow.blackwidow_main(opt.spiderWebSite, agent=agent_to_use, proxy=proxy_to_use, verbose=opt.runInVerbose) urls_to_use = get_latest_log_file(SPIDER_LOG_PATH) if opt.runSqliScan or opt.runPortScan or opt.intelCheck or opt.adminPanelFinder or opt.runXssScan: with open(urls_to_use) as urls: for url in urls.readlines(): __run_attacks( url.strip(),
algorithm=opt.algToUse, wordlist=opt.wordListToUse, salt=salt, placement=placement) except Exception as e: LOGGER.fatal("{} failed with error code: '{}'".format( os.path.basename(__file__), e)) # Bruteforce a list of hashes elif opt.bruteforceCrack is True and opt.hashListToCrack is not None and opt.hashToCrack is None: try: with open(opt.hashListToCrack) as hashes: for i, hash_to_crack in enumerate( hashes.readlines(), start=1): crack_or_not = prompt( "Attempt to crack: '{}'".format( hash_to_crack.strip()), "y/N") if crack_or_not.lower().startswith("y"): LOGGER.info( "Cracking hash number {}..".format(i)) bruteforce_main(hash_to_crack.strip(), algorithm=opt.algToUse, wordlist=opt.wordListToUse, salt=salt, placement=placement) print("\n") except Exception as e: LOGGER.fatal( "Failed with error code: {}. Check the file and try again.." .format(e))
if opt.showCurrentVersion: print(VERSION_STRING) exit(0) # run the setup on the program setup(verbose=opt.runInVerbose) if not opt.hideBanner: print(BANNER) start_up() if opt.runSqliScan: prompt( "make sure you have started the sqlmap API, press enter when ready to continue..." ) if opt.showSqlmapArguments: logger.info(set_color( "there are a total of {} arguments understood by sqlmap API, " "they include:".format(len(SQLMAP_API_OPTIONS)) )) print("\n") for arg in SQLMAP_API_OPTIONS: print( "[*] {}".format(arg) ) print("\n") logger.info(set_color( "for more information about sqlmap arguments, see here '{}'...".format(
def main_xss(start_url, verbose=False, proxy=None, agent=None, tamper=None): if tamper: logger.info(set_color( "tampering payloads with '{}'...".format(tamper) )) find_xss_script(start_url) logger.info(set_color( "loading payloads..." )) payloads = __load_payloads() if verbose: logger.debug(set_color( "a total of {} payloads loaded...".format(len(payloads)), level=10 )) logger.info(set_color( "payloads will be written to a temporary file and read from there..." )) filename = create_urls(start_url, payloads, tamper=tamper) logger.info(set_color( "loaded URL's have been saved to '{}'...".format(filename) )) logger.info(set_color( "testing for XSS vulnerabilities on host '{}'...".format(start_url) )) if proxy is not None: logger.info(set_color( "using proxy '{}'...".format(proxy) )) success = set() with open(filename) as urls: for i, url in enumerate(urls.readlines(), start=1): url = url.strip() result = scan_xss(url, proxy=proxy, agent=agent) payload = find_xss_script(url) if verbose: logger.info(set_color( "trying payload '{}'...".format(payload) )) if result[0] != "sqli" and result[0] is True: success.add(url) if verbose: logger.debug(set_color( "payload '{}' appears to be usable...".format(payload), level=10 )) elif result[0] is "sqli": if i <= 1: logger.error(set_color( "loaded URL '{}' threw a DBMS error and appears to be injectable, test for SQL injection, " "backend DBMS appears to be '{}'...".format( url, result[1] ), level=40 )) else: if verbose: logger.error(set_color( "SQL error discovered...", level=40 )) else: if verbose: logger.debug(set_color( "host '{}' does not appear to be vulnerable to XSS attacks with payload '{}'...".format( start_url, payload ), level=10 )) if len(success) != 0: logger.info(set_color( "possible XSS scripts to be used:" )) create_tree(start_url, list(success)) else: logger.error(set_color( "host '{}' does not appear to be vulnerable to XSS attacks...".format(start_url) )) save = prompt( "would you like to keep the URL's saved for further testing", opts="yN" ) if save.lower().startswith("n"): os.remove(filename)
def bruteforce_main(verf_hash, algorithm=None, wordlist=None, salt=None, placement=None, all_algs=False, posx="", use_hex=False, verbose=False, batch=False, rounds=10): """ Main function to be used for bruteforcing a hash """ wordlist_created = False if wordlist is None: create_dir("bf-dicts", verbose=verbose) for item in os.listdir(os.getcwd() + "/bf-dicts"): if WORDLIST_RE.match(item): wordlist_created = True wordlist = "{}/bf-dicts/{}".format(os.getcwd(), item) if not wordlist_created: LOGGER.info("Creating wordlist..") create_wordlist(verbose=verbose) else: LOGGER.info("Reading from, {}..".format(wordlist)) if algorithm is None: hash_type = verify_hash_type(verf_hash, least_likely=all_algs) LOGGER.info( "Found {} possible hash type(s) to run against: {} ".format( len(hash_type) - 1 if hash_type[1] is None else len(hash_type), hash_type[0] if hash_type[1] is None else hash_type)) for alg in hash_type: if alg is None: err_msg = ( "Ran out of algorithms to try. There are no more " "algorithms currently available that match this hashes " "length, and complexity.") LOGGER.fatal(err_msg.format(DAGON_ISSUE_LINK)) break else: if ":::" in verf_hash: LOGGER.debug( "It appears that you are trying to crack an '{}' hash, " "these hashes have a certain sequence to them that looks " "like this 'USERNAME:SID:LM_HASH:NTLM_HASH:::'. What you're " "wanting is the NTLM part, of the hash, fix your hash and try " "again..".format(alg.upper())) shutdown(1) LOGGER.info("Starting bruteforce with {}..".format( alg.upper())) bruteforcing = hash_words(verf_hash, wordlist, alg, salt=salt, placement=placement, posx=posx, use_hex=use_hex, verbose=verbose, rounds=rounds) if bruteforcing is None: LOGGER.warning( "Unable to find a match for '{}', using {}..".format( verf_hash, alg.upper())) else: match_found(bruteforcing) break else: LOGGER.info("Using algorithm, {}..".format(algorithm.upper())) results = hash_words(verf_hash, wordlist, algorithm, salt=salt, placement=placement, posx=posx, verbose=verbose) if results is None: LOGGER.warning("Unable to find a match using {}..".format( algorithm.upper())) if not batch: verify = prompt( "Would you like to attempt to verify the hash type automatically and crack it", "y/N") else: verify = "n" if verify.startswith(("y", "Y")): bruteforce_main(verf_hash, wordlist=wordlist, salt=salt, placement=placement, posx=posx, use_hex=use_hex, verbose=verbose) else: LOGGER.warning( "Unable to produce a result for given hash '{}' using {}.." .format(verf_hash, algorithm.upper())) else: match_found(results)
def bruteforce_main(verf_hash, algorithm=None, wordlist=None, salt=None, placement=None, all_algs=False, perms="", posx="", use_hex=False): """ Main function to be used for bruteforcing a hash """ wordlist_created = False if wordlist is None: for item in os.listdir(os.getcwd()): if WORDLIST_RE.match(item): wordlist_created = True wordlist = item if wordlist_created is True: pass else: LOGGER.info("Creating wordlist..") create_wordlist(perms=perms) else: LOGGER.info("Reading from, {}..".format(wordlist)) if algorithm is None: hash_type = verify_hash_type(verf_hash, least_likely=all_algs) LOGGER.info("Found {} possible hash types to run against: {} ".format( len(hash_type) - 1 if hash_type[1] is None else len(hash_type), hash_type[0] if hash_type[1] is None else hash_type)) for alg in hash_type: if alg is None: err_msg = "Ran out of algorithms to try. There are no more algorithms " err_msg += "currently available that match this hashes length, and complexity. " err_msg += "Please attempt to use your own wordlist (switch '--wordlist'), " err_msg += "download one (switch '--download'), use salt (switch '-S SALT'), " err_msg += "or find the algorithm type and create a issue here {}.. " LOGGER.fatal(err_msg.format(DAGON_ISSUE_LINK)) break else: if ":" in verf_hash: LOGGER.debug( "It appears that you are trying to crack an '{}' hash, " "these hashes have a certain sequence to them that looks " "like this 'USERNAME:SID:LM_HASH:NTLM_HASH:::'. What you're " "wanting is the NTLM part, of the hash, fix your hash and try " "again..".format(alg.upper())) shutdown(1) LOGGER.info("Starting bruteforce with {}..".format( alg.upper())) bruteforcing = hash_words(verf_hash, wordlist, alg, salt=salt, placement=placement, posx=posx, use_hex=use_hex) if bruteforcing is None: LOGGER.warning( "Unable to find a match for '{}', using {}..".format( verf_hash, alg.upper())) else: match_found(bruteforcing) break else: LOGGER.info("Using algorithm, {}..".format(algorithm.upper())) results = hash_words(verf_hash, wordlist, algorithm, salt=salt, placement=placement, posx=posx) if results is None: LOGGER.warning("Unable to find a match using {}..".format( algorithm.upper())) verifiy = prompt( "Would you like to attempt to verify the hash type automatically and crack it", "y/N") if verifiy.lower().startswith("y"): bruteforce_main(verf_hash, wordlist=wordlist, salt=salt, placement=placement, posx=posx, use_hex=use_hex) else: LOGGER.warning( "Unable to produce a result for given hash '{}' using {}.. Exiting.." .format(verf_hash, algorithm.upper())) else: match_found(results)