Beispiel #1
0
 def prince_keyspace(self, task, chunk):
     binary = "pp64."
     if Initialize.get_os() != 1:
         binary = "./" + binary + "bin"
     else:
         binary += "exe"
     full_cmd = binary + " --keyspace " + get_wordlist(
         update_files(task['attackcmd'], True).replace(
             task['hashlistAlias'], ""))
     if Initialize.get_os() == 1:
         full_cmd = full_cmd.replace("/", '\\')
     try:
         logging.debug("CALL: " + full_cmd)
         output = subprocess.check_output(full_cmd,
                                          shell=True,
                                          cwd="prince")
     except subprocess.CalledProcessError:
         logging.error("Error during PRINCE keyspace measure")
         send_error("PRINCE keyspace measure failed!",
                    self.config.get_value('token'), task['taskId'], None)
         sleep(5)
         return False
     output = output.decode(encoding='utf-8').replace("\r\n",
                                                      "\n").split("\n")
     keyspace = "0"
     for line in output:
         if not line:
             continue
         keyspace = line
     # as the keyspace of prince can get very very large, we only save it in case it's small enough to fit in a long,
     # otherwise we assume that the user will abort the task earlier anyway
     if int(keyspace
            ) > 9000000000000000000:  # close to max size of a long long int
         return chunk.send_keyspace(-1, task['taskId'])
     return chunk.send_keyspace(int(keyspace), task['taskId'])
    def preprocessor_keyspace(self, task, chunk):
        preprocessor = task.get_preprocessor()
        if preprocessor['keyspaceCommand'] is None:  # in case there is no keyspace flag, we just assume the task will be that large to run forever
          return chunk.send_keyspace(-1, task.get_task()['taskId'])

        binary = preprocessor['executable']
        if Initialize.get_os() != 1:
            binary = "./" + binary
        if not os.path.isfile(binary):
            split = binary.split(".")
            binary = '.'.join(split[:-1]) + get_bit() + "." + split[-1]

        full_cmd = binary + " " + preprocessor['keyspaceCommand'] + " " + update_files(task.get_task()['preprocessorCommand'])
        if Initialize.get_os() == 1:
            full_cmd = full_cmd.replace("/", '\\')
        try:
            logging.debug("CALL: " + full_cmd)
            output = subprocess.check_output(full_cmd, shell=True, cwd="preprocessor/" + str(task.get_task()['preprocessor']))
        except subprocess.CalledProcessError:
            logging.error("Error during preprocessor keyspace measure")
            send_error("Preprocessor keyspace measure failed!", self.config.get_value('token'), task.get_task()['taskId'], None)
            sleep(5)
            return False
        output = output.decode(encoding='utf-8').replace("\r\n", "\n").split("\n")
        keyspace = "0"
        for line in output:
            if not line:
                continue
            keyspace = line
        # as the keyspace of preprocessors can get very very large, we only save it in case it's small enough to fit in a long,
        # otherwise we assume that the user will abort the task earlier anyway
        if int(keyspace) > 9000000000000000000:  # close to max size of a long long int
            return chunk.send_keyspace(-1, task.get_task()['taskId'])
        return chunk.send_keyspace(int(keyspace), task.get_task()['taskId'])
 def run_speed_benchmark(self, task):
     args = " --machine-readable --quiet --progress-only"
     args += " --restore-disable --potfile-disable --session=hashtopolis "
     args += update_files(task['attackcmd']).replace(task['hashlistAlias'], "../../hashlists/" + str(task['hashlistId']))
     args += " -o ../../hashlists/" + str(task['hashlistId']) + ".out"
     full_cmd = self.callPath + args
     if Initialize.get_os() == 1:
         full_cmd = full_cmd.replace("/", '\\')
     try:
         logging.debug("CALL: " + full_cmd)
         output = subprocess.check_output(full_cmd, shell=True, cwd=self.cracker_path)
     except subprocess.CalledProcessError as e:
         logging.error("Error during keyspace measure, return code: " + str(e.returncode))
         send_error("Keyspace measure failed!", self.config.get_value('token'), task['taskId'])
         return 0
     output = output.decode(encoding='utf-8').replace("\r\n", "\n").split("\n")
     sum = [0, 0]
     for line in output:
         if len(line) == 0:
             continue
         line = line.split(":")
         if len(line) != 3:
             continue
         sum[0] += int(line[1])
         sum[1] += float(line[2])
     return str(sum[0]) + ":" + str(sum[1])
 def measure_keyspace(self, task, chunk):
     if 'usePrince' in task.get_task() and task.get_task()['usePrince']:
         return self.prince_keyspace(task.get_task(), chunk)
     elif 'usePreprocessor' in task.get_task() and task.get_task()['usePreprocessor']:
         return self.preprocessor_keyspace(task, chunk)
     task = task.get_task()  # TODO: refactor this to be better code
     full_cmd = self.callPath + " --keyspace --quiet " + update_files(task['attackcmd']).replace(task['hashlistAlias'] + " ", "") + ' ' + task['cmdpars']
     if 'useBrain' in task and task['useBrain']:
         full_cmd += " -S"
     if Initialize.get_os() == 1:
         full_cmd = full_cmd.replace("/", '\\')
     try:
         logging.debug("CALL: " + full_cmd)
         output = subprocess.check_output(full_cmd, shell=True, cwd=self.cracker_path)
     except subprocess.CalledProcessError as e:
         logging.error("Error during keyspace measure: " + str(e))
         send_error("Keyspace measure failed!", self.config.get_value('token'), task['taskId'], None)
         sleep(5)
         return False
     output = output.decode(encoding='utf-8').replace("\r\n", "\n").split("\n")
     keyspace = "0"
     for line in output:
         if not line:
             continue
         keyspace = line
     return chunk.send_keyspace(int(keyspace), task['taskId'])
