Пример #1
0
 def check_files(self, files, task_id):
     for file in files:
         if os.path.isfile("files/" + file) or os.path.isfile(
                 "files/" + file.replace(".7z", ".txt")):
             continue
         query = copyAndSetToken(ditc_getFile,
                                 self.config.get_value('token'))
         query['taskId'] = task_id
         query['file'] = file
         req = JsonRequest(query)
         ans = req.execute()
         if ans is None:
             logging.error("Failed to get file!")
             sleep(5)
             return False
         elif ans['response'] != 'SUCCESS':
             logging.error("Getting of file failed: " + str(ans))
             sleep(5)
             return False
         else:
             Download.download(
                 self.config.get_value('url').replace("api/server.php", "")
                 + ans['url'], "files/" + file)
             if os.path.splitext("files/" +
                                 file)[1] == '.7z' and not os.path.isfile(
                                     "files/" +
                                     file.replace(".7z", ".txt")):
                 # extract if needed
                 if Initialize.get_os() != 1:
                     os.system("./7zr" + Initialize.get_os_extension() +
                               " x -aoa -ofiles/ -y files/" + file)
                 else:
                     os.system("7zr" + Initialize.get_os_extension() +
                               " x -aoa -ofiles/ -y files/" + file)
     return True
Пример #2
0
def init(args):
    global CONFIG, binaryDownload

    logging.info("Starting client '" + Initialize.get_version() + "'...")

    # check if there are running hashcat.pid files around (as we assume that nothing is running anymore if the client gets newly started)
    if os.path.exists("crackers"):
        for root, dirs, files in os.walk("crackers"):
            for folder in dirs:
                if folder.isdigit() and os.path.exists("crackers/" + folder +
                                                       "/hashtopolis.pid"):
                    logging.info("Cleaning hashcat PID file from crackers/" +
                                 folder)
                    os.unlink("crackers/" + folder + "/hashtopolis.pid")

    session = Session(requests.Session()).s
    session.headers.update({'User-Agent': Initialize.get_version()})

    if CONFIG.get_value('proxies'):
        session.proxies = CONFIG.get_value('proxies')

    if CONFIG.get_value('auth-user') and CONFIG.get_value('auth-password'):
        session.auth = (CONFIG.get_value('auth-user'),
                        CONFIG.get_value('auth-password'))

    # connection initialization
    Initialize().run(args)
    # download and updates
    binaryDownload = BinaryDownload(args)
    binaryDownload.run()

    # if multicast is set to run, we need to start the daemon
    if CONFIG.get_value('multicast') and Initialize().get_os() == 0:
        start_uftpd(Initialize().get_os_extension(), CONFIG)
Пример #3
0
 def check_version(self, cracker_id):
     path = "crackers/" + str(cracker_id) + "/"
     query = copy_and_set_token(dict_downloadBinary, self.config.get_value('token'))
     query['type'] = 'cracker'
     query['binaryVersionId'] = cracker_id
     req = JsonRequest(query)
     ans = req.execute()
     if ans is None:
         logging.error("Failed to load cracker!")
         sleep(5)
         return False
     elif ans['response'] != 'SUCCESS' or not ans['url']:
         logging.error("Getting cracker failed: " + str(ans))
         sleep(5)
         return False
     else:
         self.last_version = ans
         if not os.path.isdir(path):
             # we need to download the 7zip
             if not Download.download(ans['url'], "crackers/" + str(cracker_id) + ".7z"):
                 logging.error("Download of cracker binary failed!")
                 sleep(5)
                 return False
             if Initialize.get_os() == 1:
                 os.system("7zr" + Initialize.get_os_extension() + " x -ocrackers/temp crackers/" + str(cracker_id) + ".7z")
             else:
                 os.system("./7zr" + Initialize.get_os_extension() + " x -ocrackers/temp crackers/" + str(cracker_id) + ".7z")
             os.unlink("crackers/" + str(cracker_id) + ".7z")
             for name in os.listdir("crackers/temp"):
                 if os.path.isdir("crackers/temp/" + name):
                     os.rename("crackers/temp/" + name, "crackers/" + str(cracker_id))
                 else:
                     os.rename("crackers/temp", "crackers/" + str(cracker_id))
                     break
     return True
    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'])
