Exemple #1
0
    def hybrid_attack(self,
                      *,
                      hash_types: List[str],
                      hashes_file: str,
                      inverse: bool = False,
                      wordlists: List[str],
                      masks: List[str] = None,
                      masks_file: Path = None,
                      sleep: int = 1,
                      slurm: Slurm,
                      local: bool = False,
                      db_status: bool = False,
                      workspace: str = None,
                      db_credential_file: Path = None):
        """
        hybrid attack using hashcat submiting parallel tasks in a cluster with Slurm

        Args:
        hash_type (str): Hashcat's hash type
        hashes_file (str): Hash file to attack
        inverse (bool): If inverse is false the attack combine WORDLISTS + MASKS, otherwise it combine MASKS + WORDLISTS
        wordlists (List[str]): wordlists to attack
        masks (List[str]): masks to attack
        masks_file (str): masks file to attack
        slurm (Slurm): Instance of Slurm class
        """

        #import pdb; pdb.set_trace()
        if self.enable:
            try:
                if not inverse:
                    attack_mode = 6
                else:
                    attack_mode = 7

                permission = [os.R_OK]
                Path.access(permission, hashes_file, *wordlists)
                Hashcat.check_hash_type(hash_types)

                if masks and masks_file:
                    raise Exception("Only supplied masks or a masks file")

                elif masks:
                    valid_masks = []
                    for mask in masks:
                        if Mask.is_mask(mask):
                            valid_masks.append(mask)

                    if not valid_masks:
                        raise Exception("No valid masks supplied")
                    masks = valid_masks

                else:  # masks_file supplied
                    Path.access(permission, masks_file)
                    masks = []
                    with open(masks_file, 'r') as _masks_file:
                        while mask := _masks_file.readline().rstrip():
                            if Mask.is_mask(mask):
                                masks.append(mask)

                if not inverse:
                    print_status(
                        f"Attacking hashes in {ColorStr(hashes_file).StyleBRIGHT} file in hibrid mode {ColorStr('WORDLISTS + MASKS').StyleBRIGHT} "
                    )
                else:
                    print_status(
                        f"Attacking hashes in {ColorStr(hashes_file).StyleBRIGHT} file in hibrid mode {ColorStr('MASKS + WORDLISTS').StyleBRIGHT}"
                    )

                print_status(f"Wordlists: {ColorStr(wordlists).StyleBRIGHT}")
                if masks and masks_file is None:
                    print_status(f"Masks: {ColorStr(masks).StyleBRIGHT}")
                else:
                    print_status(
                        f"Masks file: {ColorStr(masks_file).StyleBRIGHT}")

                hash_types_names = [
                    Hashcat.HASHES[hash_type]['Name']
                    for hash_type in hash_types
                ]
                print_status(
                    f"Possible hashes identities: {ColorStr(hash_types_names).StyleBRIGHT}"
                )

                #import pdb; pdb.set_trace()
                if (not local) and slurm and slurm.partition:

                    parallel_job_type = slurm.parallel_job_parser()
                    if not parallel_job_type in ["GPU"]:
                        raise InvalidParallelJob(parallel_job_type)

                    parallel_work = []
                    for hash_type in hash_types:
                        for wordlist in wordlists:
                            for mask in masks:
                                if not inverse:
                                    attack_cmd = (
                                        f"{self.main_exec}"
                                        f" -a {attack_mode}"
                                        f" -m {hash_type}"
                                        f" {hashes_file} {wordlist} {mask}")
                                else:
                                    attack_cmd = (
                                        f"{self.main_exec}"
                                        f" -a {attack_mode}"
                                        f" -m {hash_type}"
                                        f" {hashes_file} {mask} {wordlist}")

                                header_attack = f"echo -e '\\n\\n[*] Running: {attack_cmd}'"

                                if db_status and workspace and db_credential_file:
                                    insert_cracked_hashes = (
                                        f"amadb -c {db_credential_file} -w {workspace}"
                                        f" --cracker {Hashcat.MAINNAME} -j {hashes_file}"
                                    )

                                    parallel_work.append(
                                        (header_attack, attack_cmd,
                                         insert_cracked_hashes))
                                else:
                                    parallel_work.append(
                                        (header_attack, attack_cmd))

                    slurm_script_name = slurm.gen_batch_script(parallel_work)
                    #import pdb; pdb.set_trace()
                    Bash.exec(f"sbatch {slurm_script_name}")

                else:
                    #import pdb; pdb.set_trace()
                    all_cracked = False

                    for hash_type in hash_types:
                        for wordlist in wordlists:
                            for mask in masks:
                                all_cracked = Hashcat.are_all_hashes_cracked(
                                    hashes_file)
                                if not all_cracked:  # some hash isn't cracked yet
                                    if not inverse:
                                        attack_cmd = (
                                            f"{self.main_exec}"
                                            f" -a {attack_mode}"
                                            f" -m {hash_type}"
                                            f" {hashes_file} {wordlist} {mask}"
                                        )
                                    else:
                                        attack_cmd = (
                                            f"{self.main_exec}"
                                            f" -a {attack_mode}"
                                            f" -m {hash_type}"
                                            f" {hashes_file} {mask} {wordlist}"
                                        )

                                    print()
                                    print_status(
                                        f"Running: {ColorStr(attack_cmd).StyleBRIGHT}"
                                    )
                                    Bash.exec(attack_cmd)
                                    if sleep > 0:
                                        print_status(
                                            f"{ColorStr('Sleeping ...').StyleBRIGHT}"
                                        )
                                        time.sleep(sleep)

                                else:
                                    print_successful(
                                        f"Hashes in {ColorStr(hashes_file).StyleBRIGHT} were cracked"
                                    )
                                    break
                            if all_cracked:
                                break
                        if all_cracked:
                            break

                    #import pdb; pdb.set_trace()
                    if db_status and workspace and db_credential_file:
                        Hashcat.insert_hashes_to_db(hashes_file, workspace,
                                                    db_credential_file)

            except Exception as error:
                print_failure(error)
