--crack supports hashcat, aircrack, john, cowpatty, and pyrit.
* Still not "print" option for --crack. * Checks hashcat for devices, uses --force if no devices are found. * Interrupting --crack stops entire process, not just a single crack attempt * Changed wordlist location, hopefully completes #102.
This commit is contained in:
@@ -97,7 +97,12 @@ class AttackPMKID(Attack):
|
||||
return False # No hash found.
|
||||
|
||||
# Crack it.
|
||||
self.success = self.crack_pmkid_file(pmkid_file)
|
||||
try:
|
||||
self.success = self.crack_pmkid_file(pmkid_file)
|
||||
except KeyboardInterrupt:
|
||||
Color.pl('\n{!} {R}Failed to crack PMKID: {O}Cracking interrupted by user{W}')
|
||||
self.success = False
|
||||
return False
|
||||
|
||||
return True # Even if we don't crack it, capturing a PMKID is 'successful'
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ..model.attack import Attack
|
||||
from ..tools.aircrack import Aircrack
|
||||
from ..tools.airodump import Airodump
|
||||
from ..tools.aireplay import Aireplay
|
||||
from ..config import Configuration
|
||||
@@ -47,11 +48,29 @@ class AttackWPA(Attack):
|
||||
Color.pl('\n{+} analysis of captured handshake file:')
|
||||
handshake.analyze()
|
||||
|
||||
# Check wordlist
|
||||
if Configuration.wordlist is None:
|
||||
Color.pl('{!} {O}Not cracking handshake because' +
|
||||
' wordlist ({R}--dict{O}) is not set')
|
||||
self.success = False
|
||||
return False
|
||||
|
||||
elif not os.path.exists(Configuration.wordlist):
|
||||
Color.pl('{!} {O}Not cracking handshake because' +
|
||||
' wordlist {R}%s{O} was not found' % Configuration.wordlist)
|
||||
self.success = False
|
||||
return False
|
||||
|
||||
Color.pl('\n{+} {C}Cracking WPA Handshake:{W} Using {C}aircrack-ng{W} via' +
|
||||
' {C}%s{W} wordlist' % os.path.split(Configuration.wordlist)[-1])
|
||||
|
||||
# Crack it
|
||||
key = self.crack_handshake(handshake, Configuration.wordlist)
|
||||
key = Aircrack.crack_handshake(handshake, Configuration.wordlist)
|
||||
if key is None:
|
||||
Color.pl('{!} {R}Failed to crack handshake: {O}%s{R} did not contain password{W}' % Configuration.wordlist.split(os.sep)[-1])
|
||||
self.success = False
|
||||
else:
|
||||
Color.pl('{+} {G}Cracked WPA Handshake{W} PSK: {G}%s{W}\n' % key)
|
||||
self.crack_result = CrackResultWPA(handshake.bssid, handshake.essid, handshake.capfile, key)
|
||||
self.crack_result.dump()
|
||||
self.success = True
|
||||
@@ -157,84 +176,6 @@ class AttackWPA(Attack):
|
||||
self.save_handshake(handshake)
|
||||
return handshake
|
||||
|
||||
@staticmethod
|
||||
def crack_handshake(handshake, wordlist, verbose=False):
|
||||
'''Tries to crack a handshake. Returns WPA key if found, otherwise None.'''
|
||||
if wordlist is None:
|
||||
Color.pl('{!} {O}Not cracking handshake because' +
|
||||
' wordlist ({R}--dict{O}) is not set')
|
||||
return None
|
||||
elif not os.path.exists(wordlist):
|
||||
Color.pl('{!} {O}Not cracking handshake because' +
|
||||
' wordlist {R}%s{O} was not found' % wordlist)
|
||||
return None
|
||||
|
||||
if not verbose:
|
||||
Color.pl('\n{+} {C}Cracking WPA Handshake:{W} Using {C}aircrack-ng{W} via' +
|
||||
' {C}%s{W} wordlist' % os.path.split(wordlist)[-1])
|
||||
|
||||
key_file = Configuration.temp('wpakey.txt')
|
||||
command = [
|
||||
'aircrack-ng',
|
||||
'-a', '2',
|
||||
'-w', wordlist,
|
||||
'--bssid', handshake.bssid,
|
||||
'-l', key_file,
|
||||
handshake.capfile
|
||||
]
|
||||
if verbose:
|
||||
Color.pl('{+} {D}Running: {W}{P}%s{W}' % ' '.join(command))
|
||||
crack_proc = Process(command)
|
||||
|
||||
# Report progress of cracking
|
||||
aircrack_nums_re = re.compile(r'(\d+)/(\d+) keys tested.*\(([\d.]+)\s+k/s')
|
||||
aircrack_key_re = re.compile(r'Current passphrase:\s*([^\s].*[^\s])\s*$')
|
||||
num_tried = num_total = 0
|
||||
percent = num_kps = 0.0
|
||||
eta_str = 'unknown'
|
||||
current_key = ''
|
||||
while crack_proc.poll() is None:
|
||||
line = crack_proc.pid.stdout.readline()
|
||||
match_nums = aircrack_nums_re.search(line.decode('utf-8'))
|
||||
match_keys = aircrack_key_re.search(line.decode('utf-8'))
|
||||
if match_nums:
|
||||
num_tried = int(match_nums.group(1))
|
||||
num_total = int(match_nums.group(2))
|
||||
num_kps = float(match_nums.group(3))
|
||||
eta_seconds = (num_total - num_tried) / num_kps
|
||||
eta_str = Timer.secs_to_str(eta_seconds)
|
||||
percent = 100.0 * float(num_tried) / float(num_total)
|
||||
elif match_keys:
|
||||
current_key = match_keys.group(1)
|
||||
else:
|
||||
continue
|
||||
|
||||
status = '\r{+} {C}Cracking WPA Handshake: %0.2f%%{W}' % percent
|
||||
status += ' ETA: {C}%s{W}' % eta_str
|
||||
status += ' @ {C}%0.1fkps{W}' % num_kps
|
||||
#status += ' ({C}%d{W}/{C}%d{W} keys)' % (num_tried, num_total)
|
||||
status += ' (current key: {C}%s{W})' % current_key
|
||||
if not verbose:
|
||||
Color.clear_entire_line()
|
||||
Color.p(status)
|
||||
|
||||
if not verbose:
|
||||
Color.pl('')
|
||||
|
||||
# Check crack result
|
||||
if os.path.exists(key_file):
|
||||
with open(key_file, 'r') as fid:
|
||||
key = fid.read().strip()
|
||||
os.remove(key_file)
|
||||
|
||||
if not verbose:
|
||||
Color.pl('{+} {G}Cracked WPA Handshake{W} PSK: {G}%s{W}\n' % key)
|
||||
return key
|
||||
else:
|
||||
if not verbose:
|
||||
Color.pl('{!} {R}Failed to crack handshake: {O}%s{R} did not contain password{W}' % wordlist.split(os.sep)[-1])
|
||||
return None
|
||||
|
||||
def load_handshake(self, bssid, essid):
|
||||
if not os.path.exists(Configuration.wpa_handshake_dir):
|
||||
return None
|
||||
|
||||
@@ -84,9 +84,10 @@ class Configuration(object):
|
||||
# Default dictionary for cracking
|
||||
cls.wordlist = None
|
||||
wordlists = [
|
||||
'./wordlist-top4800-probable.txt',
|
||||
'/usr/share/wordlists/wordlist-top4800-probable.txt',
|
||||
'/usr/local/share/wordlists/wordlist-top4800-probable.txt',
|
||||
'./wordlist-top4800-probable.txt', # Local file (ran from cloned repo)
|
||||
'/usr/dict/wordlists/wordlist-top4800-probable.txt', # setup.py with prefix=/usr
|
||||
'/usr/local/dict/wordlists/wordlist-top4800-probable.txt', # setup.py with prefix=/usr/local
|
||||
# Other passwords found on Kali
|
||||
'/usr/share/wfuzz/wordlist/fuzzdb/wordlists-user-passwd/passwds/phpbb.txt',
|
||||
'/usr/share/fuzzdb/wordlists-user-passwd/passwds/phpbb.txt',
|
||||
'/usr/share/wordlists/fern-wifi/common.txt'
|
||||
|
||||
@@ -38,7 +38,7 @@ class Handshake(object):
|
||||
|
||||
if len(pairs) == 0 and not self.bssid and not self.essid:
|
||||
# Tshark and Pyrit failed us, nothing else we can do.
|
||||
raise Exception('Cannot find BSSID or ESSID in cap file')
|
||||
raise ValueError('Cannot find BSSID or ESSID in cap file %s' % self.capfile)
|
||||
|
||||
if not self.essid and not self.bssid:
|
||||
# We do not know the bssid nor the essid
|
||||
|
||||
@@ -7,6 +7,7 @@ from ..util.input import xrange
|
||||
from ..config import Configuration
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
class Aircrack(Dependency):
|
||||
dependency_required = True
|
||||
@@ -77,6 +78,70 @@ class Aircrack(Dependency):
|
||||
if os.path.exists(self.cracked_file):
|
||||
os.remove(self.cracked_file)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def crack_handshake(handshake, show_command=False):
|
||||
from ..util.color import Color
|
||||
from ..util.timer import Timer
|
||||
'''Tries to crack a handshake. Returns WPA key if found, otherwise None.'''
|
||||
|
||||
key_file = Configuration.temp('wpakey.txt')
|
||||
command = [
|
||||
'aircrack-ng',
|
||||
'-a', '2',
|
||||
'-w', Configuration.wordlist,
|
||||
'--bssid', handshake.bssid,
|
||||
'-l', key_file,
|
||||
handshake.capfile
|
||||
]
|
||||
if show_command:
|
||||
Color.pl('{+} {D}Running: {W}{P}%s{W}' % ' '.join(command))
|
||||
crack_proc = Process(command)
|
||||
|
||||
# Report progress of cracking
|
||||
aircrack_nums_re = re.compile(r'(\d+)/(\d+) keys tested.*\(([\d.]+)\s+k/s')
|
||||
aircrack_key_re = re.compile(r'Current passphrase:\s*([^\s].*[^\s])\s*$')
|
||||
num_tried = num_total = 0
|
||||
percent = num_kps = 0.0
|
||||
eta_str = 'unknown'
|
||||
current_key = ''
|
||||
while crack_proc.poll() is None:
|
||||
line = crack_proc.pid.stdout.readline()
|
||||
match_nums = aircrack_nums_re.search(line.decode('utf-8'))
|
||||
match_keys = aircrack_key_re.search(line.decode('utf-8'))
|
||||
if match_nums:
|
||||
num_tried = int(match_nums.group(1))
|
||||
num_total = int(match_nums.group(2))
|
||||
num_kps = float(match_nums.group(3))
|
||||
eta_seconds = (num_total - num_tried) / num_kps
|
||||
eta_str = Timer.secs_to_str(eta_seconds)
|
||||
percent = 100.0 * float(num_tried) / float(num_total)
|
||||
elif match_keys:
|
||||
current_key = match_keys.group(1)
|
||||
else:
|
||||
continue
|
||||
|
||||
status = '\r{+} {C}Cracking WPA Handshake: %0.2f%%{W}' % percent
|
||||
status += ' ETA: {C}%s{W}' % eta_str
|
||||
status += ' @ {C}%0.1fkps{W}' % num_kps
|
||||
#status += ' ({C}%d{W}/{C}%d{W} keys)' % (num_tried, num_total)
|
||||
status += ' (current key: {C}%s{W})' % current_key
|
||||
Color.clear_entire_line()
|
||||
Color.p(status)
|
||||
|
||||
Color.pl('')
|
||||
|
||||
# Check crack result
|
||||
if os.path.exists(key_file):
|
||||
with open(key_file, 'r') as fid:
|
||||
key = fid.read().strip()
|
||||
os.remove(key_file)
|
||||
|
||||
return key
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
(hexkey, asciikey) = Aircrack._hex_and_ascii_key('A1B1C1D1E1')
|
||||
assert hexkey == 'A1:B1:C1:D1:E1', 'hexkey was "%s", expected "A1:B1:C1:D1:E1"' % hexkey
|
||||
|
||||
41
wifite/tools/cowpatty.py
Normal file
41
wifite/tools/cowpatty.py
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from .dependency import Dependency
|
||||
from ..config import Configuration
|
||||
from ..util.color import Color
|
||||
from ..util.process import Process
|
||||
from ..tools.hashcat import HcxPcapTool
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
class Cowpatty(Dependency):
|
||||
''' Wrapper for Cowpatty program. '''
|
||||
dependency_required = False
|
||||
dependency_name = 'cowpatty'
|
||||
dependency_url = 'https://tools.kali.org/wireless-attacks/cowpatty'
|
||||
|
||||
|
||||
@staticmethod
|
||||
def crack_handshake(handshake, show_command=False):
|
||||
# Crack john file
|
||||
command = [
|
||||
'cowpatty',
|
||||
'-f', Configuration.wordlist,
|
||||
'-r', handshake.capfile,
|
||||
'-s', handshake.essid
|
||||
]
|
||||
if show_command:
|
||||
Color.pl('{+} {D}{C}Running %s{W}' % ' '.join(command))
|
||||
process = Process(command)
|
||||
stdout, stderr = process.get_output()
|
||||
|
||||
key = None
|
||||
for line in stdout.split('\n'):
|
||||
if 'The PSK is "' in line:
|
||||
key = line.split('"', 1)[1][:-2]
|
||||
break
|
||||
|
||||
return key
|
||||
@@ -14,6 +14,47 @@ class Hashcat(Dependency):
|
||||
dependency_name = 'hashcat'
|
||||
dependency_url = 'https://hashcat.net/hashcat/'
|
||||
|
||||
@staticmethod
|
||||
def should_use_force():
|
||||
command = ['hashcat', '-I']
|
||||
stderr = Process(command).stderr()
|
||||
return 'No devices found/left' in stderr
|
||||
|
||||
@staticmethod
|
||||
def crack_handshake(handshake, show_command=False):
|
||||
# Generate hccapx
|
||||
hccapx_file = HcxPcapTool.generate_hccapx_file(
|
||||
handshake, show_command=show_command)
|
||||
|
||||
key = None
|
||||
# Crack hccapx
|
||||
for additional_arg in [ [], ['--show']]:
|
||||
command = [
|
||||
'hashcat',
|
||||
'--quiet',
|
||||
'-m', '2500',
|
||||
hccapx_file,
|
||||
Configuration.wordlist
|
||||
]
|
||||
if Hashcat.should_use_force():
|
||||
command.append('--force')
|
||||
command.extend(additional_arg)
|
||||
if show_command:
|
||||
Color.pl('{+} {D}{C}Running %s{W}' % ' '.join(command))
|
||||
process = Process(command)
|
||||
stdout, stderr = process.get_output()
|
||||
if ':' not in stdout:
|
||||
continue
|
||||
else:
|
||||
key = stdout.split(':', 5)[-1].strip()
|
||||
break
|
||||
|
||||
if os.path.exists(hccapx_file):
|
||||
os.remove(hccapx_file)
|
||||
|
||||
return key
|
||||
|
||||
|
||||
@staticmethod
|
||||
def crack_pmkid(pmkid_file, verbose=False):
|
||||
'''
|
||||
@@ -27,27 +68,23 @@ class Hashcat(Dependency):
|
||||
for additional_arg in [ [], ['--show']]:
|
||||
command = [
|
||||
'hashcat',
|
||||
'--force',
|
||||
'--quiet', # Only output the password if found.
|
||||
'-m', '16800', # WPA-PMKID-PBKDF2
|
||||
'-a', '0', # TODO: Configure
|
||||
'-w', '2', # TODO: Configure
|
||||
'-a', '0', # Wordlist attack-mode
|
||||
pmkid_file,
|
||||
Configuration.wordlist
|
||||
]
|
||||
if Hashcat.should_use_force():
|
||||
command.append('--force')
|
||||
command.extend(additional_arg)
|
||||
if verbose and additional_arg == []:
|
||||
Color.pl('{+} {D}Running: {W}{P}%s{W}' % ' '.join(command))
|
||||
|
||||
# TODO: Check status of hashcat (%); it's impossible with --quiet
|
||||
|
||||
try:
|
||||
hashcat_proc = Process(command)
|
||||
hashcat_proc.wait()
|
||||
stdout = hashcat_proc.stdout()
|
||||
except KeyboardInterrupt: # In case user gets impatient
|
||||
Color.pl('\n{!} {O}Interrupted hashcat cracking{W}')
|
||||
stdout = ''
|
||||
hashcat_proc = Process(command)
|
||||
hashcat_proc.wait()
|
||||
stdout = hashcat_proc.stdout()
|
||||
|
||||
if ':' not in stdout:
|
||||
# Failed
|
||||
@@ -100,6 +137,52 @@ class HcxPcapTool(Dependency):
|
||||
self.bssid = self.target.bssid.lower().replace(':', '')
|
||||
self.pmkid_file = Configuration.temp('pmkid-%s.16800' % self.bssid)
|
||||
|
||||
@staticmethod
|
||||
def generate_hccapx_file(handshake, show_command=False):
|
||||
hccapx_file = Configuration.temp('generated.hccapx')
|
||||
if os.path.exists(hccapx_file):
|
||||
os.remove(hccapx_file)
|
||||
|
||||
command = [
|
||||
'hcxpcaptool',
|
||||
'-o', hccapx_file,
|
||||
handshake.capfile
|
||||
]
|
||||
|
||||
if show_command:
|
||||
Color.pl('{+} {D}{C}Running %s{W}' % ' '.join(command))
|
||||
|
||||
process = Process(command)
|
||||
stdout, stderr = process.get_output()
|
||||
if not os.path.exists(hccapx_file):
|
||||
raise ValueError('Failed to generate .hccapx file, output: \n%s\n%s' % (
|
||||
stdout, stderr))
|
||||
|
||||
return hccapx_file
|
||||
|
||||
@staticmethod
|
||||
def generate_john_file(handshake, show_command=False):
|
||||
john_file = Configuration.temp('generated.john')
|
||||
if os.path.exists(john_file):
|
||||
os.remove(john_file)
|
||||
|
||||
command = [
|
||||
'hcxpcaptool',
|
||||
'-j', john_file,
|
||||
handshake.capfile
|
||||
]
|
||||
|
||||
if show_command:
|
||||
Color.pl('{+} {D}{C}Running %s{W}' % ' '.join(command))
|
||||
|
||||
process = Process(command)
|
||||
stdout, stderr = process.get_output()
|
||||
if not os.path.exists(john_file):
|
||||
raise ValueError('Failed to generate .john file, output: \n%s\n%s' % (
|
||||
stdout, stderr))
|
||||
|
||||
return john_file
|
||||
|
||||
def get_pmkid_hash(self, pcapng_file):
|
||||
if os.path.exists(self.pmkid_file):
|
||||
os.remove(self.pmkid_file)
|
||||
|
||||
53
wifite/tools/john.py
Normal file
53
wifite/tools/john.py
Normal file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from .dependency import Dependency
|
||||
from ..config import Configuration
|
||||
from ..util.color import Color
|
||||
from ..util.process import Process
|
||||
from ..tools.hashcat import HcxPcapTool
|
||||
|
||||
import os
|
||||
|
||||
|
||||
class John(Dependency):
|
||||
''' Wrapper for John program. '''
|
||||
dependency_required = False
|
||||
dependency_name = 'john'
|
||||
dependency_url = 'http://www.openwall.com/john/'
|
||||
|
||||
|
||||
@staticmethod
|
||||
def crack_handshake(handshake, show_command=False):
|
||||
john_file = HcxPcapTool.generate_john_file(handshake, show_command=show_command)
|
||||
|
||||
# Crack john file
|
||||
command = [
|
||||
'john',
|
||||
'--format=wpapsk', # wpapsk-cuda or wpapsk-opencl
|
||||
'--wordlist', Configuration.wordlist,
|
||||
john_file
|
||||
]
|
||||
if show_command:
|
||||
Color.pl('{+} {D}{C}Running %s{W}' % ' '.join(command))
|
||||
process = Process(command)
|
||||
process.wait()
|
||||
|
||||
# Show the password (if found)
|
||||
command = ['john', '--show', john_file]
|
||||
if show_command:
|
||||
Color.pl('{+} {D}{C}Running %s{W}' % ' '.join(command))
|
||||
process = Process(command)
|
||||
stdout, stderr = process.get_output()
|
||||
|
||||
key = None
|
||||
if not '0 password hashes cracked' in stdout:
|
||||
for line in stdout.split('\n'):
|
||||
if handshake.capfile in line:
|
||||
key = line.split(':')[1]
|
||||
break
|
||||
|
||||
if os.path.exists(john_file):
|
||||
os.remove(john_file)
|
||||
|
||||
return key
|
||||
@@ -1,10 +1,17 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ..config import Configuration
|
||||
from ..model.handshake import Handshake
|
||||
from ..model.wpa_result import CrackResultWPA
|
||||
from ..model.pmkid_result import CrackResultPMKID
|
||||
from ..util.process import Process
|
||||
from ..util.color import Color
|
||||
from ..util.input import raw_input
|
||||
from ..config import Configuration
|
||||
from ..tools.aircrack import Aircrack
|
||||
from ..tools.cowpatty import Cowpatty
|
||||
from ..tools.hashcat import Hashcat, HcxPcapTool
|
||||
from ..tools.john import John
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
@@ -19,8 +26,8 @@ class CrackHelper:
|
||||
'''Manages handshake retrieval, selection, and running the cracking commands.'''
|
||||
|
||||
TYPES = {
|
||||
'4-WAY': 'WPA 4-Way Handshake',
|
||||
'PMKID': 'WPA PKID Hash'
|
||||
'4-WAY': '4-Way Handshake',
|
||||
'PMKID': 'PMKID Hash'
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +35,7 @@ class CrackHelper:
|
||||
def run(cls):
|
||||
Configuration.initialize(False)
|
||||
|
||||
# Get wordlist
|
||||
if not Configuration.wordlist:
|
||||
Color.p('\n{+} Enter wordlist file to use for cracking: {G}')
|
||||
Configuration.wordlist = raw_input()
|
||||
@@ -36,16 +44,35 @@ class CrackHelper:
|
||||
return
|
||||
Color.pl('')
|
||||
|
||||
# Get handshakes
|
||||
handshakes = cls.get_handshakes()
|
||||
if len(handshakes) == 0:
|
||||
Color.pl('{!} {O}No handshakes found{W}')
|
||||
return
|
||||
|
||||
hs_to_crack = cls.get_user_selection(handshakes)
|
||||
|
||||
# TODO: Ask what method to use for WPA (aircrack, pyrit, john, hashcat, cowpatty)
|
||||
# Get tool
|
||||
available_tools = ['aircrack', 'hashcat', 'john', 'cowpatty']
|
||||
if not Process.exists(HcxPcapTool.dependency_name):
|
||||
Color.pl('{!} {R}Unable to use hashcat: {O}missing required hcxpcaptool{W}')
|
||||
available_tools.remove('hashcat')
|
||||
if not Process.exists(John.dependency_name):
|
||||
Color.pl('{!} {R}Unable to use john: {O}missing required "john" program{W}')
|
||||
available_tools.remove('john')
|
||||
|
||||
for hs in hs_to_crack:
|
||||
cls.crack(hs)
|
||||
Color.p('{+} Enter the {C}cracking tool{W} to use ({C}%s{W}): {G}' % (
|
||||
'{W}, {C}'.join(available_tools)))
|
||||
tool_name = raw_input()
|
||||
if tool_name not in available_tools:
|
||||
Color.pl('{!} {O}%s not found, defaulting to aircrack' % tool_name)
|
||||
tool_name = 'aircrack'
|
||||
|
||||
try:
|
||||
for hs in hs_to_crack:
|
||||
cls.crack(hs, tool_name)
|
||||
except KeyboardInterrupt:
|
||||
Color.pl('\n{!} {O}Interrupted{W}')
|
||||
|
||||
@classmethod
|
||||
def get_handshakes(cls):
|
||||
@@ -136,7 +163,7 @@ class CrackHelper:
|
||||
def get_user_selection(cls, handshakes):
|
||||
cls.print_handshakes(handshakes)
|
||||
|
||||
Color.p('{+} Select handshake(s) to crack ({G}%d{W}-{G}%d{W}, select multiple with {C},{W} or {C}-{W}): {G}' % (1, len(handshakes)))
|
||||
Color.p('{+} Select handshake(s) to crack ({G}%d{W}-{G}%d{W}, select multiple with {C},{W} or {C}-{W} or {C}all{W}): {G}' % (1, len(handshakes)))
|
||||
choices = raw_input()
|
||||
|
||||
selection = []
|
||||
@@ -145,7 +172,10 @@ class CrackHelper:
|
||||
first, last = [int(x) for x in choice.split('-')]
|
||||
for index in range(first, last + 1):
|
||||
selection.append(handshakes[index-1])
|
||||
else:
|
||||
elif choice.strip().lower() == 'all':
|
||||
selection = handshakes[:]
|
||||
break
|
||||
elif [c.isdigit() for c in choice]:
|
||||
index = int(choice)
|
||||
selection.append(handshakes[index-1])
|
||||
|
||||
@@ -153,12 +183,14 @@ class CrackHelper:
|
||||
|
||||
|
||||
@classmethod
|
||||
def crack(cls, hs):
|
||||
Color.pl('\n{+} Cracking {C}%s{W} ({C}%s{W}) using {G}%s{W} method' % (hs['essid'], hs['bssid'], hs['type']))
|
||||
def crack(cls, hs, tool):
|
||||
Color.pl('\n{+} Cracking {G}%s {C}%s{W} ({C}%s{W})' % (
|
||||
cls.TYPES[hs['type']], hs['essid'], hs['bssid']))
|
||||
|
||||
if hs['type'] == 'PMKID':
|
||||
crack_result = cls.crack_pmkid(hs)
|
||||
crack_result = cls.crack_pmkid(hs, tool)
|
||||
elif hs['type'] == '4-WAY':
|
||||
crack_result = cls.crack_4way(hs)
|
||||
crack_result = cls.crack_4way(hs, tool)
|
||||
else:
|
||||
raise ValueError('Cannot crack handshake: Type is not PMKID or 4-WAY. Handshake=%s' % hs)
|
||||
|
||||
@@ -174,20 +206,25 @@ class CrackHelper:
|
||||
|
||||
|
||||
@classmethod
|
||||
def crack_4way(cls, hs):
|
||||
from ..attack.wpa import AttackWPA
|
||||
from ..model.handshake import Handshake
|
||||
from ..model.wpa_result import CrackResultWPA
|
||||
def crack_4way(cls, hs, tool):
|
||||
|
||||
handshake = Handshake(hs['filename'],
|
||||
bssid=hs['bssid'],
|
||||
essid=hs['essid'])
|
||||
|
||||
key = None
|
||||
try:
|
||||
key = AttackWPA.crack_handshake(handshake, Configuration.wordlist, verbose=True)
|
||||
except KeyboardInterrupt:
|
||||
Color.pl('\n{!} Interrupted')
|
||||
handshake.divine_bssid_and_essid()
|
||||
except ValueError as e:
|
||||
Color.pl('{!} {R}Error: {O}%s{W}' % e)
|
||||
return None
|
||||
|
||||
if tool == 'aircrack':
|
||||
key = Aircrack.crack_handshake(handshake, show_command=True)
|
||||
elif tool == 'hashcat':
|
||||
key = Hashcat.crack_handshake(handshake, show_command=True)
|
||||
elif tool == 'john':
|
||||
key = John.crack_handshake(handshake, show_command=True)
|
||||
elif tool == 'cowpatty':
|
||||
key = Cowpatty.crack_handshake(handshake, show_command=True)
|
||||
|
||||
if key is not None:
|
||||
return CrackResultWPA(hs['bssid'], hs['essid'], hs['filename'], key)
|
||||
@@ -196,15 +233,11 @@ class CrackHelper:
|
||||
|
||||
|
||||
@classmethod
|
||||
def crack_pmkid(cls, hs):
|
||||
from ..tools.hashcat import Hashcat
|
||||
from ..model.pmkid_result import CrackResultPMKID
|
||||
def crack_pmkid(cls, hs, tool_name):
|
||||
if tool_name != 'hashcat':
|
||||
Color.pl('{!} {O}Note: PMKIDs can only be cracked using hashcat{W}')
|
||||
|
||||
key = None
|
||||
try:
|
||||
key = Hashcat.crack_pmkid(hs['filename'], verbose=True)
|
||||
except KeyboardInterrupt:
|
||||
Color.pl('\n{!} Interrupted')
|
||||
key = Hashcat.crack_pmkid(hs['filename'], verbose=True)
|
||||
|
||||
if key is not None:
|
||||
return CrackResultPMKID(hs['bssid'], hs['essid'], hs['filename'], key)
|
||||
|
||||
@@ -81,7 +81,7 @@ class Wifite(object):
|
||||
# Attack
|
||||
attacked_targets = AttackAll.attack_multiple(targets)
|
||||
|
||||
Color.pl('{+} Finished attacking {C}%d{W} target(s), exiting' % attacked_targets)
|
||||
Color.pl('\n{+} Finished attacking {C}%d{W} target(s), exiting' % attacked_targets)
|
||||
|
||||
|
||||
##############################################################
|
||||
|
||||
Reference in New Issue
Block a user