Пример #5
0
    def __init__(self, cracker_id, binary_download):
        self.config = Config()
        self.io_q = Queue()

        # Build cracker executable name by taking basename plus extension
        self.executable_name = binary_download.get_version()['executable']
        k = self.executable_name.rfind(".")
        self.executable_name = self.executable_name[:k] + "." + self.executable_name[k + 1:]
        self.cracker_path = "crackers/" + str(cracker_id) + "/"
        self.callPath = self.executable_name
        if Initialize.get_os() != 1:
            self.callPath = "./" + self.callPath

        if not os.path.isfile(self.cracker_path + self.callPath):  # in case it's not the new hashcat filename, try the old one (hashcat<bit>.<ext>)
            self.executable_name = binary_download.get_version()['executable']
            k = self.executable_name.rfind(".")
            self.executable_name = self.executable_name[:k] + get_bit() + "." + self.executable_name[k + 1:]
            self.cracker_path = "crackers/" + str(cracker_id) + "/"
            self.callPath = self.executable_name
            if Initialize.get_os() != 1:
                self.callPath = "./" + self.callPath

        self.lock = Lock()
        self.cracks = []
        self.first_status = False
        self.usePipe = False
        self.progressVal = 0
        self.statusCount = 0
        self.last_update = 0
        self.uses_slow_hash_flag = False
        self.wasStopped = False
Пример #6
0
 def __check_utils(self):
     path = '7zr' + Initialize.get_os_extension()
     if not os.path.isfile(path):
         query = copy_and_set_token(dict_downloadBinary, self.config.get_value('token'))
         query['type'] = '7zr'
         req = JsonRequest(query)
         ans = req.execute()
         if ans is None:
             logging.error("Failed to get 7zr!")
             sleep(5)
             self.__check_utils()
         elif ans['response'] != 'SUCCESS' or not ans['executable']:
             logging.error("Getting 7zr failed: " + str(ans))
             sleep(5)
             self.__check_utils()
         else:
             Download.download(ans['executable'], path)
             os.chmod(path, os.stat(path).st_mode | stat.S_IEXEC)
     path = 'uftpd' + Initialize.get_os_extension()
     if not os.path.isfile(path) and self.config.get_value('multicast'):
         query = copy_and_set_token(dict_downloadBinary, self.config.get_value('token'))
         query['type'] = 'uftpd'
         req = JsonRequest(query)
         ans = req.execute()
         if ans is None:
             logging.error("Failed to get uftpd!")
             sleep(5)
             self.__check_utils()
         elif ans['response'] != 'SUCCESS' or not ans['executable']:
             logging.error("Getting uftpd failed: " + str(ans))
             sleep(5)
             self.__check_utils()
         else:
             Download.download(ans['executable'], path)
             os.chmod(path, os.stat(path).st_mode | stat.S_IEXEC)