Exemple #2
0
    def masks_attack(self,
                     *,
                     hash_types: List[int],
                     hashes_file: str,
                     masks_file: str,
                     masks_attack_script: str,
                     sleep: int = 1,
                     slurm: Slurm,
                     local: bool = False,
                     db_status: bool = False,
                     workspace: str = None,
                     db_credential_file: Path = None):
        """
        Masks attack using hashcat submitting parallel tasks in a cluster with Slurm

        Args:
        hash_type (str): Jonh's hash type
        hashes_file (str): Hash file to attack
        masks_file (str): Masks file to attack
        slurm (Slurm): Instance of Slurm class
        """

        #import pdb; pdb.set_trace()

        if self.enable:
            try:
                attack_mode = 3
                permission = [os.R_OK]
                Path.access(permission, hashes_file, masks_file)
                Hashcat.check_hash_type(hash_types)

                print_status(
                    f"Attacking hashes in {ColorStr(hashes_file).StyleBRIGHT} file with {ColorStr(masks_file).StyleBRIGHT} masks file."
                )
                hash_types_names = [
                    Hashcat.HASHES[hash_type]['Name']
                    for hash_type in hash_types
                ]
                print_status(
                    f"Possible hashes identities: {ColorStr(hash_types_names).StyleBRIGHT}"
                )

                if (not local) and slurm and slurm.partition:
                    Hashcat.gen_masks_attack(
                        hash_types=hash_types,
                        hashes_file=hashes_file,
                        masks_file=masks_file,
                        masks_attack_script=masks_attack_script,
                        slurm=slurm,
                        db_status=db_status,
                        workspace=workspace,
                        db_credential_file=db_credential_file)

                    parallel_work = [(f"python3 {masks_attack_script}", )]
                    slurm_script_name = slurm.gen_batch_script(parallel_work)
                    #import pdb; pdb.set_trace()
                    Bash.exec(f"sbatch {slurm_script_name}")

                else:
                    #import pdb; pdb.set_trace()
                    all_cracked = False
                    for hash_type in hash_types:
                        with open(masks_file, 'r') as masks:
                            while mask := masks.readline().rstrip():
                                if not Mask.is_mask(mask):
                                    print_failure("Invalid mask: {mask}")
                                    break

                                all_cracked = Hashcat.are_all_hashes_cracked(
                                    hashes_file)
                                if not all_cracked:
                                    attack_cmd = (f"{self.main_exec}"
                                                  f" -a {attack_mode}"
                                                  f" -m {hash_type}"
                                                  f" {hashes_file} {mask}")

                                    print()
                                    print_status(
                                        f"Running: {ColorStr(attack_cmd).StyleBRIGHT}"
                                    )
                                    Bash.exec(attack_cmd)
                                    if sleep > 0:
                                        print_status(
                                            f"{ColorStr('Sleeping ...').StyleBRIGHT}"
                                        )
                                        time.sleep(sleep)

                                else:
                                    break  #all hashes were cracked so stop attack

                        if all_cracked := Hashcat.are_all_hashes_cracked(
                                hashes_file):
                            print_successful(
                                f"Hashes in {ColorStr(hashes_file).StyleBRIGHT} were cracked"
                            )
                            break

                    #import pdb; pdb.set_trace()
                    if db_status and workspace and db_credential_file:
                        Hashcat.insert_hashes_to_db(hashes_file, workspace,
                                                    db_credential_file)
