def safe_send_result(password): written_flag = False while True: try: res = Cracker.req.sendresult(password) die( res is True, "Sending result '%s' for job '%s' produced an error" % (password, Cracker.mac_ssid_job)) if os.path.exists(Configuration.save_result_filename): os.remove(Configuration.save_result_filename) if res is False: Comunicator.warning_logger( "Server cancelled last job. Requesting stopwork.") Cracker.req.stopwork() break except Cracker.req.ServerDown: if not written_flag: msg = "Trying to send result '%s' for last job but the server is unreachable" % password Comunicator.dual_printer(Comunicator.logger.warning, msg) written_flag = True with open(Configuration.save_result_filename, "w") as fp: fp.write(password) sleep(10)
def die(condition, message): if condition: msg = "File '%s', line %s, in %s: '%s'" % \ (inspect.getmodule(inspect.stack()[1][0]).__file__, inspect.currentframe().f_back.f_lineno, inspect.stack()[1][3], message) Comunicator.dual_printer(Comunicator.logger.critical, msg) sys.exit(-1)
def complete_missing(): gather_flag = False try: missings = Cracker.req.getmissing() except Cracker.req.ServerDown: return die(missings is True, "Server side error occurred.") if missings is None: return for missing in missings: if missing["type"] == "program": Comunicator.info_logger("Please install program '%s'" % missing["name"]) elif missing["type"] in [ "dict", "maskfile", "generator", "john-local.conf" ]: Comunicator.dual_printer( Comunicator.logger.info, "Downloading '%s'..." % missing["path"]) gather_flag = True if "/" in missing["path"]: directory, filename = missing["path"].rsplit('/', 1) # Create directory if they do not exist os.makedirs(directory, exist_ok=True) else: filename = missing["path"] try: if Cracker.req.checkfile(filename) is None and \ Cracker.req.getfile(filename, missing["path"]) is None: Comunicator.dual_printer( Comunicator.logger.info, "Downloaded '%s'" % missing["path"]) if missing["type"] == "generator": os.chmod( missing["path"], stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) except Cracker.req.ServerDown: return else: Comunicator.warning_logger("Unknown missing type '%s'" % missing) if gather_flag: Configuration.gather_capabilities()
def test_capabilities(): """ Test cracking capabilities and run dummy programs to check for errors Removes capabilities from 'capabilities' if the test fails :return: None """ if "john" in Configuration.capabilities: res = Configuration.test_john() if res is not True: del Configuration.capabilities["john"] Comunicator.dual_printer( Comunicator.logger.warn, "John is currently not available:\n%s" % res)
def start_cracking(work): Cracker.mac_ssid_job = "%s-%s" % (work["handshake"]["mac"], work["handshake"]["ssid"]) msg = "Running '%s' with rule '%s'" % (Cracker.mac_ssid_job, work["rule"]["name"]) Comunicator.enable(interactive=False) Comunicator.dual_printer(Comunicator.logger.info, msg) _, Cracker.path_temp_file = mkstemp(prefix="psknow_crack") if work["handshake"]["file_type"] == "16800": with open(Cracker.path_temp_file, "w") as fd: fd.write(work["handshake"]["data"]) else: with open(Cracker.path_temp_file, "wb") as fd: fd.write(b64decode(work["handshake"]["data"].encode("utf8"))) # Memorize attack type - we need it to decode the output attack_type = work["handshake"]["handshake_type"] Cracker.crt_rule = work["rule"] attacked_file = Cracker.path_temp_file # Get commands needed to run hashcat generator_command, Cracker.attack_command, Cracker.scrambler =\ Cracker.get_attack_command(Cracker.crt_rule, attack_type, attacked_file, work["handshake"]["ssid"]) Comunicator.info_logger( "Trying rule %s on '%s-%s'" % (Cracker.crt_rule["name"], work["handshake"]["mac"], work["handshake"]["ssid"])) if Cracker.is_already_cracked(Cracker.attack_command): Comunicator.warning_logger( "'%s' has already been cracked. Attempting to send result." % Cracker.mac_ssid_job) Cracker.process_result() return if generator_command == "": Cracker.crt_process = SingleProcess(Cracker.attack_command) else: Cracker.crt_process = DoubleProcess(generator_command, Cracker.attack_command)
def start_cracking(work): Cracker.mac_ssid_job = "%s-%s" % (work["handshake"]["mac"], work["handshake"]["ssid"]) msg = "Running '%s' with rule '%s'" % (Cracker.mac_ssid_job, work["rule"]["name"]) Comunicator.enable(interactive=False) Comunicator.dual_printer(msg, Configuration.logger.info) _, Cracker.path_temp_file = mkstemp(prefix="psknow_crack") if work["handshake"]["file_type"] == "16800": with open(Cracker.path_temp_file, "w") as fd: fd.write(work["handshake"]["data"]) else: with open(Cracker.path_temp_file, "wb") as fd: fd.write(b64decode(work["handshake"]["data"].encode("utf8"))) # Memorize attack type - we need it to decode the output attack_type = work["handshake"]["handshake_type"] Cracker.crt_rule = work["rule"] attacked_file = Cracker.path_temp_file # Get commands needed to run hashcat generator_command, Cracker.attack_command, Cracker.scrambler =\ Cracker.get_attack_command(Cracker.crt_rule, attack_type, attacked_file, work["handshake"]["ssid"]) Configuration.logger.info( "Trying rule %s on '%s-%s'" % (Cracker.crt_rule["name"], work["handshake"]["mac"], work["handshake"]["ssid"])) if Cracker.is_potfile_duplicated(Cracker.attack_command): msg = "Duplication for %s happened. It is already present in potfile!" % Cracker.mac_ssid_job Configuration.dual_print(Configuration.logger.critical, msg) fast_stop() if generator_command == "": Cracker.crt_process = SingleProcess(Cracker.attack_command) else: Cracker.crt_process = DoubleProcess(generator_command, Cracker.attack_command)
def load_config(): """ Loads api key from file defined in variable Configuration.apikey_path. Ignores lines prefixed by '#', any leading ' ' and trailing '\n' The key is stored in Configuration.apikey :return: None """ error_string = "" try: with open(Configuration.config_file) as file: config = json.load(file) def load_key(lkey): try: return config[lkey], "" except KeyError: return None, "Missing vital information '%s' from config file\n" % lkey Configuration.apikey, err = load_key("apikey") error_string += err Configuration.john_path, err = load_key("john_path") error_string += err Configuration.remote_server, err = load_key("server_location") error_string += err Configuration.hashcat_workload, err = load_key( "hashcat_workload") error_string += err except json.decoder.JSONDecodeError as e: Comunicator.fatal_regular_message( "Configuration file '%s' is not a valid json with error '%s'. Fix" "file or completely remove to restore to default state." % (Configuration.config_file, e)) except FileNotFoundError: with open(Configuration.config_file, "w") as fd: json.dump(Configuration.empty_config, fd) Comunicator.fatal_regular_message( "Configuration file '%s' did not exist. Empty file was generated, please" "fill in data for the cracker to properly work." % Configuration.config_file) if len(error_string) > 0: if error_string.endswith("\n"): error_string = error_string[:-1] Comunicator.fatal_regular_message(error_string) # Check remote server location if Configuration.remote_server is None or len( Configuration.remote_server) < 1: Comunicator.fatal_regular_message( "Invalid or missing remote server location. Please write server location" "in configuration file Ex. " "'\"server_location\": \"http://127.0.0.1:9645/\"'") if not (Configuration.remote_server.startswith("https://") or Configuration.remote_server.startswith("http://")): Comunicator.fatal_regular_message( "Server location should start with either 'https://' or 'http://'" ) if not Configuration.remote_server.endswith("/"): Configuration.remote_server += "/" Configuration.remote_server += "api/v1/" Comunicator.printer("Using remote server '%s'" % Configuration.remote_server) # Check hashcat workload if type(Configuration.hashcat_workload) is not int: Comunicator.fatal_regular_message( "Key 'hashcat_workload' from configuration file '%s' has invalid type %s" " instead of int" % (Configuration.config_file, type(Configuration.hashcat_workload))) if Configuration.hashcat_workload < 1 or Configuration.hashcat_workload > 4: Comunicator.dual_printer( Comunicator.logger.warn, "Hashcat workload should be 1-4. Value found is %d." "Using default 4") Configuration.hashcat_workload = 4 # Check API key if Configuration.apikey is None or len(Configuration.apikey) < 10: Comunicator.fatal_regular_message( "Invalid or missing api key in config file '%s'. Please generate key " "and write it on the configuration file." % Configuration.config_file) # Check john path if len(Configuration.john_path) == 0: Configuration.john_path = None elif not os.path.exists(Configuration.john_path): Comunicator.fatal_regular_message( "Supplied path for john the ripper '%s' is not valid" % Configuration.john_path)