Пример #7
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'])
Пример #8
0
 def check_files(self, files, task_id):
     for file in files:
         file_localpath = "files/" + file
         query = copy_and_set_token(dict_getFile,
                                    self.config.get_value('token'))
         query['taskId'] = task_id
         query['file'] = file
         req = JsonRequest(query)
         ans = req.execute()
         if ans is None:
             logging.error("Failed to get file!")
             sleep(5)
             return False
         elif ans['response'] != 'SUCCESS':
             logging.error("Getting of file failed: " + str(ans))
             sleep(5)
             return False
         else:
             file_size = int(ans['filesize'])
             if os.path.isfile(file_localpath) and os.stat(
                     file_localpath).st_size == file_size:
                 continue
             elif self.config.get_value('multicast'):
                 sleep(
                     5
                 )  # in case the file is not there yet (or not completely), we just wait some time and then try again
                 return False
             # TODO: we might need a better check for this
             if os.path.isfile(file_localpath.replace(".7z", ".txt")):
                 continue
             if self.config.get_value('rsync') and Initialize.get_os() != 1:
                 Download.rsync(
                     self.config.get_value('rsync-path') + '/' + file,
                     file_localpath)
             else:
                 Download.download(
                     self.config.get_value('url').replace(
                         "api/server.php", "") + ans['url'], file_localpath)
             if os.path.isfile(file_localpath) and os.stat(
                     file_localpath).st_size != file_size:
                 logging.error("file size mismatch on file: %s" % file)
                 sleep(5)
                 return False
             if os.path.splitext("files/" +
                                 file)[1] == '.7z' and not os.path.isfile(
                                     "files/" +
                                     file.replace(".7z", ".txt")):
                 # extract if needed
                 if Initialize.get_os() != 1:
                     os.system("./7zr" + Initialize.get_os_extension() +
                               " x -aoa -ofiles/ -y files/" + file)
                 else:
                     os.system("7zr" + Initialize.get_os_extension() +
                               " x -aoa -ofiles/ -y files/" + file)
     return True
    def __init__(self, cracker_id, binary_download):
        self.config = Config()
        self.io_q = Queue()
        self.version_string = ""

        # Build cracker executable name by taking basename plus extension
        self.executable_name = binary_download.get_version()['executable']
        k = self.executable_name.rfind(".")
        self.executable_name = self.executable_name[:k] + "." + self.executable_name[k + 1:]
        self.cracker_path = "crackers/" + str(cracker_id) + "/"
        self.callPath = self.executable_name
        if Initialize.get_os() != 1:
            self.callPath = "./" + self.callPath

		# Symlink hashcat.osx in macOS
        if not os.path.isfile(self.cracker_path + "hashcat.osx"):  # in case it's not the
            if Initialize.get_os() == 2: # macOS
                try:
                    output = subprocess.check_output("ln -s $(which hashcat) hashcat.osx", shell=True, cwd=self.cracker_path)
                except subprocess.CalledProcessError as e:
                    logging.error("Error during version detection: " + str(e))
                    sleep(5)
		
        if not os.path.isfile(self.cracker_path + self.callPath):  # in case it's not the new hashcat filename, try the old one (hashcat<bit>.<ext>)
            self.executable_name = binary_download.get_version()['executable']
            k = self.executable_name.rfind(".")
            self.executable_name = self.executable_name[:k] + get_bit() + "." + self.executable_name[k + 1:]
            self.cracker_path = "crackers/" + str(cracker_id) + "/"
            self.callPath = self.executable_name
            if Initialize.get_os() != 1:
                self.callPath = "./" + self.callPath

        cmd = self.callPath + " --version"
        output = ''
        try:
            logging.debug("CALL: " + cmd)
            output = subprocess.check_output(cmd, shell=True, cwd=self.cracker_path)
        except subprocess.CalledProcessError as e:
            logging.error("Error during version detection: " + str(e))
            sleep(5)
        self.version_string = output.decode().replace('v', '')

        self.lock = Lock()
        self.cracks = []
        self.first_status = False
        self.usePipe = False
        self.progressVal = 0
        self.statusCount = 0
        self.last_update = 0
        self.uses_slow_hash_flag = False
        self.wasStopped = False
    def run_chunk(self, task, chunk, preprocessor):
        if 'enforcePipe' in task and task['enforcePipe']:
            logging.info("Enforcing pipe command because of task setting...")
            self.usePipe = True
        if 'usePrince' in task and task['usePrince']:  # DEPRECATED
            full_cmd = self.build_prince_command(task, chunk)
        elif 'usePreprocessor' in task and task['usePreprocessor']:
            full_cmd = self.build_preprocessor_command(task, chunk, preprocessor)
        elif self.usePipe:
            full_cmd = self.build_pipe_command(task, chunk)
        else:
            full_cmd = self.build_command(task, chunk)
        self.statusCount = 0
        self.wasStopped = False
        if Initialize.get_os() == 1:
            full_cmd = full_cmd.replace("/", '\\')
        # clear old found file - earlier we deleted them, but just in case, we just move it to a unique filename if configured so
        if os.path.exists("hashlists/" + str(task['hashlistId']) + ".out"):
            if self.config.get_value('outfile-history'):
                os.rename("hashlists/" + str(task['hashlistId']) + ".out", "hashlists/" + str(task['hashlistId']) + "_" + str(time.time()) + ".out")
            else:
                os.unlink("hashlists/" + str(task['hashlistId']) + ".out")
        # create zap folder
        if not os.path.exists("hashlist_" + str(task['hashlistId'])):
            os.mkdir("hashlist_" + str(task['hashlistId']))
        logging.debug("CALL: " + full_cmd)
        if Initialize.get_os() != 1:
            process = subprocess.Popen(full_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.cracker_path, preexec_fn=os.setsid)
        else:
            process = subprocess.Popen(full_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.cracker_path)

        logging.debug("started cracking")
        out_thread = Thread(target=self.stream_watcher, name='stdout-watcher', args=('OUT', process.stdout))
        err_thread = Thread(target=self.stream_watcher, name='stderr-watcher', args=('ERR', process.stderr))
        crk_thread = Thread(target=self.output_watcher, name='crack-watcher', args=("hashlists/" + str(task['hashlistId']) + ".out", process))
        out_thread.start()
        err_thread.start()
        crk_thread.start()
        self.first_status = False
        self.last_update = time.time()

        main_thread = Thread(target=self.run_loop, name='run_loop', args=(process, chunk, task))
        main_thread.start()

        # wait for all threads to finish
        process.wait()
        crk_thread.join()
        out_thread.join()
        err_thread.join()
        main_thread.join()
        logging.info("finished chunk")