Exemple #3
0
    def brute_force_attack(self,
                           *,
                           hash_types: str,
                           hashes_file: str,
                           mask: str,
                           sleep: int = 1,
                           slurm: Slurm,
                           local: bool = False,
                           db_status: bool = False,
                           workspace: str = None,
                           db_credential_file: Path = None):
        """
        Brute force attack using hashcat submiting parallel tasks in a cluster with Slurm

        Args:
        hash_type (str): Hashcat's hash type
        hashes_file (str): Hash file to attack
        mask (str): mask to attack
        slurm (Slurm): Instance of Slurm class
        """

        #import pdb; pdb.set_trace()
        if self.enable:
            try:
                attack_mode = 3
                permission = [os.R_OK]
                Mask.is_valid_mask(mask)
                Path.access(permission, hashes_file)
                Hashcat.check_hash_type(hash_types)

                print_status(
                    f"Attacking hashes in {ColorStr(hashes_file).StyleBRIGHT} file with {ColorStr(mask).StyleBRIGHT} mask"
                )

                hash_types_names = [
                    Hashcat.HASHES[hash_type]['Name']
                    for hash_type in hash_types
                ]
                print_status(
                    f"Possible hashes identities: {ColorStr(hash_types_names).StyleBRIGHT}"
                )

                if (not local) and slurm and slurm.partition:

                    parallel_job_type = slurm.parallel_job_parser()
                    if not parallel_job_type in ["GPU"]:
                        raise InvalidParallelJob(parallel_job_type)

                    parallel_work = []
                    for hash_type in hash_types:
                        attack_cmd = (f"srun {self.main_exec}"
                                      f" -a {attack_mode}"
                                      f" -m {hash_type}"
                                      f" {hashes_file} {mask}")

                        header_attack = f"echo -e '\\n\\n[*] Running: {attack_cmd}'"

                        if db_status and workspace and db_credential_file:
                            insert_cracked_hashes = (
                                f"amadb -c {db_credential_file} -w {workspace}"
                                f" --cracker {Hashcat.MAINNAME} -j {hashes_file}"
                            )

                            parallel_work.append((header_attack, attack_cmd,
                                                  insert_cracked_hashes))
                        else:
                            parallel_work.append((header_attack, attack_cmd))

                    slurm_script_name = slurm.gen_batch_script(parallel_work)
                    #import pdb;pdb.set_trace()
                    Bash.exec(f"sbatch {slurm_script_name}")

                else:
                    #import pdb;pdb.set_trace()
                    for hash_type in hash_types:
                        are_all_hashes_cracked = Hashcat.are_all_hashes_cracked(
                            hashes_file)
                        if not are_all_hashes_cracked:  # some hash isn't cracked yet
                            attack_cmd = (f"{self.main_exec}"
                                          f" -a {attack_mode}"
                                          f" -m {hash_type}"
                                          f" {hashes_file} {mask}")

                            print()
                            print_status(
                                f"Running: {ColorStr(attack_cmd).StyleBRIGHT}")
                            Bash.exec(attack_cmd)
                            if sleep > 0:
                                print_status(
                                    f"{ColorStr('Sleeping ...').StyleBRIGHT}")
                                time.sleep(sleep)

                        else:
                            print_successful(
                                f"Hashes in {ColorStr(hashes_file).StyleBRIGHT} were cracked"
                            )
                            break

                    #import pdb;pdb.set_trace()
                    if db_status and workspace and db_credential_file:
                        Hashcat.insert_hashes_to_db(hashes_file, workspace,
                                                    db_credential_file)

            except Exception as error:
                print_failure(error)

        else:
            print_failure(
                f"Cracker {ColorStr(self.main_name).StyleBRIGHT} is disable")