Beispiel #5
0
 def run_speed_benchmark(self, task):
     args = " --machine-readable --quiet --progress-only"
     args += " --restore-disable --potfile-disable --session=hashtopolis -p \"" + str(chr(9)) + "\" "
     if task['usePrince']:
         args += get_rules_and_hl(update_files(task['attackcmd']), task['hashlistAlias']).replace(task['hashlistAlias'], "../../hashlists/" + str(task['hashlistId'])) + ' '
         args += " example.dict" + ' ' + task['cmdpars']
     else:
         args += update_files(task['attackcmd']).replace(task['hashlistAlias'], "../../hashlists/" + str(task['hashlistId'])) + ' ' + task['cmdpars']
     if 'useBrain' in task and task['useBrain']:
         args += " -S"
     args += " -o ../../hashlists/" + str(task['hashlistId']) + ".out"
     full_cmd = self.callPath + args
     if Initialize.get_os() == 1:
         full_cmd = full_cmd.replace("/", '\\')
     try:
         logging.debug("CALL: " + full_cmd)
         output = subprocess.check_output(full_cmd, shell=True, cwd=self.cracker_path)
     except subprocess.CalledProcessError as e:
         logging.error("Error during speed benchmark, return code: " + str(e.returncode))
         send_error("Speed benchmark failed!", self.config.get_value('token'), task['taskId'], None)
         return 0
     output = output.decode(encoding='utf-8').replace("\r\n", "\n").split("\n")
     benchmark_sum = [0, 0]
     for line in output:
         if not line:
             continue
         line = line.split(":")
         if len(line) != 3:
             continue
         # we need to do a weighted sum of all the time outputs of the GPUs
         benchmark_sum[0] += int(line[1])
         benchmark_sum[1] += float(line[2])*int(line[1])
     return str(benchmark_sum[0]) + ":" + str(float(benchmark_sum[1]) / benchmark_sum[0])
 def measure_keyspace(self, task, chunk):
     if 'usePrince' in task.get_task() and task.get_task()['usePrince']:
         return self.prince_keyspace(task.get_task(), chunk)
     elif 'usePreprocessor' in task.get_task() and task.get_task()['usePreprocessor']:
         return self.preprocessor_keyspace(task, chunk)
     task = task.get_task()  # TODO: refactor this to be better code
     full_cmd = self.callPath + " --keyspace --quiet " + update_files(task['attackcmd']).replace(task['hashlistAlias'] + " ", "") + ' ' + task['cmdpars']
     if 'useBrain' in task and task['useBrain']:
         full_cmd += " -S"
     if Initialize.get_os() == 1:
         full_cmd = full_cmd.replace("/", '\\')
     output = b''
     try:
         logging.debug("CALL: " + full_cmd)
         output = subprocess.check_output(full_cmd, shell=True, cwd=self.cracker_path, stderr=subprocess.STDOUT)
     except subprocess.CalledProcessError as e:
         logging.error("Error during keyspace measure: " + str(e) + " Output: " + output.decode(encoding='utf-8'))
         send_error("Keyspace measure failed!", self.config.get_value('token'), task['taskId'], None)
         sleep(5)
         return False
     output = output.decode(encoding='utf-8').replace("\r\n", "\n").split("\n")
     ks = 0
     # try to parse each line as a keyspace result integer (normally only one line should be in output, but some warnings might show up)
     for line in output:
         if not line:
             continue
         try:
             ks = int(line)
         except ValueError:
             pass
     return chunk.send_keyspace(ks, task['taskId'])
 def measure_keyspace(self, task, chunk):
     full_cmd = self.callPath + " --keyspace --quiet " + update_files(task['attackcmd']).replace(task['hashlistAlias'] + " ", "")
     if Initialize.get_os() == 1:
         full_cmd = full_cmd.replace("/", '\\')
     try:
         output = subprocess.check_output(full_cmd, shell=True, cwd=self.cracker_path)
     except subprocess.CalledProcessError:
         logging.error("Error during keyspace measure")
         send_error("Keyspace measure failed!", self.config.get_value('token'), task['taskId'])
         return
     output = output.decode(encoding='utf-8').replace("\r\n", "\n").split("\n")
     keyspace = "0"
     for line in output:
         if len(line) == 0:
             continue
         keyspace = line
     chunk.send_keyspace(int(keyspace), task['taskId'])
 def measure_keyspace(self, task, chunk):
     task = task.get_task()
     full_cmd = self.callPath + " keyspace " + task['attackcmd'].replace(
         "-a " + task['hashlistAlias'] + " ", "")
     if Initialize.get_os() == 1:
         full_cmd = full_cmd.replace("/", '\\')
     try:
         logging.debug("CALL: " + full_cmd)
         output = subprocess.check_output(full_cmd, shell=True, cwd='files')
     except subprocess.CalledProcessError as e:
         logging.error("Error during keyspace measurement: " + str(e))
         send_error("Keyspace measure failed!",
                    self.config.get_value('token'), task['taskId'], None)
         sleep(5)
         return False
     output = output.decode(encoding='utf-8').replace("\r\n",
                                                      "\n").split("\n")
     keyspace = "0"
     for line in output:
         if not line:
             continue
         keyspace = line
     self.keyspace = int(keyspace)
     return chunk.send_keyspace(int(keyspace), task['taskId'])