Пример #11
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 build_preprocessor_command(self, task, chunk, preprocessor):
        binary = "../../preprocessor/" + str(task['preprocessor']) + "/" + 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]

        # in case the skip or limit command are not available, we try to achieve the same with head/tail (the more chunks are run, the more inefficient it might be)
        if preprocessor['skipCommand'] is not None and preprocessor['limitCommand'] is not None:
            pre_args = " " + preprocessor['skipCommand'] + " " + str(chunk['skip']) + " " + preprocessor['limitCommand'] + " " + str(chunk['length']) + ' '
        else:
            pre_args = ""

        pre_args += ' ' + update_files(task['preprocessorCommand'])

        # TODO: add support for windows as well (pre-built tools)
        if preprocessor['skipCommand'] is None or preprocessor['limitCommand'] is None:
            pre_args += " | head -n " + str(chunk['skip'] + chunk['length']) + " | tail -n " + str(chunk['length'])

        post_args = " --machine-readable --quiet --status --remove --restore-disable --potfile-disable --session=hashtopolis"
        post_args += " --status-timer " + str(task['statustimer'])
        post_args += " --outfile-check-timer=" + str(task['statustimer'])
        post_args += " --outfile-check-dir=../../hashlist_" + str(task['hashlistId'])
        post_args += " -o ../../hashlists/" + str(task['hashlistId']) + ".out --outfile-format=" + self.get_outfile_format() + " -p \"" + str(chr(9)) + "\""
        post_args += " --remove-timer=" + str(task['statustimer'])
        post_args += " ../../hashlists/" + str(task['hashlistId'])
        post_args += update_files(task['attackcmd']).replace(task['hashlistAlias'], '')
        return binary + pre_args + " | " + self.callPath + post_args + task['cmdpars']