Exemple #4
0
    def masks_attack(self, *,
                     hash_types: List[str] = None, hashes_file: Path, masks_file: Path,
                     slurm: Slurm, local: bool = False,
                     db_status:bool = False, workspace:str = None, db_credential_file: Path = None):
        """
        Masks attack using john submiting parallel tasks in a cluster with Slurm

        Args:
        hash_type (str): John's hash type
        hashes_file (str): Hash file to attack
        masks_file (str): Masks file
        mask_attack_script (str): Name for generated mask attack script
        slurm (Slurm): Instance of Slurm class
        """

        #import pdb; pdb.set_trace()

        if self.enable:
            try:
                permission = [os.R_OK]
                Path.access(permission, hashes_file, masks_file)
                if hash_types:
                    John.check_hash_type(hash_types)

                print_status(f"Attacking hashes in {ColorStr(hashes_file).StyleBRIGHT} file with {ColorStr(masks_file).StyleBRIGHT} masks file")
                print_status(f"Possible hashes identities: {ColorStr(hash_types).StyleBRIGHT}")

                if (not local) and slurm and slurm.partition:
                    self.check_slurm_partition(slurm.partition, slurm.config['partitions'])

                    parallel_job_type = slurm.parallel_job_parser()
                    if not  parallel_job_type in ["MPI", "OMP"]:
                        raise InvalidParallelJob(parallel_job_type)

                    array_tasks = slurm.sbatch['array'].value
                    if array_tasks is None:
                        array_tasks = 1


                    base_path = masks_file.parent
                    name_masks_file = masks_file.name
                    suffix = masks_file.suffix
                    if array_tasks > 1:
                        self.array_masks(masks_file, array_tasks)
                        only_name_masks_file = name_masks_file[:-len(suffix)]

                        for a in range(array_tasks):
                            name_split_masks_file = only_name_masks_file + str(a) + suffix
                            split_masks_file = Path.joinpath(base_path, name_split_masks_file)
                            print_status(f"(array id {a}) Processing: masks file = {split_masks_file}")

                        MASKS_FILE = only_name_masks_file + "${SLURM_ARRAY_TASK_ID}" + suffix

                    else:
                        MASKS_FILE = masks_file.name

                    MASKS_FILE = Path.joinpath(base_path, MASKS_FILE)
                    HASHES_FILE = hashes_file
                    HID = self.pylist2bash(hash_types)
                    #ARRAY = slurm.sbatch['array'].value

                    variable_definition_block = (
                        f"HASHES_FILE={HASHES_FILE}",
                        f"MASKS_FILE={MASKS_FILE}",
                        f"HID={HID}",
                        #f"ARRAY="
                    )

                    attack_cmd = f"{self.main_exec}"
                    attack_cmd += " --mask=${mask}"
                    attack_cmd += " --format=${hid}"

                    if parallel_job_type == "MPI":
                        attack_cmd = f"srun --mpi={slurm.pmix} "  + attack_cmd

                    elif parallel_job_type == "OMP":
                        attack_cmd = f"srun "  + attack_cmd

                    attack_cmd += " ${HASHES_FILE}"
                    header_attack = f"echo -e \"\\n\\n[*] Running: {attack_cmd}\""

                    insert_cracked_hashes = ''
                    if db_status and workspace and db_credential_file:
                        insert_cracked_hashes = (
                            f"amadb -c {db_credential_file} -w {workspace}"
                            f" --cracker {John.MAINNAME} -j {hashes_file}"
                        )

                    cracking_block = (
                        "while read mask",
                        "do",
                        "\tfor hid in ${HID[@]}; do",
                        "\t\t" + header_attack,
                        "\t\t" + attack_cmd,
                        "\t\t" + insert_cracked_hashes,
                        "\t\t" + "all_cracked=false",
                        "\t\t" + "if $all_cracked; then break; fi",
                        "\tdone",
                        "done < ${MASKS_FILE}"
                    )

                    parallel_work = (variable_definition_block,
                                         cracking_block)

                    slurm_script_name = slurm.gen_batch_script(parallel_work)
                    import pdb; pdb.set_trace()
                    Bash.exec(f"sbatch {slurm_script_name}")

                else:
                    all_cracked = False
                    for hash_type in hash_types:
                        with open(masks_file, 'r') as masks:
                            while mask := masks.readline().rstrip():
                                all_cracked = John.are_all_hashes_cracked(hashes_file)
                                if not all_cracked:
                                    attack_cmd = f"{self.main_exec} --mask={mask}"

                                    if hash_type:
                                        attack_cmd += f" --format={hash_type}"
                                    attack_cmd += f" {hashes_file}"

                                    print()
                                    print_status(f"Running: {ColorStr(attack_cmd).StyleBRIGHT}")
                                    Bash.exec(attack_cmd)

                                else:
                                    break

                        if all_cracked := John.are_all_hashes_cracked(hashes_file):
                            print_successful(f"Hashes in {ColorStr(hashes_file).StyleBRIGHT} were cracked")
                            break

                    if db_status and workspace and db_credential_file:
                        John.insert_hashes_to_db(hashes_file, workspace, db_credential_file, pretty=True)