Beispiel #9
0
    def run_loop(self, proc, chunk, task):
        self.cracks = []
        piping_threshold = 95
        enable_piping = False
        if self.config.get_value('piping-threshold'):
            piping_threshold = self.config.get_value('piping-threshold')
        if self.config.get_value('allow-piping') != '':
            enable_piping = self.config.get_value('allow-piping')
        while True:
            try:
                # Block for 1 second.
                if not self.first_status and self.last_update < time.time() - 5:
                    # send update
                    query = copy_and_set_token(dict_sendProgress,
                                               self.config.get_value('token'))
                    query['chunkId'] = chunk['chunkId']
                    query['keyspaceProgress'] = chunk['skip']
                    query['relativeProgress'] = 0
                    query['speed'] = 0
                    query['state'] = 2
                    query['cracks'] = []
                    req = JsonRequest(query)
                    logging.info(
                        "Sending keepalive progress to avoid timeout...")
                    req.execute()
                    self.last_update = time.time()
                item = self.io_q.get(True, 1)
            except Empty:
                # No output in either streams for a second. Are we done?
                if proc.poll() is not None:
                    # is the case when the process is finished
                    break
            else:
                identifier, line = item
                if identifier == 'OUT':
                    status = HashcatStatus(line.decode())
                    if status.is_valid():
                        self.statusCount += 1

                        # test if we have a low utility
                        # not allowed if brain is used
                        if enable_piping and not self.uses_slow_hash_flag and (
                                'useBrain' not in task or not task['useBrain']
                        ) and 'slowHash' in task and task[
                                'slowHash'] and not self.usePipe:
                            if task['files'] and not (
                                    'usePrince' in task and task['usePrince']
                            ) and not (
                                    'usePreprocessor' in task
                                    and task['usePreprocessor']
                            ) and 1 < self.statusCount < 10 and status.get_util(
                            ) != -1 and status.get_util() < piping_threshold:
                                # we need to try piping -> kill the process and then wait for issuing the chunk again
                                self.usePipe = True
                                chunk_start = int(
                                    status.get_progress_total() /
                                    (chunk['skip'] + chunk['length']) *
                                    chunk['skip'])
                                self.progressVal = status.get_progress_total(
                                ) - chunk_start
                                logging.info(
                                    "Detected low UTIL value, restart chunk with piping..."
                                )
                                try:
                                    kill_hashcat(proc.pid, Initialize.get_os())
                                except ProcessLookupError:
                                    pass
                                return

                        self.first_status = True
                        # send update to server
                        logging.debug(line.decode().replace('\n', '').replace(
                            '\r', ''))
                        total = status.get_progress_total()
                        if self.usePipe:  # if we are piping, we might have saved the total progress before switching to piping, so we can use this
                            total = self.progressVal
                        # we need to calculate the chunk start, because progress does not start at 0 for a chunk
                        chunk_start = int(status.get_progress_total() /
                                          (chunk['skip'] + chunk['length']) *
                                          chunk['skip'])
                        if total > 0:
                            relative_progress = int(
                                (status.get_progress() - chunk_start) /
                                float(total - chunk_start) * 10000)
                        else:  # this is the case when we cannot say anything about the progress
                            relative_progress = 0
                        speed = status.get_speed()
                        initial = True
                        if status.get_state() == 4 or status.get_state() == 5:
                            time.sleep(
                                5
                            )  # we wait five seconds so all output is loaded from file
                            # reset piping stuff when a chunk is successfully finished
                            self.progressVal = 0
                            self.usePipe = False
                        while self.cracks or initial:
                            self.lock.acquire()
                            initial = False
                            cracks_backup = []
                            if len(self.cracks) > 1000:
                                # we split
                                cnt = 0
                                new_cracks = []
                                for crack in self.cracks:
                                    cnt += 1
                                    if cnt > 1000:
                                        cracks_backup.append(crack)
                                    else:
                                        new_cracks.append(crack)
                                self.cracks = new_cracks
                            query = copy_and_set_token(
                                dict_sendProgress,
                                self.config.get_value('token'))
                            query['chunkId'] = chunk['chunkId']
                            query['keyspaceProgress'] = status.get_curku()
                            if (self.usePipe or 'usePrince' in task
                                    and task['usePrince'] or 'usePreprocessor'
                                    in task and task['usePreprocessor']
                                ) and status.get_curku() == 0:
                                query['keyspaceProgress'] = chunk['skip']
                            query['relativeProgress'] = relative_progress
                            query['speed'] = speed
                            query['state'] = status.get_state()
                            # crack format: hash[:salt]:plain:hex_plain:crack_pos (separator will be tab instead of :)
                            prepared = []
                            for crack in self.cracks:
                                prepared.append(crack.rsplit(":", 3))
                            query['cracks'] = prepared
                            if status.get_temps():
                                query['gpuTemp'] = status.get_temps()
                            if status.get_all_util():
                                query['gpuUtil'] = status.get_all_util()
                            query['cpuUtil'] = [round(psutil.cpu_percent(), 1)]
                            req = JsonRequest(query)

                            logging.debug("Sending " + str(len(self.cracks)) +
                                          " cracks...")
                            ans = req.execute()
                            if ans is None:
                                logging.error("Failed to send solve!")
                            elif ans['response'] != 'SUCCESS':
                                self.wasStopped = True
                                logging.error("Error from server on solve: " +
                                              str(ans))
                                try:
                                    kill_hashcat(proc.pid, Initialize.get_os())
                                except ProcessLookupError:
                                    pass
                                sleep(5)
                                return
                            elif 'agent' in ans.keys(
                            ) and ans['agent'] == 'stop':
                                # server set agent to stop
                                self.wasStopped = True
                                logging.info(
                                    "Received stop order from server!")
                                try:
                                    kill_hashcat(proc.pid, Initialize.get_os())
                                except ProcessLookupError:
                                    pass
                                sleep(5)
                                return
                            else:
                                cracks_count = len(self.cracks)
                                self.cracks = cracks_backup
                                zaps = ans['zaps']
                                if zaps:
                                    logging.debug("Writing zaps")
                                    zap_output = "\tFF\n".join(zaps) + '\tFF\n'
                                    f = open(
                                        "hashlist_" + str(task['hashlistId']) +
                                        "/" + str(time.time()), 'a')
                                    f.write(zap_output)
                                    f.close()
                                logging.info("Progress:" +
                                             str("{:6.2f}".format(
                                                 relative_progress / 100)) +
                                             "% Speed: " + print_speed(speed) +
                                             " Cracks: " + str(cracks_count) +
                                             " Accepted: " +
                                             str(ans['cracked']) + " Skips: " +
                                             str(ans['skipped']) + " Zaps: " +
                                             str(len(zaps)))
                            self.lock.release()
                    else:
                        # hacky solution to exclude warnings from hashcat
                        if str(line[0]) not in string.printable:
                            continue
                        else:
                            pass  # logging.warning("HCOUT: " + line.strip())
                elif identifier == 'ERR':
                    msg = escape_ansi(
                        line.replace(b"\r\n", b"\n").decode('utf-8')).strip()
                    if msg and str(
                            msg
                    ) != '^C':  # this is maybe not the fanciest way, but as ctrl+c is sent to the underlying process it reports it to stderr
                        logging.error("HC error: " + msg)
                        send_error(msg, self.config.get_value('token'),
                                   task['taskId'], chunk['chunkId'])
                        sleep(
                            0.1
                        )  # we set a minimal sleep to avoid overreaction of the client sending a huge number of errors, but it should not be slowed down too much, in case the errors are not critical and the agent can continue
    def run_loop(self, proc, chunk, task):
        self.cracks = []
        while True:
            try:
                # Block for 1 second.
                if not self.first_status and self.last_update < time.time() - 5:
                    # send update
                    query = copyAndSetToken(dict_sendProgress, self.config.get_value('token'))
                    query['chunkId'] = chunk['chunkId']
                    query['keyspaceProgress'] = chunk['skip']
                    query['relativeProgress'] = 0
                    query['speed'] = 0
                    query['state'] = 2
                    query['cracks'] = []
                    req = JsonRequest(query)
                    logging.info("Sending keepalive progress to avoid timeout...")
                    req.execute()
                    self.last_update = time.time()
                item = self.io_q.get(True, 1)
            except Empty:
                # No output in either streams for a second. Are we done?
                if proc.poll() is not None:
                    # is the case when the process is finished
                    break
            else:
                identifier, line = item
                if identifier == 'OUT':
                    status = HashcatStatus(line.decode())
                    if status.is_valid():
                        self.first_status = True
                        # send update to server
                        chunk_start = int(status.get_progress_total() / (chunk['skip'] + chunk['length']) * chunk['skip'])
                        relative_progress = int((status.get_progress() - chunk_start) / float(status.get_progress_total() - chunk_start) * 10000)
                        speed = status.get_speed()
                        initial = True
                        if status.get_state() == 5:
                            time.sleep(1)  # we wait for a second so all output is loaded from file
                        while len(self.cracks) > 0 or initial:
                            self.lock.acquire()
                            initial = False
                            cracks_backup = []
                            if len(self.cracks) > 1000:
                                # we split
                                cnt = 0
                                new_cracks = []
                                for crack in self.cracks:
                                    cnt += 1
                                    if cnt > 1000:
                                        cracks_backup.append(crack)
                                    else:
                                        new_cracks.append(crack)
                                self.cracks = new_cracks
                            query = copyAndSetToken(dict_sendProgress, self.config.get_value('token'))
                            query['chunkId'] = chunk['chunkId']
                            query['keyspaceProgress'] = status.get_curku()
                            query['relativeProgress'] = relative_progress
                            query['speed'] = speed
                            query['state'] = status.get_state()
                            query['cracks'] = self.cracks
                            req = JsonRequest(query)

                            logging.debug("Sending " + str(len(self.cracks)) + " cracks...")
                            ans = req.execute()
                            if ans is None:
                                logging.error("Failed to send solve!")
                            elif ans['response'] != 'SUCCESS':
                                logging.error("Error from server on solve: " + str(ans))
                                try:
                                    kill_hashcat(proc.pid, Initialize.get_os())
                                except ProcessLookupError:
                                    pass
                                return
                            elif 'agent' in ans.keys() and ans['agent'] == 'stop':
                                # server set agent to stop
                                logging.info("Received stop order from server!")
                                try:
                                    kill_hashcat(proc.pid, Initialize.get_os())
                                except ProcessLookupError:
                                    pass
                                return
                            else:
                                cracks_count = len(self.cracks)
                                self.cracks = cracks_backup
                                zaps = ans['zaps']
                                if len(zaps) > 0:
                                    logging.debug("Writing zaps")
                                    zap_output = '\n'.join(zaps) + '\n'
                                    f = open("hashlist_" + str(task['hashlistId']) + "/" + str(time.time()), 'a')
                                    f.write(zap_output)
                                    f.close()
                                logging.info("Progress:" + str(
                                    "{:6.2f}".format(relative_progress / 100)) + "% Speed: " + print_speed(
                                    speed) + " Cracks: " + str(cracks_count) + " Accepted: " + str(
                                    ans['cracked']) + " Skips: " + str(ans['skipped']) + " Zaps: " + str(len(zaps)))
                            self.lock.release()
                    else:
                        # hacky solution to exclude warnings from hashcat
                        if str(line[0]) not in string.printable:
                            continue
                        else:
                            pass
                            # logging.warning("HCOUT: " + line.strip())
                else:
                    logging.error("HC error: " + str(line).strip())
                    msg = str(line).strip()
                    send_error(msg, self.config.get_value('token'), task['taskId'])