Пример #13
0
 def build_prince_command(self, task, chunk):
     binary = "../../prince/pp64."
     if Initialize.get_os() != 1:
         binary = "./" + binary + "bin"
     else:
         binary += "exe"
     pre_args = " -s " + str(chunk['skip']) + " -l " + str(
         chunk['length']) + ' '
     pre_args += get_wordlist(
         update_files(task['attackcmd']).replace(task['hashlistAlias'], ''))
     post_args = " --machine-readable --quiet --status --remove --restore-disable --potfile-disable --session=hashtopolis"
     post_args += " --status-timer " + str(task['statustimer'])
     post_args += " --outfile-check-timer=" + str(task['statustimer'])
     post_args += " --outfile-check-dir=../../hashlist_" + str(
         task['hashlistId'])
     post_args += " -o ../../hashlists/" + str(
         task['hashlistId']
     ) + ".out --outfile-format=" + self.get_outfile_format() + " "
     post_args += " --remove-timer=" + str(task['statustimer'])
     post_args += " ../../hashlists/" + str(task['hashlistId'])
     post_args += get_rules_and_hl(update_files(task['attackcmd']),
                                   task['hashlistAlias']).replace(
                                       task['hashlistAlias'], '')
     return binary + pre_args + " | " + self.callPath + post_args + task[
         'cmdpars']
Пример #14
0
 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])
Пример #15
0
    def download(url, output, no_header=False):
        try:
            session = Session().s
            if Initialize.get_os() == 1:
                output = output.replace("/", '\\')

            # Check header
            if not no_header:
                head = session.head(url)
                # not sure if we only should allow 200/302, but then it's present for sure
                if head.status_code != 200 and head.status_code != 302:
                    return False

            with open(output, "wb") as file:
                response = session.get(url, stream=True)
                total_length = response.headers.get('Content-Length')

                if total_length is None:  # no content length header
                    file.write(response.content)
                else:
                    dl = 0
                    total_length = int(total_length)
                    for data in response.iter_content(chunk_size=4096):
                        dl += len(data)
                        file.write(data)
                        done = int(50 * dl / total_length)
                        sys.stdout.write("\rDownloading: [%s%s]" %
                                         ('=' * done, ' ' * (50 - done)))
                        sys.stdout.flush()
            sys.stdout.write("\n")
            return True
        except requests.exceptions.ConnectionError as e:
            logging.error("Download error: " + str(e))
            sleep(30)
            return False
Пример #16
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):
     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'])
Пример #18
0
    def run_chunk(self, task, chunk, preprocessor):
        args = " crack -s " + str(chunk['skip'])
        args += " -l " + str(chunk['length'])
        args += " " + task['attackcmd'].replace(
            task['hashlistAlias'], "../hashlists/" + str(task['hashlistId']))
        full_cmd = self.callPath + args
        if Initialize.get_os() == 1:
            full_cmd = full_cmd.replace("/", '\\')
        logging.debug("CALL: " + full_cmd)
        process = subprocess.Popen(full_cmd,
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   cwd='files')

        logging.debug("started cracking")
        out_thread = Thread(target=self.stream_watcher,
                            name='stdout-watcher',
                            args=('OUT', process.stdout))
        err_thread = Thread(target=self.stream_watcher,
                            name='stderr-watcher',
                            args=('ERR', process.stderr))
        out_thread.start()
        err_thread.start()

        main_thread = Thread(target=self.run_loop,
                             name='run_loop',
                             args=(process, chunk, task))
        main_thread.start()

        # wait for all threads to finish
        process.wait()
        out_thread.join()
        err_thread.join()
        logging.info("finished chunk")
 def run_health_check(self, attack, hashlist_alias):
     args = " --machine-readable --quiet"
     args += " --restore-disable --potfile-disable --session=health "
     args += update_files(attack).replace(hashlist_alias, "../../hashlists/health_check.txt")
     args += " -o ../../hashlists/health_check.out"
     full_cmd = self.callPath + args
     if Initialize.get_os() == 1:
         full_cmd = full_cmd.replace("/", '\\')
     logging.debug("CALL: " + full_cmd)
     proc = subprocess.Popen(full_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.cracker_path)
     output, error = proc.communicate()
     logging.debug("Started health check attack")
     # wait until done, on the health check we don't send any update during running. Maybe later we could at least
     # introduce some heartbeat update to make visible that the agent is still alive.
     proc.wait()
     errors = []
     states = []
     if error:
         error = escape_ansi(error.replace(b"\r\n", b"\n").decode('utf-8'))
         error = error.split('\n')
         for line in error:
             if not line:
                 continue
             errors.append(line)
     if output:
         output = escape_ansi(output.replace(b"\r\n", b"\n").decode('utf-8'))
         output = output.split('\n')
         for line in output:
             if not line:
                 continue
             logging.debug(line)
             status = HashcatStatus(line)
             if status.is_valid():
                 states.append(status)
     return [states, errors]