Exemple #5
0
    def incremental_attack(self, *,
                           hash_types: List[str] = None, hashes_file: str,
                           slurm: Slurm , local:bool = False,
                           db_status:bool = False, workspace:str = None, db_credential_file: Path = None):
        """
        Incemental attack using john submiting parallel tasks in a cluster with Slurm

        Args:
        hash_type (str): John's hash type
        hashes_file (str): Hash file to attack
        slurm (Slurm): Instance of Slurm class
        """

        #import pdb; pdb.set_trace()

        if self.enable:
            try:
                permission = [os.R_OK]
                Path.access(permission, hashes_file)
                if hash_types:
                    John.check_hash_type(hash_types)

                print_status(f"Attacking hashes in {ColorStr(hashes_file).StyleBRIGHT} file in incremental mode")
                print_status(f"Possible hashes identities: {ColorStr(hash_types).StyleBRIGHT}")

                if (not local) and slurm and slurm.partition:
                    parallel_job_type = slurm.parallel_job_parser()
                    if not  parallel_job_type in ["MPI", "OMP"]:
                        raise InvalidParallelJob(parallel_job_type)

                    parallel_work = []
                    for hash_type in hash_types:
                        attack_cmd = f"{self.main_exec} --incremental"
                        if parallel_job_type == "MPI":
                            attack_cmd = f"srun --mpi={slurm.pmix} "  + attack_cmd

                        elif parallel_job_type == "OMP":
                            attack_cmd = f"srun "  + attack_cmd

                        if hash_type:
                            attack_cmd += f" --format={hash_type}"

                        attack_cmd += f" {hashes_file}"
                        header_attack = f"echo -e '\\n\\n[*] Running: {attack_cmd}'"

                        if db_status and workspace and db_credential_file:
                            insert_cracked_hashes = (
                                f"amadb -c {db_credential_file} -w {workspace}"
                                f" --cracker {John.MAINNAME} -j {hashes_file}"
                            )
                            parallel_work.append((header_attack, attack_cmd, insert_cracked_hashes))

                        else:
                            parallel_work.append((header_attack, attack_cmd))


                        slurm_script_name = slurm.gen_batch_script(parallel_work)
                        Bash.exec(f"sbatch {slurm_script_name}")

                else:
                    #import pdb;pdb.set_trace()
                    for hash_type in hash_types:
                        attack_cmd = f"{self.main_exec} --incremental"
                        if hash_type:
                            attack_cmd += f" --format={hash_type}"

                        attack_cmd += f" {hashes_file}"

                        if are_all_hashes_cracked := John.are_all_hashes_cracked(hashes_file):
                            print_successful(f"Hashes in {ColorStr(hashes_file).StyleBRIGHT} were cracked")
                            break

                        else: # some hash isn't cracked yet
                            print()
                            print_status(f"Running: {ColorStr(attack_cmd).StyleBRIGHT}")
                            Bash.exec(attack_cmd)

                    if db_status and workspace and db_credential_file:
                        John.insert_hashes_to_db(hashes_file, workspace, db_credential_file, pretty=True)

            except Exception as error:
                #cmd2.Cmd.pexcept(error)
                print_failure(error)

        else:
            print_failure(f"Cracker {ColorStr(self.main_name).StyleBRIGHT} is disable")
