def _run_essid_digits(compounds_fpath: Path, hashcat_cmd=None, fast=True): if not fast: assert hashcat_cmd is not None, \ "Non-fast mode requires running a hashcat command." candidates = set() wordlist_order = [compounds_fpath] if fast: wordlist_order.append(WordListDefault.DIGITS_APPEND_SHORT) else: wordlist_order.append(WordListDefault.DIGITS_APPEND) with open(compounds_fpath) as f: compounds_count = len(f.readlines()) if compounds_count > 1000 and hashcat_cmd is not None: # reduce IO operations, run the hashcat attack directly fast = False for reverse in range(2): with tempfile.NamedTemporaryFile(mode='w+', errors='ignore') as f: hashcat_stdout = HashcatCmdStdout(outfile=f.name) hashcat_stdout.add_wordlists(*wordlist_order, options=['-a1']) subprocess_call(hashcat_stdout.build()) if fast: candidates.update(f.read().splitlines()) else: _hashcat_cmd_tmp = deepcopy(hashcat_cmd) _hashcat_cmd_tmp.add_wordlists(f.name) subprocess_call(_hashcat_cmd_tmp.build()) wordlist_order = wordlist_order[::-1] return candidates
def run_essid_attack(essid, hashcat_cmd=None, fast=True): # hashcat_cmd could be None for debug mode to check the no. of candidates password_candidates = set() essid_as_wordlist_dir = Path(tempfile.mkdtemp()) # (1) Hamming ball attack essid_compounds = _collect_essid_parts(essid) # Limit the number of word compounds to an arbitrary number. if len(essid_compounds) < 100: for compound in essid_compounds: password_candidates.update(_collect_essid_hamming(essid=compound)) else: password_candidates.update(_collect_essid_hamming(essid=essid)) # (2) best64 rule attack # strip all except digits, letters and '_' compounds_fpath = essid_as_wordlist_dir / re.sub(r'\W+', '', essid) compounds_fpath.write_text('\n'.join(essid_compounds)) password_candidates.update(_collect_essid_rule(compounds_fpath)) # (3) digits_append attack password_candidates.update( _run_essid_digits(compounds_fpath, hashcat_cmd=hashcat_cmd, fast=fast)) if hashcat_cmd is not None: with tempfile.NamedTemporaryFile(mode='w') as f: f.write('\n'.join(password_candidates)) hashcat_cmd = deepcopy(hashcat_cmd) hashcat_cmd.add_wordlists(f.name) subprocess_call(hashcat_cmd.build()) shutil.rmtree(essid_as_wordlist_dir) return password_candidates
def run_top1k(self): """ - Top1575-probable-v2.txt with best64 rules """ hashcat_cmd = self.new_cmd() hashcat_cmd.add_wordlists(WordListDefault.TOP1K_RULE_BEST64) subprocess_call(hashcat_cmd.build())
def read_key(self): dump_keys_cmd = HashcatCmdCapture(self.file_22000, outfile=self.key_file, hashcat_args=['--show']) subprocess_call(dump_keys_cmd.build()) key_password = read_plain_key(self.key_file) with self.lock: self.lock.found_key = key_password
def run_names(self): with tempfile.NamedTemporaryFile(mode='w') as f: hashcat_stdout = HashcatCmdStdout(outfile=f.name) hashcat_stdout.add_wordlists(WordListDefault.NAMES_UA_RU) hashcat_stdout.add_rule(Rule.ESSID) subprocess_call(hashcat_stdout.build()) hashcat_cmd = self.new_cmd() hashcat_cmd.add_wordlists(f.name) subprocess_call(hashcat_cmd.build())
def _run_essid_hamming(self, hcap_fpath_essid: Path, essid: str, hamming_dist_max=2): essid_hamming = set() essid_hamming.update(hamming_ball(s=essid, n=hamming_dist_max)) essid_hamming.update(hamming_ball(s=essid.lower(), n=hamming_dist_max)) logger.debug(f"Essid {essid} -> {len(essid_hamming)} hamming cousins with dist={hamming_dist_max}") with tempfile.NamedTemporaryFile(mode='w') as f: f.write('\n'.join(essid_hamming)) hashcat_cmd = self.new_cmd(hcap_file=hcap_fpath_essid) hashcat_cmd.add_wordlists(f.name) subprocess_call(hashcat_cmd.build())
def run_digits8(self): """ Run digits8+ attack. This includes: - birthdays 100 years backward - simple digits like 88888888, 12345678, etc. For more information refer to `digits/create_digits.py` """ hashcat_cmd = self.new_cmd() hashcat_cmd.add_wordlists(WordListDefault.DIGITS_8) subprocess_call(hashcat_cmd.build())
def _run_essid_digits(self, hcap_fpath_essid: Path, essid_wordlist_path: str): wordlist_order = [essid_wordlist_path, WordListDefault.DIGITS_APPEND.path] for reverse in range(2): with tempfile.NamedTemporaryFile(mode='w') as f: hashcat_stdout = HashcatCmdStdout(outfile=f.name) hashcat_stdout.add_wordlists(*wordlist_order, options=['-a1']) subprocess_call(hashcat_stdout.build()) hashcat_cmd = self.new_cmd(hcap_file=hcap_fpath_essid) hashcat_cmd.add_wordlists(f.name) subprocess_call(hashcat_cmd.build()) wordlist_order = wordlist_order[::-1]
def _collect_essid_rule(essid_wordlist_path: Path): """ Run ESSID + best64.rule attack. """ with tempfile.NamedTemporaryFile(mode='w+', errors='ignore') as f: # Ignore UnicodeDecodeError: 'utf-8' codec can't decode byte ... hashcat_stdout = HashcatCmdStdout(outfile=f.name) hashcat_stdout.add_wordlists(essid_wordlist_path) hashcat_stdout.add_rule(Rule.ESSID) subprocess_call(hashcat_stdout.build()) candidates = f.read().splitlines() return candidates
def _run_essid_rule(self, hcap_fpath: Path, essid_wordlist_path: Path): """ Run ESSID + best64.rule attack. """ with tempfile.NamedTemporaryFile(mode='w') as f: hashcat_stdout = HashcatCmdStdout(outfile=f.name) hashcat_stdout.add_wordlists(essid_wordlist_path) hashcat_stdout.add_rule(Rule.ESSID) subprocess_call(hashcat_stdout.build()) hashcat_cmd = self.new_cmd(hcap_file=hcap_fpath) hashcat_cmd.add_wordlists(f.name) subprocess_call(hashcat_cmd.build())
def download(self): if self.path is None or self.path.exists(): return if self.url is None: return gzip_file = self.url.split('/')[-1] gzip_file = self.path.with_name(gzip_file) logger.debug(f"Downloading {gzip_file}") while calculate_md5(gzip_file) != self.checksum: subprocess_call(['wget', self.url, '-O', gzip_file]) with lock_app: subprocess_call(['gzip', '-d', gzip_file]) logger.debug(f"Downloaded and extracted {self.path}")
def create_fast_wordlists(): # note that dumping all combinations in a file is not equivalent to # directly adding top1k wordlist and best64 rule because hashcat ignores # patterns that are <8 chars _before_ expanding a candidate with the rule. if not WordListDefault.TOP1K_RULE_BEST64.path.exists(): # it should be already created in a docker logger.warning( f"{WordListDefault.TOP1K_RULE_BEST64.name} does not exist. Creating" ) hashcat_stdout = HashcatCmdStdout( outfile=WordListDefault.TOP1K_RULE_BEST64.path) hashcat_stdout.add_wordlists(WordListDefault.TOP1K) hashcat_stdout.add_rule(Rule.BEST_64) subprocess_call(hashcat_stdout.build())
def run_names_with_digits(self): # excluded from the fast run # for each case-changed <name> in (Name, name, NAME) do # - append digits # - prepend digits with open(WordListDefault.NAMES_UA_RU_WITH_DIGITS.path, 'w') as f: wordlist_order = [WordListDefault.NAMES_UA_RU, WordListDefault.DIGITS_APPEND] for left in ['left', 'right']: for rule_names in ['', 'T0', 'u']: hashcat_stdout = HashcatCmdStdout(outfile=f.name) hashcat_stdout.add_wordlists(*wordlist_order, options=['-a1', f'--rule-{left}={rule_names}']) subprocess_call(hashcat_stdout.build()) wordlist_order = wordlist_order[::-1] hashcat_cmd = self.new_cmd() hashcat_cmd.add_wordlists(WordListDefault.NAMES_UA_RU_WITH_DIGITS) subprocess_call(hashcat_cmd.build())
def count_wordlist(wordlist_path): wordlist_path = str(wordlist_path) out, err = subprocess_call(['wc', '-l', wordlist_path]) out = out.rstrip('\n') counter = 0 if re.fullmatch(f"\d+ {wordlist_path}", out): counter, path = out.split(' ') return int(counter)
def _hashcat_benchmark_async(): """ Called in background process. """ out, err = subprocess_call([ 'hashcat', '-m2500', "-b", "--machine-readable", "--quiet", "--force" ]) pattern = re.compile("\d+:2500:.*:.*:\d+\.\d+:\d+") total_speed = 0 for line in filter(pattern.fullmatch, out.splitlines()): device_speed = int(line.split(':')[-1]) total_speed += device_speed if total_speed > 0: snapshot = "{date},{speed}\n".format(date=date_formatted(), speed=total_speed) with lock_app, open(BENCHMARK_FILE, 'a') as f: f.write(snapshot)
def run_phone_mobile(self): # EXCLUDED hashcat_cmd = self.new_cmd() hashcat_cmd.set_mask(Mask.MOBILE_UA) subprocess_call(hashcat_cmd.build())
def run_keyboard_walk(self): hashcat_cmd = self.new_cmd() hashcat_cmd.add_wordlists(WordListDefault.KEYBOARD_WALK) subprocess_call(hashcat_cmd.build())
def terminate(self): for lock in tuple(self.locks.values()): with lock: lock.cancel() subprocess_call(["pkill", "hashcat"]) self.locks.clear()