Пример #20
0
 def check_client_version(self):
     if self.args.disable_update:
         return
     if os.path.isfile("old.zip"):
         os.unlink("old.zip")  # cleanup old version
     query = copy_and_set_token(dict_checkVersion, self.config.get_value('token'))
     query['version'] = Initialize.get_version_number()
     req = JsonRequest(query)
     ans = req.execute()
     if ans is None:
         logging.error("Agent version check failed!")
     elif ans['response'] != 'SUCCESS':
         logging.error("Error from server: " + str(ans['message']))
     else:
         if ans['version'] == 'OK':
             logging.info("Client is up-to-date!")
         else:
             url = ans['url']
             if not url:
                 logging.warning("Got empty URL for client update!")
             else:
                 logging.info("New client version available!")
                 if os.path.isfile("update.zip"):
                     os.unlink("update.zip")
                 Download.download(url, "update.zip")
                 if os.path.isfile("update.zip") and os.path.getsize("update.zip"):
                     if os.path.isfile("old.zip"):
                         os.unlink("old.zip")
                     os.rename("hashtopolis.zip", "old.zip")
                     os.rename("update.zip", "hashtopolis.zip")
                     logging.info("Update received, restarting client...")
                     if os.path.exists("lock.pid"):
                         os.unlink("lock.pid")
                     os.execl(sys.executable, sys.executable, "hashtopolis.zip")
                     exit(0)
Пример #21
0
    def run_chunk(self, task, chunk):
        args = " --machine-readable --quiet --status --remove --restore-disable --potfile-disable --session=hashtopolis"
        args += " --status-timer " + str(task['statustimer'])
        args += " --outfile-check-timer=" + str(task['statustimer'])
        args += " --outfile-check-dir=../hashlist_" + str(task['hashlistId'])
        args += " -o ../../hashlists/" + str(task['hashlistId']) + ".out"
        args += " --remove-timer=" + str(task['statustimer'])
        args += " -s " + str(chunk['skip'])
        args += " -l " + str(chunk['length'])
        args += " " + update_files(task['attackcmd']).replace(task['hashlistAlias'], "../../hashlists/" + str(task['hashlistId']))
        full_cmd = self.callPath + args
        if Initialize.get_os() == 1:
            full_cmd = full_cmd.replace("/", '\\')
        # clear old found file
        if os.path.exists("hashlists/" + str(task['hashlistId']) + ".out"):
            os.remove("hashlists/" + str(task['hashlistId']) + ".out")
        # create zap folder
        if not os.path.exists("hashlist_" + str(task['hashlistId'])):
            os.mkdir("hashlist_" + str(task['hashlistId']))
        logging.debug("CALL: " + full_cmd)
        if Initialize.get_os() != 1:
            proc = subprocess.Popen(full_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.cracker_path, preexec_fn=os.setsid)
        else:
            proc = subprocess.Popen(full_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.cracker_path)

        logging.debug("started cracking")
        out_thread = Thread(target=self.stream_watcher, name='stdout-watcher', args=('OUT', proc.stdout))
        err_thread = Thread(target=self.stream_watcher, name='stderr-watcher', args=('ERR', proc.stderr))
        crk_thread = Thread(target=self.output_watcher, name='crack-watcher', args=("hashlists/" + str(task['hashlistId']) + ".out", proc))
        out_thread.start()
        err_thread.start()
        crk_thread.start()
        self.first_status = False
        self.last_update = time.time()

        main_thread = Thread(target=self.run_loop, name='run_loop', args=(proc, chunk, task))
        main_thread.start()

        # wait for all threads to finish
        proc.wait()
        crk_thread.join()
        out_thread.join()
        err_thread.join()
        main_thread.join()
        logging.info("finished chunk")