Exemple #6
0
    def wordlist_attack(self , *,
                        hash_types: List[str] = None , hashes_file: Path, wordlists: List[Path],
                        rules:str = None, rules_file:Path = None,
                        slurm: Slurm, local:bool = False,
                        db_status:bool = False, workspace:str = None, db_credential_file: Path = None):
        """
        Wordlist attack using john submiting parallel tasks in a cluster with Slurm

        Args:
        hash_type (str): Jonh's hash type
        hashes_file (str): Hash file to attack
        wordlist (str): wordlist to attack
        slurm (Slurm): Instance of Slurm class
        """

        #import pdb; pdb.set_trace()
        if self.enable:
            try:
                permission = [os.R_OK]
                Path.access(permission, hashes_file, *wordlists)

                if hash_types:
                    John.check_hash_type(hash_types)

                if rules and rules_file:
                    Path.access(permission, rules_file)

                    print_status(f"Attacking hashes in {ColorStr(hashes_file).StyleBRIGHT} file in wordlist mode")
                print_status(f"Wordlists: {ColorStr(wordlists).StyleBRIGHT}")
                print_status(f"Possible hashes identities: {ColorStr(hash_types).StyleBRIGHT}")


                if (not local) and slurm and slurm.partition:
                    #import pdb; pdb.set_trace()
                    self.check_slurm_partition(slurm.partition, slurm.config['partitions'])

                    parallel_job_type = slurm.parallel_job_parser()
                    if not  parallel_job_type in ["MPI", "OMP"]:
                        raise InvalidParallelJob(parallel_job_type)

                    hash_types_len = len(hash_types)
                    wordlists_len = len(wordlists)
                    array_tasks = slurm.sbatch['array'].value
                    #import pdb;pdb.set_trace()
                    if array_tasks is None:
                        array_tasks = 1

                    #debugged - date Apr 9
                    if  wordlists_len > 1: # hash_types_len >= 1

                        if array_tasks > 1:
                            if array_tasks > wordlists_len:
                                print_failure(f"These is more array jobs that work to process (ARRAY={array_tasks}, WLS={wordlists_len})")
                                print_status(f"Adjusting {ColorStr('ARRAY').StyleBRIGHT} to {wordlists_len} (1 job per wordlist)")
                                array_tasks = wordlists_len
                                slurm.set_option('array', array_tasks)

                            for array_task_id in range(array_tasks):
                                init = floor(wordlists_len/array_tasks)*array_task_id
                                if array_task_id == (array_tasks - 1):
                                    end = wordlists_len
                                else:
                                    end = floor(wordlists_len/array_tasks)*(array_task_id+1)

                                print_status(f"(array id {array_task_id}) Processing: wordlists={ColorStr(wordlists[init:end]).StyleBRIGHT}, hash_types={ColorStr('ALL').StyleBRIGHT}")

                            WLS = self.pylist2bash(wordlists)
                            HID = self.pylist2bash(hash_types)
                            ARRAY = slurm.sbatch['array'].value  #array enumeration:  0-(ARRAY-1)
                            LEN_WLS = "${#WLS[@]}"
                            INIT = "$((LEN_WLS/ARRAY * SLURM_ARRAY_TASK_ID))"
                            END = "$((LEN_WLS/ARRAY * (SLURM_ARRAY_TASK_ID+1)))"

                            variable_definition_block = (
                                f"WLS={WLS}",
                                f"HID={HID}",
                                f"LEN_WLS={LEN_WLS}",
                                f"ARRAY={ARRAY}",
                                f"INIT={INIT}",
                                "\nif [[ $SLURM_ARRAY_TASK_ID -eq $((ARRAY -1)) ]]; then",
                                "\t" + "END=$LEN_WLS",
                                "else",
                                "\t" + f"END={END}",
                                "fi",
                            )

                        else:
                            WLS = self.pylist2bash(wordlists)
                            HID = self.pylist2bash(hash_types)
                            INIT = 0
                            END = wordlists_len

                            variable_definition_block = (
                                f"WLS={WLS}",
                                f"HID={HID}",
                                f"INIT={INIT}",
                                f"END={END}",
                            )


                        attack_cmd = f"{self.main_exec}"
                        attack_cmd += " --format=${identity}"
                        attack_cmd += " -w ${wl}"

                        if parallel_job_type == "MPI":
                            attack_cmd = f"srun --mpi={slurm.pmix} "  + attack_cmd

                        elif parallel_job_type == "OMP":
                            attack_cmd = f"srun "  + attack_cmd

                        if rules and rules_file:
                            attack_cmd += f" --rules={rules} {rules_file}"

                        attack_cmd += f" {hashes_file}"
                        header_attack = f"echo -e \"\\n\\n[*] Running: {attack_cmd}\""

                        insert_cracked_hashes = ''
                        if db_status and workspace and db_credential_file:
                            insert_cracked_hashes = (
                                f"amadb -c {db_credential_file} -w {workspace}"
                                f" --cracker {John.MAINNAME} -j {hashes_file}"
                            )

                        cracking_block = (
                            "for wl in ${WLS[@]:INIT:END-INIT}; do",
                            "\tfor identity in ${HID[@]}; do",
                            "\t\t" + header_attack,
                            "\t\t" + attack_cmd,
                            "\t\t" + insert_cracked_hashes,
                            "\t\t" + "all_cracked=false",
                            "\t\t" + "if $all_cracked; then break; fi",
                            "\tdone",
                            "done"
                        )

                        parallel_work = (variable_definition_block,
                                         cracking_block)


                        slurm_script_name = slurm.gen_batch_script(parallel_work)
                        #import pdb;pdb.set_trace()
                        Bash.exec(f"sbatch {slurm_script_name}")

                    #debugged - date apr 9 2021
                    elif hash_types_len > 1 and wordlists_len == 1:
                        #import pdb;pdb.set_trace()
                        if array_tasks > 1:
                            if array_tasks > hash_types_len:
                                print_failure(f"These is more array jobs that work to process (ARRAY={array_tasks}, HID={hash_types_len})")
                                print_status(f"Adjusting {ColorStr('ARRAY').StyleBRIGHT} to {hash_type_len} (1 job per hash type)")
                                array_tasks = hash_types_len
                                slurm.set_option('array', array_tasks)

                            for array_task_id in range(array_tasks):
                                init = floor(hash_types_len/array_tasks)*array_task_id
                                if array_task_id == (array_tasks - 1):
                                    end = hash_types_len
                                else:
                                    end = floor(hash_types_len/array_tasks)*(array_task_id+1)
                                print_status(f"(array id {array_task_id}) Processing: hash-types={ColorStr(hash_types[init:end]).StyleBRIGHT}, wordlists={ColorStr('ALL').StyleBRIGHT}")

                            HID = self.pylist2bash(hash_types)
                            ARRAY = slurm.sbatch['array'].value  #array enumeration:  0-(ARRAY-1)
                            LEN_HID = "${#HID[@]}"
                            INIT = "$((LEN_HID/ARRAY * SLURM_ARRAY_TASK_ID))"
                            END = "$((LEN_HID/ARRAY * (SLURM_ARRAY_TASK_ID+1)))"

                            variable_definition_block = (
                                f"HID={HID}",
                                f"LEN_HID={LEN_HID}",
                                f"ARRAY={ARRAY}",
                                f"INIT={INIT}",
                                "\nif [[ $SLURM_ARRAY_TASK_ID -eq $((ARRAY -1)) ]]; then",
                                "\t" + "END=$LEN_HID",
                                "else",
                                "\t" + f"END={END}",
                                "fi",
                            )

                        else:
                            HID = self.pylist2bash(hash_types)
                            INIT = 0
                            END = hash_types_len

                            variable_definition_block = (
                                f"HID={HID}",
                                f"INIT={INIT}",
                                f"END={END}",
                            )

                        wordlist = wordlists[0]
                        attack_cmd = f"{self.main_exec} --wordlist={wordlist}"
                        attack_cmd += " --format=${identity}"

                        if parallel_job_type == "MPI":
                            attack_cmd = f"srun --mpi={slurm.pmix} "  + attack_cmd


                        elif parallel_job_type == "OMP":
                            attack_cmd = f"srun "  + attack_cmd

                        if rules and rules_file:
                            attack_cmd += f" --rules={rules} {rules_file}"

                        attack_cmd += f" {hashes_file}"
                        header_attack = f"echo -e \"\\n\\n[*] Running: {attack_cmd}\""
                        insert_cracked_hashes = ''
                        if db_status and workspace and db_credential_file:
                            insert_cracked_hashes = (
                                f"amadb -c {db_credential_file} -w {workspace}"
                                f" --cracker {John.MAINNAME} -j {hashes_file}"
                            )

                        cracking_block = (
                            "for identity in ${HID[@]:INIT:END-INIT}; do",
                            "\t" + header_attack,
                            "\t" + attack_cmd,
                            "\t" + insert_cracked_hashes,
                            "\t" + "all_cracked=false",
                            "\t" + "if $all_cracked; then break; fi",
                            "done"
                        )

                        parallel_work = (variable_definition_block,
                                         cracking_block)


                        slurm_script_name = slurm.gen_batch_script(parallel_work)
                        #import pdb;pdb.set_trace()
                        Bash.exec(f"sbatch {slurm_script_name}")

                    # replaced by case: hash_types_len >= 1 and wordlists_len > 1
                    #debugged - date apr 9 2021
                    # elif hash_types_len == 1 and wordlists_len > 1:

                    #     #import pdb;pdb.set_trace()
                    #     if array_tasks > 1:
                    #         if array_tasks > wordlists_len:
                    #             print_failure(f"These is more array jobs that work to process (ARRAY={array_tasks}, WLS={wordlists_len})")
                    #             print_status(f"Adjusting {ColorStr('ARRAY').StyleBRIGHT} to {wordlists_len} (1 job per wordlist)")
                    #             array_tasks = wordlists_len
                    #             slurm.set_option('array', array_tasks)

                    #         for array_task_id in range(array_tasks):
                    #             init = floor(wordlists_len/array_tasks)*array_task_id
                    #             if array_task_id == (array_tasks - 1):
                    #                 end = wordlists_len
                    #             else:
                    #                 end = floor(wordlists_len/array_tasks)*(array_task_id+1)
                    #             print_status(f"(array id {array_task_id}) Processing: wordlists={ColorStr(wordlists[init:end]).StyleBRIGHT}, hash types={ColorStr('ALL').StyleBRIGHT}")

                    #         WLS = self.pylist2bash(wordlists)
                    #         ARRAY = slurm.sbatch['array'].value  #array enumeration:  0-(ARRAY-1)
                    #         LEN_WLS = "${#WLS[@]}"
                    #         INIT = "$((LEN_WLS/ARRAY * SLURM_ARRAY_TASK_ID))"
                    #         END = "$((LEN_WLS/ARRAY * (SLURM_ARRAY_TASK_ID+1)))"

                    #         variable_definition_block = (
                    #             f"WLS={WLS}",
                    #             f"LEN_WLS={LEN_WLS}",
                    #             f"ARRAY={ARRAY}",
                    #             f"INIT={INIT}",
                    #             "\nif [[ $SLURM_ARRAY_TASK_ID -eq $((ARRAY -1)) ]]; then",
                    #             "\t" + "END=$LEN_WLS",
                    #             "else",
                    #             "\t" + f"END={END}",
                    #             "fi",
                    #         )

                    #     else:
                    #         WLS = self.pylist2bash(wordlists)
                    #         INIT = 0
                    #         END = wordlists_len

                    #         variable_definition_block = (
                    #             f"WLS={WLS}",
                    #             f"INIT={INIT}",
                    #             f"END={END}"
                    #         )


                    #     hash_type = hash_types[0]
                    #     attack_cmd = f"{self.main_exec} --format={hash_type}"
                    #     attack_cmd += " -w ${wl}"
                    #     if parallel_job_type == "MPI":
                    #         attack_cmd = f"srun --mpi={slurm.pmix} "  + attack_cmd


                    #     elif parallel_job_type == "OMP":
                    #         attack_cmd = f"srun "  + attack_cmd

                    #     if rules and rules_file:
                    #         attack_cmd += f" --rules={rules} {rules_file}"

                    #     attack_cmd += f" {hashes_file}"
                    #     header_attack = f"echo -e \"\\n\\n[*] Running: {attack_cmd}\""
                    #     insert_cracked_hashes = ''
                    #     if db_status and workspace and db_credential_file:
                    #         insert_cracked_hashes = (
                    #             f"amadb -c {db_credential_file} -w {workspace}"
                    #             f" --cracker {John.MAINNAME} -j {hashes_file}"
                    #         )

                    #     cracking_block = (
                    #         "for wl in ${WLS[@]:INIT:END-INIT}; do",
                    #         "\t" + header_attack,
                    #         "\t" + attack_cmd,
                    #         "\t" + insert_cracked_hashes,
                    #         "\t" + "all_cracked=false",
                    #         "\t" + "if $all_cracked; then break; fi",
                    #         "done"
                    #     )

                    #     parallel_work = (variable_definition_block,
                    #                      cracking_block)


                    #     slurm_script_name = slurm.gen_batch_script(parallel_work)
                    #     #import pdb;pdb.set_trace()
                    #     Bash.exec(f"sbatch {slurm_script_name}")

                    # debugged - date apr 9 2021
                    else: # hash_types_len == 1 and wordlists_len == 1:

                        if array_tasks > 1:
                            print_failure("There is not much work for performing an array attack")
                            slurm.set_option('array', None)
                            if slurm.sbatch['output'] == "slurm-%A_%a.out": # default output name for array jobs
                                slurm.set_option('output', 'slurm-%j.out')

                        #import pdb;pdb.set_trace()
                        hash_type = hash_types[0]
                        wordlist = wordlists[0]
                        attack_cmd = (
                            f"{self.main_exec}"
                            f" --wordlist={wordlist}"
                            f" --format={hash_type}"
                        )

                        if parallel_job_type == "MPI":
                            attack_cmd = f"srun --mpi={slurm.pmix} "  + attack_cmd

                        elif parallel_job_type == "OMP":
                            attack_cmd = f"srun "  + attack_cmd

                        if rules and rules_file:
                            attack_cmd += f" --rules={rules} {rules_file}"

                        attack_cmd += f" {hashes_file}"
                        header_attack = f"echo -e \"\\n\\n[*] Running: {attack_cmd}\""
                        insert_cracked_hashes = ''
                        if db_status and workspace and db_credential_file:
                            insert_cracked_hashes = (
                                f"amadb -c {db_credential_file} -w {workspace}"
                                f" --cracker {John.MAINNAME} -j {hashes_file}"
                            )

                        cracking_block = (header_attack, attack_cmd, insert_cracked_hashes)

                        parallel_work = [cracking_block]
                        slurm_script_name = slurm.gen_batch_script(parallel_work)
                        import pdb;pdb.set_trace()
                        Bash.exec(f"sbatch {slurm_script_name}")

                else:
                    for hash_type in hash_types:
                        are_all_hashes_cracked = John.are_all_hashes_cracked(hashes_file)
                        if  not are_all_hashes_cracked: # some hash isn't cracked yet
                            attack_cmd = f"{self.main_exec} --wordlist={wordlist}"
                            if hash_type:
                                attack_cmd += f" --format={hash_type}"

                            if rules and rules_file:
                                attack_cmd += f" --rules={rules} {rules_file}"

                            attack_cmd += f" {hashes_file}"

                            print()
                            print_status(f"Running: {ColorStr(attack_cmd).StyleBRIGHT}")
                            Bash.exec(attack_cmd)

                        else:
                            print_successful(f"Hashes in {ColorStr(hashes_file).StyleBRIGHT} were cracked")
                            break

                    if db_status and workspace and db_credential_file:
                        John.insert_hashes_to_db(hashes_file, workspace, db_credential_file, pretty=True)

            except Exception as error:
                #cmd2.Cmd.pexcept(error)
                print_failure(error)

        else:
            print_failure(f"Cracker {ColorStr(self.main_name).StyleBRIGHT} is disable")