def checkHashType(self, hash_type): """ Check if input hash type is a... correct number valid string corresponding a hash type number in the hash_types.json file """ try: # if it is already a valid number if hash_type.isdigit() and int(hash_type) in range(0, 99999): return hash_type # if it is a string with the title of the format else: with open(os.path.join(self.source_dir, "hash_types.json"), "r", encoding="utf-8") as f: types = json.load(f) lower_keys = { k.lower(): v for k, v in types.items() } #r take ['MD5': '0'...] and return ['md5': '0'] hash_type = hash_type.lower() # lower input type MD5 to md5 if hash_type in lower_keys.keys(): return lower_keys[hash_type] else: Color.showError( "Invalid hash type number or title. Check valid list here: https://hashcat.net/wiki/doku.php?id=example_hashes", True) except Exception as e: Color.showException(e)
def parseHashFilesList(hash_files_list_path): """ Parse hash files list with the hash_file, hash_type, extra_params in json format """ try: with open(hash_files_list_path, "r", encoding="utf-8") as f: json_file = json.load(f) files_list = json_file["list"] return files_list except Exception as e: Color.showException(e)
def parseConfigFilesList(all_attacks_file): """ Parse attacks_files list from json file """ try: path = os.path.join(Configuration.getBaseDir(), "attacks", all_attacks_file) with open(path, "r", encoding="utf-8") as f: json_file = json.load(f) files_list = json_file["attacks_files"] return files_list except Exception as e: Color.showException(e)
def main(color): """ configuration: all the attacks and config data from the user and files attacks: configure attacks from files data hashcat: calls to hashcat individual attacks """ # print start datetime start_date = datetime.now() Color.showVerbose("Start date: " + Color.datetime_to_string(start_date)) Color.showVerbose("Press enter or [s] to see hashcat's status...") Color.showVerbose("Press [q]' to skip one hashcat command...") Color.showVerbose("Press [Ctrl+c] to skip one attack file...") Color.showVerbose("Press [Ctrl+c] x3 times to stop all attacks...") # get input arguments arguments = getArguments() if not arguments.attacks_file: Color.showError("Nothing happening here... add [-a attacks_file] to execute attacks", True) # ctrl+c signal counter for exiting program instead of bypassing resources interruptCounter = 0 lastInterruptTime = datetime.now() try: """ For every attacks_file in the list (all configs) """ attacks_file_list = Configuration.getConfigFilesArray(arguments.attacks_file) for attacks_file in attacks_file_list: """ For every hash_file in the list, execute all the defined attacks in the attacks_file """ hash_files_list = Configuration.getHashFilesArray(arguments.hash_file, arguments.hash_type, arguments.extra_params, arguments.hash_files) for hash_file_item in hash_files_list: parsing_errors = False if hash_file_item: if hash_file_item["hash_file"]: hash_file = hash_file_item["hash_file"] else: parsing_errors = True if hash_file_item["hash_type"]: hash_type = hash_file_item["hash_type"] else: parsing_errors = True if len(hash_file_item) == 3 and hash_file_item["extra_params"]: extra_params = hash_file_item["extra_params"] else: extra_params = "" else: parsing_errors = True if parsing_errors: Color.showError("Error in the files/types/extra_param parsing... skipping this file", False) break # load other scripts conf = Configuration(hash_file, hash_type, attacks_file, extra_params, arguments.output_dir, arguments.wordlist_custom_file) hashcat = Hashcat(conf.static_values, arguments.verbose, color) attacks = Attacks(hashcat) #set logging file log_path = os.path.join(conf.results_dir, "autocrackeo.log") color.setFileHandler(log_path) # set log file Color.showVerbose("The results (potfile, cracked passwords and logfile) will be written to: " + conf.results_dir + "\n") # print important info Color.showTitle(Color.datetime_to_string(datetime.now())) msg = "Attacks config file:" + attacks_file + ", hash file:" + hash_file + ", hash type:" + hash_type + ", extra params:" + extra_params Color.showMessage(msg + "\n") # show attack file color.logThis("[i] " + Color.datetime_to_string(datetime.now()) + ", " + msg) # log attack file if attacks_file: # if -c/--config """ Execute a specific selection of hashcat attacks previously defined on the configuration json file This will be updated gradually as the efficiency of the attacks are measured """ try: for attack_name in conf.attacks: if arguments.verbose: Color.showVerbose("Attack type: " + attack_name.replace("_"," ").title()) # nice print if "straight" in attack_name: attacks.straight_attacks(attack_name, conf.attacks[attack_name], conf.wordlists, conf.rules) elif "combinator" in attack_name: attacks.combinator_attacks(attack_name, conf.attacks[attack_name], conf.wordlists) elif "brute_force" in attack_name: attacks.brute_force_attacks(attack_name, conf.attacks[attack_name], conf.masks) elif "hybrid" in attack_name: attacks.hybrid_attacks(attack_name, conf.attacks[attack_name], conf.wordlists, conf.masks) elif "one_word_per_hash" in attack_name: attacks.OneWordPerHashAttacks(attack_name, conf.attacks[attack_name], conf.wordlists) else: Color.showError("This attack name is not recognized!", False) # dump plaintext passwords from potfile to custom wordlist if arguments.feedback: hashcat.feedback(arguments.wordlist_custom_file) except KeyboardInterrupt as ki: """ Set a SIGINT signal handler to securely skip all the attacks for this hash_file and attacks_file and it continues the loop but if it is x3 times clicked with less than 1 second of distance, exit program """ Color.showError("Ctrl+C {0}: Skipping {1} attacks...".format(interruptCounter+1,attacks_file), False) color.logThis("[X] Ctrl+C {0}: Skipping {1} attacks...".format(interruptCounter+1,attacks_file)) hashcat.save_cracked() # dump results output in cracked file interruptTime = datetime.now() difference = interruptTime - lastInterruptTime if (difference.total_seconds() < 1): interruptCounter+=1 if (interruptCounter > 2): ki.message = "ctrl+c x3" raise else: interruptCounter = 0 lastInterruptTime = interruptTime except Exception as e: Color.showException(e, True) hashcat.save_cracked() # ALWAYS DUMP RESULTS: for every config file tried, and every hash file/type except KeyboardInterrupt as ki: Color.showError("Ctrl+C (x3): Exiting attacks...", False) color.logThis("[X] Ctrl+C (x3): Exiting attacks...") except Exception as e: Color.showError(str(e), False) """ Print end of execution """ # print end datetime and duration Color.showTitle("") end_date = datetime.now() Color.showVerbose("End date: " + Color.datetime_to_string(end_date)) duration = end_date - start_date Color.showVerbose("Duration: " + Color.timedelta_to_string(duration))
hashcat.save_cracked() # ALWAYS DUMP RESULTS: for every config file tried, and every hash file/type except KeyboardInterrupt as ki: Color.showError("Ctrl+C (x3): Exiting attacks...", False) color.logThis("[X] Ctrl+C (x3): Exiting attacks...") except Exception as e: Color.showError(str(e), False) """ Print end of execution """ # print end datetime and duration Color.showTitle("") end_date = datetime.now() Color.showVerbose("End date: " + Color.datetime_to_string(end_date)) duration = end_date - start_date Color.showVerbose("Duration: " + Color.timedelta_to_string(duration)) """ Call main method """ if __name__ == '__main__': os.system("") # do nothing but enable command colors on windows cmd color = Color() Color.showTitle("Autocrackeo") try: main(color) except Exception as e: Color.showException(e, True) Color.showEnding()
def __init__(self, hash_file, hash_type, attacks_file, extra_params, output_dir, wordlist_custom_dir): self.color = Color() conf = None hostconf = None self.attacks = {} self.static_values = {} """ Configure working paths """ # ....../autocrackeo/src/configuration.py --> ......./autocrackeo/ base_dir = os.path.dirname(os.path.dirname( os.path.realpath(__file__))) # print("base_dir: " + base_dir) self.attacks_dir = os.path.join(base_dir, "attacks") self.wordlists_dir = os.path.join(base_dir, "wordlists") self.rules_dir = os.path.join(base_dir, "rules") self.masks_dir = os.path.join(base_dir, "masks") self.source_dir = os.path.join(base_dir, "src") # configure results dir and create folder if not exists if output_dir: self.results_dir = os.path.join(output_dir) else: self.results_dir = os.path.join( ".") # if not selected, make current dir . try: if not os.path.exists(self.results_dir): os.makedirs(self.results_dir) except OSError as e: Color.showException(e) try: """ Load hashcat execution parameters from host-config file """ #read and extract json data with open(os.path.join(self.source_dir, "HOST_CONFIG.json"), "r", encoding="utf-8") as f: hostconf = json.load(f) # host config: executable, resources self.static_values["executable"] = hostconf["executable"] self.static_values["resource_options"] = hostconf["resources"] """ Load parameters from input arguments """ # generate filename for cracked results self.static_values["hash_file"] = hash_file hash_file_name = hash_file.split(os.path.sep)[ -1] # last part of the hash list path: hashfile name cracked_file_name = "cracked-" + hash_type + "-" + hash_file_name.replace( ".", "_") + ".txt" cracked_file_name = cracked_file_name.lower() self.static_values["out_file_cracked"] = os.path.join( self.results_dir, cracked_file_name) hash_type = self.checkHashType(hash_type) self.static_values["hash_type"] = hash_type self.static_values["attacks_file"] = attacks_file self.static_values["extra_params"] = extra_params # Define potfile pot_file = os.path.join(self.results_dir, "potfile.pot") self.static_values["pot_file"] = pot_file # Check needed file existence file_paths = [hash_file] for file_path in file_paths: exists = os.path.isfile(file_path) if not exists: Color.showError( "File {file_path} does not exist...".format( file_path=file_path), True) """ Load attacks and useful files from attacks json file And add the relative paths to the files to use """ if attacks_file: # load /autocrackeo/attacks/ + {attacks_file} attacks_path = os.path.join(self.attacks_dir, attacks_file) with open(attacks_path, "r", encoding="utf-8") as f: conf = json.load(f) self.wordlists, self.rules, self.masks = [], [], [] self.attacks = conf["attacks"] self.static_values.update(conf["files"]) # path to the files: ## wordlists for wordlist in self.static_values["wordlists_files"]: if wordlist: if wordlist != "custom.txt": self.wordlists.append( os.path.join(self.wordlists_dir, wordlist)) else: if wordlist_custom_dir: self.wordlists.append( os.path.join(wordlist_custom_dir) ) # if input argument -w custom_wordlist.txt replace default custom.txt else: self.wordlists.append( os.path.join(self.wordlists_dir, "super.txt") ) # else take super.txt by default instead of custom.txt wordlist ## rules for rules_file in self.static_values["rules_files"]: self.rules.append( os.path.join(self.rules_dir, rules_file)) ## masks for masks_file in self.static_values["masks_files"]: self.masks.append( os.path.join(self.masks_dir, masks_file)) #pprint(self.static_values)# mostrar contenido del objeto except Exception as e: Color.showException(e)