Пример #22
0
    def run_benchmark(self, task):
        if task['benchType'] == 'speed':
            # do a speed benchmark
            return self.run_speed_benchmark(task)

        args = " --machine-readable --quiet --runtime=" + str(task['bench'])
        args += " --restore-disable --potfile-disable --session=hashtopolis -p \"" + str(
            chr(9)) + "\" "
        args += update_files(task['attackcmd']).replace(
            task['hashlistAlias'], "../../hashlists/" +
            str(task['hashlistId'])) + ' ' + task['cmdpars']
        args += " -o ../../hashlists/" + str(task['hashlistId']) + ".out"
        full_cmd = self.callPath + args
        if Initialize.get_os() == 1:
            full_cmd = full_cmd.replace("/", '\\')
        logging.debug("CALL: " + full_cmd)
        proc = subprocess.Popen(full_cmd,
                                shell=True,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                cwd=self.cracker_path)
        output, error = proc.communicate()
        logging.debug("started benchmark")
        proc.wait()  # wait until done
        if error:
            error = escape_ansi(error.replace(b"\r\n", b"\n").decode('utf-8'))
            # parse errors and send it to server
            error = error.split('\n')
            for line in error:
                if not line:
                    continue
                query = copy_and_set_token(dict_clientError,
                                           self.config.get_value('token'))
                query['taskId'] = task['taskId']
                query['message'] = line
                req = JsonRequest(query)
                req.execute()
            # return 0  it might not be ideal to return here.  In case of errors still try to read the benchmark.
        if output:
            output = output.replace(b"\r\n", b"\n").decode('utf-8')
            output = output.split('\n')
            last_valid_status = None
            for line in output:
                if not line:
                    continue
                logging.debug("HCSTAT: " + line.strip())
                status = HashcatStatus(line)
                if status.is_valid():
                    last_valid_status = status
            if last_valid_status is None:
                return 0
            # we just calculate how far in the task the agent went during the benchmark time
            return (last_valid_status.get_progress() -
                    last_valid_status.get_rejected()) / float(
                        last_valid_status.get_progress_total())
        return 0
 def check_prince(self):
     logging.debug("Checking if PRINCE is present...")
     path = "prince/"
     if os.path.isdir(
             path):  # if it already exists, we don't need to download it
         logging.debug("PRINCE is already downloaded")
         return True
     logging.debug("PRINCE not found, download...")
     query = copy_and_set_token(dict_downloadBinary,
                                self.config.get_value('token'))
     query['type'] = 'prince'
     req = JsonRequest(query)
     ans = req.execute()
     if ans is None:
         logging.error("Failed to load prince!")
         sleep(5)
         return False
     elif ans['response'] != 'SUCCESS' or not ans['url']:
         logging.error("Getting prince failed: " + str(ans))
         sleep(5)
         return False
     else:
         if not Download.download(ans['url'], "prince.7z"):
             logging.error("Download of prince failed!")
             sleep(5)
             return False
         if Initialize.get_os() == 1:
             os.system("7zr" + Initialize.get_os_extension() +
                       " x -otemp prince.7z")
         else:
             os.system("./7zr" + Initialize.get_os_extension() +
                       " x -otemp prince.7z")
         for name in os.listdir(
                 "temp"
         ):  # this part needs to be done because it is compressed with the main subfolder of prince
             if os.path.isdir("temp/" + name):
                 os.rename("temp/" + name, "prince")
                 break
         os.unlink("prince.7z")
         os.rmdir("temp")
         logging.debug("PRINCE downloaded and extracted")
     return True
