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: Configuration.logger.warning( "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 Configuration.dual_print(Configuration.logger.warning, msg) written_flag = True with open(Configuration.save_result_filename, "w") as fp: fp.write(password) sleep(10)
def run(): Configuration.initialize() Cracker.crt_workload = 4 # TODO get value from parameters, adjust from keyboard signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) Cracker.req = Requester(Configuration.apikey, Comunicator.error_printer) Cracker.resume_work() Comunicator.initialize() Comunicator.printer("Cracker initialized", reprint=False) # Disable terminal echo os.system("stty -echo") try: last_time = None while True: now_time = datetime.now() if last_time is None or (now_time - last_time).total_seconds() > 10: last_time = now_time Cracker.crack_existing_handshakes() cmd = Comunicator.get_command() if cmd is not None: Cracker.parse_command(cmd) sleep(0.1) except Exception as e: Configuration.dual_print( Configuration.logger.critical, "Caught unexpected exception: '%s'" % (traceback.format_exc())) Cracker.clean_variables() die(True, e) finally: # Reenable terminal echo os.system("stty echo") pass
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": Configuration.dual_print( Configuration.logger.info, "Please install program '%s'" % missing["name"]) elif missing["type"] in [ "dict", "maskfile", "generator", "john-local.conf" ]: Configuration.dual_print( Configuration.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: Configuration.dual_print( Configuration.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: Configuration.dual_print(Configuration.logger.warning, "Unknown missing type '%s'" % missing) if gather_flag: Configuration.gather_capabilities()
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 crack_existing_handshakes(): # Something just finished! if Cracker.crt_process is not None and Cracker.crt_process.isdead(): Cracker.process_result() # Process is still running - update eta if Cracker.crt_process is not None: Cracker.update_eta() return if slow_stop_flag: Configuration.logger.info( "Slow shutdown signal received - shutting down!") sys.exit(0) # Before getting more work make sure we are up to date Cracker.complete_missing() # Nothing is running - getting more work try: work = Cracker.req.getwork() except Cracker.req.ServerDown: # TODO print something maybe return die(work is True, "An error occured while getting work!") # No work to be done right now if work is None: print("No work to be done, checking in 10 seconds again.") return # Redundant check if work is False: Configuration.dual_print(Configuration.logger.warning, "Capabilities out of date!") return Cracker.start_cracking(work)
def die(condition, message): if condition: msg = "line %s in '%s': '%s'" % \ (inspect.currentframe().f_back.f_lineno, inspect.stack()[1][3], message) Configuration.dual_print(Configuration.logger.critical, msg) sys.exit(-1)