def search_hash(self, query_hash: str, *, timeout: int, greppable: bool = False): """ search an hash in all the availables online cracking APIs """ #import pdb; pdb.set_trace() if self.enable: sth_cmd = f"{self.main_exec} --no-banner --accessible" if isinstance(timeout, int) and timeout > 0: sth_cmd += f"--timeout {timeout}" sth_cmd += f" --text {query_hash}" print_status( f"Searching {query_hash} hash in availables online cracking APIs" ) Bash.exec(sth_cmd) else: print_failure("Auxliary plugin {self.main_name} is disable")
def search_hashes(self, hashes_file: str, *, timeout: int, greppable: bool = False): """ search each hash in hashes_file in all the availables online cracking APIs """ #import pdb; pdb.set_trace() try: if self.enable: permission = [os.R_OK] Path.access(permission, hashes_file) sth_cmd = f"{self.main_exec} --no-banner --accessible" if isinstance(timeout, int) and timeout > 0: sth_cmd += f"--timeout {timeout}" sth_cmd += f" --file {hashes_file}" print_status( f"Searching hashes in {hashes_file} file in availables online cracking APIs" ) Bash.exec(sth_cmd) else: print_failure("Auxliary plugin {self.main_name} is disable") except Exception as error: print_failure(error)
def benchmark(self, slurm, local: bool = False): """ Hashcat benchmark """ #import pdb; pdb.set_trace() if self.enable: 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) #core, extra = slurm.parameters() attack_cmd = f"srun {self.main_exec} -b" header_attack = f"echo -e '\\n\\n[*] Running: {attack_cmd}'" parallel_work = [(header_attack, attack_cmd)] batch_script_name = slurm.gen_batch_script(parallel_work) Bash.exec(f"sbatch {batch_script_name}") else: attack_cmd = f"{self.main_exec} -b" print_status(f"Running: {ColorStr(attack_cmd).StyleBRIGHT}") Bash.exec(attack_cmd) else: print_failure( f"Cracker {ColorStr(self.main_name).StyleBRIGHT} is disable")
def benchmark(self, slurm=None): """ Run john benchmark """ #import pdb; pdb.set_trace() if self.enable: #cmd2.Cmd.poutput(f"Performing John Benchmark.") #print_status(f"Performing John Benchmark.") if slurm and slurm.partition: parallel_job_type = slurm.parallel_job_parser() if not parallel_job_type in ["MPI", "OMP"]: raise InvalidParallelJob(parallel_job_type) attack_cmd = f"{self.main_exec} --test" 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 header_attack = f"echo -e \"\\n\\n[*] Running: {attack_cmd}\"" parallel_work = [(header_attack, attack_cmd)] batch_script_name = slurm.gen_batch_script(parallel_work) Bash.exec(f"sbatch {batch_script_name}") else: attack_cmd = f"{self.main_exec} --test" print_status("Running: {ColorStr(attack_cmd).StyleBRIGHT}") Bash.exec(attack_cmd) else: print_failure(f"Cracker {ColorStr(self.main_name).StyleBRIGHT} is disable")
def deleteDB(dbName=None, roleName=None): """ Delete ama-framework database """ if dbName: if Answer.shortAnwser( f"Do you really want to delete the {ColorStr(dbName).StyleBRIGHT} database(y/n)? " ): if roleName: Bash.exec( f"psql -U {roleName} -c \"DROP DATABASE {dbName}\"") else: Bash.exec( f"psql -U postgres -c \"DROP DATABASE {dbName}\"") else: #cmd2.Cmd.pwarning("Be carefully you could lose your data") print_failure("Be carefully you could lose your data") else: #cmd2.Cmd.pwarning("No database was selected to delete") print_failure("No database was selected to delete")
def initDB(dbName="ama", roleName="attacker"): """ Database initialization (creation of database, role, and initialization of default workspace) """ try: #cmd2.Cmd.poutput(f"Creating {roleName} role") print_status(f"Creating role: {ColorStr(roleName).StyleBRIGHT}") password = getpass( prompt= f"Password for {ColorStr(roleName).StyleBRIGHT} role (empty for random generation): " ) if not password: passwd = PasswordGenerator() passwd.minlen = 16 passwd.maxlen = 16 passwd.minnumbers = 2 passwd.minschars = 3 passwd.minuchars = 2 password = passwd.generate() Bash.exec( f"psql -U postgres -c \"CREATE ROLE {roleName} WITH LOGIN CREATEDB PASSWORD '{password}'\"", quiet=True) Bash.exec( f"psql -U postgres -c \"CREATE DATABASE {roleName} OWNER {roleName}\"", quiet=True) #cmd2.Cmd.poutput(f"Role {roleName} has been created") print_successful( f"Role {ColorStr(roleName).StyleBRIGHT} has been created") #cmd2.Cmd.poutput(f"Creating {dbName} database") print_status(f"Creating {ColorStr(dbName).StyleBRIGHT} database") Bash.exec( f"psql -U {roleName} -c \"CREATE DATABASE {dbName} OWNER {roleName}\"", quiet=True) #cmd2.Cmd.poutput("Database {dbName} has been created") # creation workspaces table dbCredential = { 'host': 'localhost', 'database': dbName, 'user': roleName, 'password': password } workspace = "default" tablesCreation = (""" CREATE TABLE IF NOT EXISTS workspaces ( name VARCHAR (100) UNIQUE NOT NULL ) """, f""" CREATE TABLE IF NOT EXISTS hashes_{workspace} ( hash VARCHAR (128) UNIQUE NOT NULL, type VARCHAR (20), cracker VARCHAR (20) NOT NULL, password VARCHAR (32) NOT NULL ) """, f""" CREATE TABLE IF NOT EXISTS services_{workspace} ( service VARCHAR (20) NOT NULL, target VARCHAR (15) NOT NULL, service_user VARCHAR (20) NOT NULL, password VARCHAR (32) NOT NULL ) """) valueInsert = (""" INSERT INTO workspaces (name) VALUES (%s); """) conn = None conn = psycopg2.connect(**dbCredential) cur = conn.cursor() # workspace table creation and # hashes and services tables creation for "default" workspace for cmdTable in tablesCreation: cur.execute(cmdTable) conn.commit() # default workspace insertion cur.execute(valueInsert, (workspace, )) conn.commit() cur.close() print_successful( f"Database {ColorStr(dbName).StyleBRIGHT} has been created") #import pdb; pdb.set_trace() # writing credential to AMA_HOME/db/database.json file database_json_file = Path.joinpath(AMA_HOME, 'db/database.json') with open(database_json_file, 'w') as db_credentials: json.dump(dbCredential, db_credentials, indent=4) print_successful( f"Database credential file has been created: {ColorStr(database_json_file).StyleBRIGHT}" ) del dbCredential except (Exception, psycopg2.DatabaseError) as error: print_failure(error)
def wordlist_attack(self, *, user=None, users_file=None, passwd=None, passwd_file=None, users_passwd_file=None, port=None, ip4=True, output=None, output_format=None, verbose=True, stopInSuccess=False, stopInSuccessPerTarget=True, targets_file=None, target=None, service=None, slurm=None): """ Perform a wordlist attack against services using hydra submiting parallel task in a cluster using slurm. Args: user (str): None, users_file (str): None, passwd_file (str): None, users_passwd_file (str): None, port (str): None, ip4 (str): True, output=None, output_format=None, verbose=True, stopInSucess=False, stopInSucessPerTarget=True, targets_file=None, target=None, service=None slurm = None """ #import pdb; pdb.set_trace() if self.enable: try: # validation of data Args.not_none(service) Args.some_not_none(user, users_file) Args.some_not_none(passwd, passwd_file, users_passwd_file) Args.some_not_none(target, targets_file) permission = [os.R_OK] Hydra.checkService(service) #cmd2.Cmd.poutput(f"Attacking {service} service of {target} target with {wordlist} wordlist.") #print_failure(f"Attacking {service} service of {target} target with {wordlist} wordlist.") attack_cmd = f"{self.main_exec}" # user and password flags if users_passwd_file: Path.access(permission, users_passwd_file) attack_cmd += f" -C {users_passwd_file}" else: # user if user: attack_cmd += f" -l {user}" else: # use userFile as users file Path.access(permission, users_file) attack_cmd += f" -L {users_file}" # passwords if passwd: attack_cmd += f" -p {passwd}" else: # passwd_file is not None Path.access(permission, passwd_file) attack_cmd += f" -P {passwd_file}" # port if port: attack_cmd += f" -s {port}" # output if output: attack_cmd += f" -o {output}" # ip version if ip4: attack_cmd += " -4" else: # ipv6 attack_cmd += " -6" # verbose if verbose: attack_cmd += " -V" # exit if success if stopInSuccessPerTarget: attack_cmd += " -f" if stopInSuccess: attack_cmd += " -F" # target if targets_file: Path.access(permission, targets_file) attack_cmd += f" -M {targets_file}" else: # simple target attack_cmd += f" {target}" # service attack_cmd += f" {service}" if slurm.partition: parallel_job_type = slurm.parallel_job_parser() if not parallel_job_type in ["OMP"]: raise InvalidParallelJob(parallel_job_type) parallel_work = [attack_cmd] batch_script_name = slurm.gen_batch_script(parallel_work) Bash.exec(f"sbatch {batch_script_name}") else: Bash.exec(attack_cmd) except Exception as error: #cmd2.Cmd.pexcept(error) print_failure(error) else: #cmd2.Cmd.pwarning(f"Cracker {self.main_name} is disable") print_failure(f"Cracker {self.main_name} is disable")
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)
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)
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")
def spider(self, url: str, *, depth: int = 2, min_length: int = 3, offsite: bool = False, exclude: str = None, allowed: str = None, write: str = None, lowercase: bool = False, with_numbers: bool = False, convert_umlauts: bool = True, meta: bool = False, meta_file: str = None, email: bool = False, email_file: str = None, count: bool = False, verbose: bool = True, debug: bool = False): #import pdb; pdb.set_trace() try: permission = [os.R_OK] cewl_cmd = f"{self.main_exec} --depth {depth} --min_word_length {min_length}" if offsite: cewl_cmd += " --offsite" if exclude: Path.access(permission, exclude) cewl_cmd += f" --exclude {exclude}" if allowed: cewl_cmd += f" --allowed {allowed}" if write: cewl_cmd += f" --write {write}" if lowercase: cewl_cmd += " --lowercase" if with_numbers: cewl_cmd += " --with_numbers" if convert_umlauts: cewl_cmd += " --convert-umlauts" if meta: if meta_file: Path.access(permission, meta_file) cewl_cmd += f" --meta --meta_file {meta_file}" else: raise Exception( "meta option enable, but meta_file not supplied") if email: if email_file: Path.access(permission, email_file) cewl_cmd += f" --email --email_file {email_file}" else: raise Exception( "email option enable, but email_file not supplied") if count: cewl_cmd += " --count" if verbose: cewl_cmd += " --verbose" if debug: cewl_cmd += " --debug" cewl_cmd += f" {url}" print_status(f"Running: {cewl_cmd}") Bash.exec(cewl_cmd) except Exception as error: print_failure(error)
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)
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")
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")