Пример #24
0
def init():
    global CONFIG, binaryDownload
    logformat  = '[%(asctime)s] [%(levelname)-5s] %(message)s'
    dateformat = '%Y-%m-%d %H:%M:%S'
    logfile  = 'client.log'
    loglevel = logging.INFO

    logging.getLogger("requests").setLevel(logging.WARNING)

    CONFIG = Config()
    if CONFIG.get_value('debug'):
        loglevel = logging.DEBUG
        logging.getLogger("requests").setLevel(logging.DEBUG)
    logging.basicConfig(filename=logfile, level=loglevel, format=logformat, datefmt=dateformat)
    logging.getLogger().addHandler(logging.StreamHandler())

    logging.info("Starting client '" + Initialize.get_version() + "'...")

    # connection initialization
    Initialize().run()
    # download and updates
    binaryDownload = BinaryDownload()
    binaryDownload.run()
Пример #25
0
 def __init__(self, cracker_id, binary_download):
     self.config = Config()
     self.io_q = Queue()
     self.executable_name = binary_download.get_version()['executable']
     k = self.executable_name.rfind(".")
     self.executable_name = self.executable_name[:k] + get_bit() + "." + self.executable_name[k + 1:]
     self.cracker_path = "crackers/" + str(cracker_id) + "/"
     self.callPath = self.executable_name
     if Initialize.get_os() != 1:
         self.callPath = "./" + self.callPath
     self.lock = Lock()
     self.cracks = []
     self.first_status = False
     self.last_update = 0
Пример #26
0
 def measure_keyspace(self, task, chunk):
     full_cmd = self.callPath + " keyspace " + task['attackcmd'].replace(
         "-a " + task['hashlistAlias'] + " ", "")
     if Initialize.get_os() == 1:
         full_cmd = full_cmd.replace("/", '\\')
     output = subprocess.check_output(full_cmd, shell=True, cwd='files')
     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'])
Пример #27
0
 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'])
Пример #28
0
 def run_benchmark(self, task):
     ksp = self.keyspace
     if ksp == 0:
         ksp = task['keyspace']
     args = task['attackcmd'].replace(
         task['hashlistAlias'], "../hashlists/" + str(task['hashlistId']))
     full_cmd = self.callPath + " crack " + args + " -s 0 -l " + str(
         ksp) + " --timeout=" + str(task['bench'])
     if Initialize.get_os() == 1:
         full_cmd = full_cmd.replace("/", '\\')
     logging.debug("CALL: " + full_cmd)
     output = subprocess.check_output(full_cmd, shell=True, cwd='files')
     if output:
         output = output.replace(b"\r\n", b"\n").decode('utf-8')
         output = output.split('\n')
         last_valid_status = None
         for line in output:
             if not line:
                 continue
             status = GenericStatus(line)
             if status.is_valid():
                 last_valid_status = status
         if last_valid_status is None:
             query = copy_and_set_token(dict_clientError,
                                        self.config.get_value('token'))
             query['taskId'] = task['taskId']
             query['message'] = "Generic benchmark failed!"
             req = JsonRequest(query)
             req.execute()
             return 0
         return float(last_valid_status.get_progress()) / 10000
     else:
         query = copy_and_set_token(dict_clientError,
                                    self.config.get_value('token'))
         query['taskId'] = task['taskId']
         query['message'] = "Generic benchmark gave no output!"
         req = JsonRequest(query)
         req.execute()
     return 0
    def __init__(self, cracker_id, binary_download):
        self.config = Config()
        self.io_q = Queue()

        # Build cracker executable name by taking basename and adding 32/64 plus extension
        self.executable_name = binary_download.get_version()['executable']
        k = self.executable_name.rfind(".")
        self.executable_name = self.executable_name[:k] + get_bit(
        ) + "." + self.executable_name[k + 1:]
        self.cracker_path = "crackers/" + str(cracker_id) + "/"
        self.callPath = self.executable_name
        if Initialize.get_os() != 1:
            self.callPath = "./" + self.callPath

        self.lock = Lock()
        self.cracks = []
        self.first_status = False
        self.usePipe = False
        self.progressVal = 0
        self.statusCount = 0
        self.last_update = 0
        self.uses_slow_hash_flag = False
        self.wasStopped = False
Пример #30
0
 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'])