--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:
@@ -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
|
||||
Reference in New Issue
Block a user