Avoid AttributeErrors, support re-cracking PMKIDs

Process.__del__() swallows AttributeErrors now (for #120).

And hashcat won't output the key if it's already been cracked (it's in the pot file).
So we run hashcat again, with the --show parameter. This does not try to crack again.
This commit is contained in:
derv82
2018-08-16 00:10:13 -07:00
parent fd3c955c48
commit e48f3bb035
4 changed files with 49 additions and 36 deletions

View File

@@ -106,7 +106,7 @@ class AttackPMKID(Attack):
return None # No hash found. return None # No hash found.
Color.clear_entire_line() Color.clear_entire_line()
Color.pattack('PMKID', self.target, 'CAPTURE', '{G}Captured PMKID{W}\n') Color.pattack('PMKID', self.target, 'CAPTURE', '{G}Captured PMKID{W}')
pmkid_file = self.save_pmkid(pmkid_hash) pmkid_file = self.save_pmkid(pmkid_hash)
return pmkid_file return pmkid_file
@@ -118,8 +118,6 @@ class AttackPMKID(Attack):
Returns: Returns:
True if cracked, False otherwise. True if cracked, False otherwise.
''' '''
with open(pmkid_file, 'r') as pmkid_handle:
Color.pl("\nPMKID_FILE:%s HASH:'%s'" % (pmkid_file, pmkid_handle.read()))
# Check that wordlist exists before cracking. # Check that wordlist exists before cracking.
if Configuration.wordlist is None: if Configuration.wordlist is None:
Color.pl('\n{!} {O}Not cracking because {R}wordlist{O} is not found.') Color.pl('\n{!} {O}Not cracking because {R}wordlist{O} is not found.')
@@ -140,9 +138,10 @@ class AttackPMKID(Attack):
else: else:
# Successfully cracked. # Successfully cracked.
Color.clear_entire_line() Color.clear_entire_line()
Color.pattack('PMKID', self.target, 'CRACKED', '{C}Key: {G}%s{W}\n' % key) Color.pattack('PMKID', self.target, 'CRACKED', '{C}Key: {G}%s{W}' % key)
self.crack_result = CrackResultPMKID(self.target.bssid, self.target.essid, self.crack_result = CrackResultPMKID(self.target.bssid, self.target.essid,
pmkid_file, key) pmkid_file, key)
Color.pl('\n')
self.crack_result.dump() self.crack_result.dump()
return True return True

View File

@@ -22,34 +22,38 @@ class Hashcat(Dependency):
Key (str) if found; `None` if not found. Key (str) if found; `None` if not found.
''' '''
command = [ # Run hashcat once normally, then with --show if it failed
'hashcat', # To catch cases where the password is already in the pot file.
'--force', for additional_arg in [ [], ['--show']]:
'--quiet', command = [
'-m', '16800', 'hashcat',
'-a', '0', # TODO: Configure '--force',
'-w', '2', # TODO: Configure '--quiet', # Only output the password if found.
pmkid_file, '-m', '16800', # WPA-PMKID-PBKDF2
Configuration.wordlist '-a', '0', # TODO: Configure
] '-w', '2', # TODO: Configure
pmkid_file,
Configuration.wordlist
]
command.extend(additional_arg)
# TODO: Check status of hashcat (%); it's impossible with --quiet # TODO: Check status of hashcat (%); it's impossible with --quiet
try: try:
hashcat_proc = Process(command) hashcat_proc = Process(command)
hashcat_proc.wait() hashcat_proc.wait()
stdout = hashcat_proc.stdout() stdout = hashcat_proc.stdout()
except KeyboardInterrupt: # In case user gets impatient except KeyboardInterrupt: # In case user gets impatient
Color.pl('\n{!} {O}Interrupted hashcat cracking{W}') Color.pl('\n{!} {O}Interrupted hashcat cracking{W}')
stdout = '' stdout = ''
if ':' not in stdout: if ':' not in stdout:
# Failed # Failed
return None continue
else: else:
# Cracked # Cracked
key = stdout.strip().split(':', 1)[1] key = stdout.strip().split(':', 1)[1]
return key return key
class HcxDumpTool(Dependency): class HcxDumpTool(Dependency):

View File

@@ -93,8 +93,11 @@ class Process(object):
Ran when object is GC'd. Ran when object is GC'd.
If process is still running at this point, it should die. If process is still running at this point, it should die.
''' '''
if self.pid and self.pid.poll() is None: try:
self.interrupt() if self.pid and self.pid.poll() is None:
self.interrupt()
except AttributeError:
pass
def stdout(self): def stdout(self):
''' Waits for process to finish, returns stdout output ''' ''' Waits for process to finish, returns stdout output '''
@@ -177,23 +180,30 @@ class Process(object):
if __name__ == '__main__': if __name__ == '__main__':
Configuration.initialize(False)
p = Process('ls') p = Process('ls')
print(p.stdout(), p.stderr()) print(p.stdout())
print(p.stderr())
p.interrupt() p.interrupt()
# Calling as list of arguments # Calling as list of arguments
(out, err) = Process.call(['ls', '-lah']) (out, err) = Process.call(['ls', '-lah'])
print(out, err) print(out)
print(err)
print('\n---------------------\n') print('\n---------------------\n')
# Calling as string # Calling as string
(out, err) = Process.call('ls -l | head -2') (out, err) = Process.call('ls -l | head -2')
print(out, err) print(out)
print(err)
print('"reaver" exists:', Process.exists('reaver')) print('"reaver" exists: %s' % Process.exists('reaver'))
# Test on never-ending process # Test on never-ending process
p = Process('yes') p = Process('yes')
print("Running yes...")
time.sleep(1)
print("yes should stop now")
# After program loses reference to instance in 'p', process dies. # After program loses reference to instance in 'p', process dies.

View File

@@ -64,7 +64,7 @@ class Wifite(object):
def print_banner(self): def print_banner(self):
""" Displays ASCII art of the highest caliber. """ """ Displays ASCII art of the highest caliber. """
Color.pl('''\ Color.pl(r'''
{G} . {GR}{D} {W}{G} . {W} {G} . {GR}{D} {W}{G} . {W}
{G}.´ · .{GR}{D} {W}{G}. · `. {G}wifite {D}%s{W} {G}.´ · .{GR}{D} {W}{G}. · `. {G}wifite {D}%s{W}
{G}: : : {GR}{D} (¯) {W}{G} : : : {W}{D}automated wireless auditor {G}: : : {GR}{D} (¯) {W}{G} : : : {W}{D}automated wireless auditor