From f7faf28b081065ff867ab6513e08fe257ef3366a Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Mon, 3 Sep 2018 00:23:51 +0300 Subject: [PATCH 01/16] * Make cracked.txt a configurable variable * Do not show handshake files that are in cracked.txt with a key (match on filename). * Don't ask user for a crack-tool when attacking PMKIDs only * Few minor cleanups --- wifite/config.py | 1 + wifite/model/result.py | 9 ++++---- wifite/util/crack.py | 52 +++++++++++++++++++++++++++++------------- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/wifite/config.py b/wifite/config.py index 010784102..2c907576e 100755 --- a/wifite/config.py +++ b/wifite/config.py @@ -81,6 +81,7 @@ def initialize(cls, load_interface=True): cls.use_pmkid_only = False # Only use PMKID Capture+Crack attack # Default dictionary for cracking + cls.cracked_file = 'cracked.txt' cls.wordlist = None wordlists = [ './wordlist-top4800-probable.txt', # Local file (ran from cloned repo) diff --git a/wifite/model/result.py b/wifite/model/result.py index 7dd6084f2..dcb4089bf 100755 --- a/wifite/model/result.py +++ b/wifite/model/result.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- from ..util.color import Color +from ..config import Configuration import os import time @@ -11,7 +12,7 @@ class CrackResult(object): ''' Abstract class containing results from a crack session ''' # File to save cracks to, in PWD - cracked_file = 'cracked.txt' + cracked_file = Configuration.cracked_file def __init__(self): self.date = int(time.time()) @@ -55,8 +56,8 @@ def save(self): this_dict['date'] = entry.get('date') if entry == this_dict: # Skip if we already saved this BSSID+ESSID+TYPE+KEY - Color.pl('{+} {C}%s{O} already exists in {G}cracked.txt{O}, skipping.' % ( - self.essid)) + Color.pl('{+} {C}%s{O} already exists in {G}%s{O}, skipping.' % ( + self.essid, Configuration.cracked_file)) return saved_results.append(self.to_dict()) @@ -67,7 +68,7 @@ def save(self): @classmethod def display(cls): - ''' Show cracked targets from cracked.txt ''' + ''' Show cracked targets from cracked file ''' name = cls.cracked_file if not os.path.exists(name): Color.pl('{!} {O}file {C}%s{O} not found{W}' % name) diff --git a/wifite/util/crack.py b/wifite/util/crack.py index 5a5b6a0fa..118a7d1f0 100755 --- a/wifite/util/crack.py +++ b/wifite/util/crack.py @@ -13,14 +13,14 @@ from ..tools.hashcat import Hashcat, HcxPcapTool from ..tools.john import John -from datetime import datetime +from json import loads import os # TODO: Bring back the 'print' option, for easy copy/pasting. Just one-liners people can paste into terminal. -# TODO: Do not show handshake files that are in cracked.txt with a key (match on filename). +# TODO: Add an ability to select multiple dictionaries from a directory (the directory may possibly be an argument to the script --wordlist-dir). # TODO: --no-crack option while attacking targets (implies user will run --crack later) @@ -32,7 +32,6 @@ class CrackHelper: 'PMKID': 'PMKID Hash' } - @classmethod def run(cls): Configuration.initialize(False) @@ -79,14 +78,16 @@ def run(cls): dep_list = ', '.join([dep.dependency_name for dep in deps]) Color.pl(' {R}* {R}%s {W}({O}%s{W})' % (tool, dep_list)) - Color.p('\n{+} Enter the {C}cracking tool{W} to use ({C}%s{W}): {G}' % ( - '{W}, {C}'.join(available_tools.keys()))) - tool_name = raw_input() - if tool_name not in available_tools: - Color.pl('{!} {R}"%s"{O} tool not found, defaulting to {C}aircrack{W}' % tool_name) - tool_name = 'aircrack' - elif any_pmkid and tool_name != 'hashcat': + if any_pmkid: Color.pl('{!} {O}Note: PMKID hashes will be cracked using {C}hashcat{W}') + tool_name = 'hashcat' + else: + Color.p('\n{+} Enter the {C}cracking tool{W} to use ({C}%s{W}): {G}' % ( + '{W}, {C}'.join(available_tools.keys()))) + tool_name = raw_input() + if tool_name not in available_tools: + Color.pl('{!} {R}"%s"{O} tool not found, defaulting to {C}aircrack{W}' % tool_name) + tool_name = 'aircrack' try: for hs in hs_to_crack: @@ -94,11 +95,26 @@ def run(cls): except KeyboardInterrupt: Color.pl('\n{!} {O}Interrupted{W}') + @classmethod + def is_cracked(cls, file): + if not os.path.exists(Configuration.cracked_file): + return False + with open(Configuration.cracked_file) as f: + json = loads(f.read()) + if json is None: + return False + for result in json: + for k in result.keys(): + v = result[k] + if 'file' in k and v.split('/')[1] == file: + return True + return False + @classmethod def get_handshakes(cls): handshakes = [] - skipped_pmkid_files = 0 + skipped_pmkid_files = skipped_cracked_files = 0 hs_dir = Configuration.wpa_handshake_dir if not os.path.exists(hs_dir) or not os.path.isdir(hs_dir): @@ -110,6 +126,10 @@ def get_handshakes(cls): if hs_file.count('_') != 3: continue + if cls.is_cracked(hs_file): + skipped_cracked_files += 1 + continue + if hs_file.endswith('.cap'): # WPA Handshake hs_type = '4-WAY' @@ -148,7 +168,9 @@ def get_handshakes(cls): handshakes.append(handshake) if skipped_pmkid_files > 0: - Color.pl('{!} {O}Skipping %d {R}*.16800{O} files because {R}hashcat{O} is missing.' % skipped_pmkid_files) + Color.pl('{!} {O}Skipping %d {R}*.16800{O} files because {R}hashcat{O} is missing.\n' % skipped_pmkid_files) + if skipped_cracked_files > 0: + Color.pl('{!} {O}Skipping %d already cracked files.\n' % skipped_cracked_files) # Sort by Date (Descending) return sorted(handshakes, key=lambda x: x.get('date'), reverse=True) @@ -170,8 +192,6 @@ def print_handshakes(cls, handshakes): Color.p(' ' + ('-' * 19) + '{W}\n') # Handshakes for index, handshake in enumerate(handshakes, start=1): - bssid = handshake['bssid'] - date = handshake['date'] Color.p(' {G}%s{W}' % str(index).rjust(3)) Color.p(' {C}%s{W}' % handshake['essid'].ljust(max_essid_len)) Color.p(' {O}%s{W}' % handshake['bssid'].ljust(17)) @@ -208,7 +228,7 @@ def crack(cls, hs, tool): cls.TYPES[hs['type']], hs['essid'], hs['bssid'])) if hs['type'] == 'PMKID': - crack_result = cls.crack_pmkid(hs, tool) + crack_result = cls.crack_pmkid(hs) elif hs['type'] == '4-WAY': crack_result = cls.crack_4way(hs, tool) else: @@ -253,7 +273,7 @@ def crack_4way(cls, hs, tool): @classmethod - def crack_pmkid(cls, hs, tool_name): + def crack_pmkid(cls, hs): key = Hashcat.crack_pmkid(hs['filename'], verbose=True) if key is not None: From 2ebfb13e369abbe831a24c34782750c7c4670933 Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Mon, 3 Sep 2018 20:44:06 +0300 Subject: [PATCH 02/16] * Fixed any_pmkid -> all_pmkid (to decide that we are strictly using hashcat) * Added a safe-check to make sure we are indeed using hashcat for the PMKID hashes * Changed the ugly split() to basename() --- wifite/util/crack.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/wifite/util/crack.py b/wifite/util/crack.py index 118a7d1f0..51fb29139 100755 --- a/wifite/util/crack.py +++ b/wifite/util/crack.py @@ -52,7 +52,7 @@ def run(cls): return hs_to_crack = cls.get_user_selection(handshakes) - any_pmkid = any([hs['type'] == 'PMKID' for hs in hs_to_crack]) + all_pmkid = all([hs['type'] == 'PMKID' for hs in hs_to_crack]) # Tools for cracking & their dependencies. available_tools = { @@ -78,7 +78,7 @@ def run(cls): dep_list = ', '.join([dep.dependency_name for dep in deps]) Color.pl(' {R}* {R}%s {W}({O}%s{W})' % (tool, dep_list)) - if any_pmkid: + if all_pmkid: Color.pl('{!} {O}Note: PMKID hashes will be cracked using {C}hashcat{W}') tool_name = 'hashcat' else: @@ -91,6 +91,8 @@ def run(cls): try: for hs in hs_to_crack: + if tool_name != 'hashcat' and hs['type'] == 'PMKID': + cls.crack(hs, 'hashcat') cls.crack(hs, tool_name) except KeyboardInterrupt: Color.pl('\n{!} {O}Interrupted{W}') @@ -106,7 +108,7 @@ def is_cracked(cls, file): for result in json: for k in result.keys(): v = result[k] - if 'file' in k and v.split('/')[1] == file: + if 'file' in k and os.path.basename(v) == file: return True return False From 4ece1d4c437558e32b347ad9cec47940f0a44502 Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Mon, 3 Sep 2018 20:44:06 +0300 Subject: [PATCH 03/16] * Fixed any_pmkid -> all_pmkid (to decide that we are strictly using hashcat) * Added a safe-check to make sure we are indeed using hashcat for the PMKID hashes * Changed the ugly split() to basename() --- wifite/util/crack.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/wifite/util/crack.py b/wifite/util/crack.py index 118a7d1f0..e8d405020 100755 --- a/wifite/util/crack.py +++ b/wifite/util/crack.py @@ -52,7 +52,7 @@ def run(cls): return hs_to_crack = cls.get_user_selection(handshakes) - any_pmkid = any([hs['type'] == 'PMKID' for hs in hs_to_crack]) + all_pmkid = all([hs['type'] == 'PMKID' for hs in hs_to_crack]) # Tools for cracking & their dependencies. available_tools = { @@ -78,7 +78,7 @@ def run(cls): dep_list = ', '.join([dep.dependency_name for dep in deps]) Color.pl(' {R}* {R}%s {W}({O}%s{W})' % (tool, dep_list)) - if any_pmkid: + if all_pmkid: Color.pl('{!} {O}Note: PMKID hashes will be cracked using {C}hashcat{W}') tool_name = 'hashcat' else: @@ -91,6 +91,11 @@ def run(cls): try: for hs in hs_to_crack: + if tool_name != 'hashcat' and hs['type'] == 'PMKID': + if 'hashcat' in missing_tools: + Color.pl('{!} {O}Hashcat is missing, therefore we cannot crack PMKID hash{W}') + else: + cls.crack(hs, 'hashcat') cls.crack(hs, tool_name) except KeyboardInterrupt: Color.pl('\n{!} {O}Interrupted{W}') @@ -106,7 +111,7 @@ def is_cracked(cls, file): for result in json: for k in result.keys(): v = result[k] - if 'file' in k and v.split('/')[1] == file: + if 'file' in k and os.path.basename(v) == file: return True return False From 2fb09661348ffe394369ca37ff11378548c91321 Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Mon, 3 Sep 2018 20:52:42 +0300 Subject: [PATCH 04/16] Making an FR from the TODO --- wifite/util/crack.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/wifite/util/crack.py b/wifite/util/crack.py index e8d405020..b28f0084d 100755 --- a/wifite/util/crack.py +++ b/wifite/util/crack.py @@ -20,8 +20,6 @@ # TODO: Bring back the 'print' option, for easy copy/pasting. Just one-liners people can paste into terminal. -# TODO: Add an ability to select multiple dictionaries from a directory (the directory may possibly be an argument to the script --wordlist-dir). - # TODO: --no-crack option while attacking targets (implies user will run --crack later) class CrackHelper: From 5f3713dfc1b8a3c999137801611e339c19fea9a8 Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Mon, 3 Sep 2018 21:31:25 +0300 Subject: [PATCH 05/16] Allow the user to specify how much time to wait for the PMKID capture * Added PMKID argument group --- wifite/args.py | 29 +++++++++++++++++++---------- wifite/attack/pmkid.py | 2 +- wifite/config.py | 19 +++++++++++++++---- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/wifite/args.py b/wifite/args.py index 3f3048d97..408f3d542 100755 --- a/wifite/args.py +++ b/wifite/args.py @@ -31,6 +31,7 @@ def get_arguments(self): self._add_wep_args(parser.add_argument_group(Color.s('{C}WEP{W}'))) self._add_wpa_args(parser.add_argument_group(Color.s('{C}WPA{W}'))) self._add_wps_args(parser.add_argument_group(Color.s('{C}WPS{W}'))) + self._add_pmkid_args(parser.add_argument_group(Color.s('{C}PMKID{W}'))) self._add_eviltwin_args(parser.add_argument_group(Color.s('{C}EVIL TWIN{W}'))) self._add_command_args(parser.add_argument_group(Color.s('{C}COMMANDS{W}'))) @@ -292,15 +293,6 @@ def _add_wpa_args(self, wpa): wpa.add_argument('-wpa', help=argparse.SUPPRESS, action='store_true', dest='wpa_filter') - wpa.add_argument('--pmkid', - action='store_true', - dest='use_pmkid_only', - help=Color.s('{O}Only{W} use {C}PMKID capture{W}, avoids other WPS & ' + - 'WPA attacks (default: {G}off{W})')) - # Alias - wpa.add_argument('-pmkid', action='store_true', dest='use_pmkid_only', - help=argparse.SUPPRESS) - wpa.add_argument('--new-hs', action='store_true', dest='ignore_old_handshakes', @@ -435,6 +427,23 @@ def _add_wps_args(self, wps): wps.add_argument('-wpsto', help=argparse.SUPPRESS, action='store', dest='wps_timeout_threshold', type=int) + def _add_pmkid_args(self, pmkid): + pmkid.add_argument('--pmkid', + action='store_true', + dest='use_pmkid_only', + help=Color.s('{O}Only{W} use {C}PMKID capture{W}, avoids other WPS & ' + + 'WPA attacks (default: {G}off{W})')) + # Alias + pmkid.add_argument('-pmkid', action='store_true', dest='use_pmkid_only', + help=argparse.SUPPRESS) + + pmkid.add_argument('--pmkid-timeout', + action='store', + dest='pmkid_timeout', + metavar='[seconds]', + type=int, + help=Color.s('How many seconds to wait for PMKID hash capture ' + + '(default: {G}%d{W})' % self.config.pmkid_timeout)) def _add_command_args(self, commands): commands.add_argument('--cracked', @@ -462,7 +471,7 @@ def _add_command_args(self, commands): if __name__ == '__main__': from .util.color import Color - from config import Configuration + from .config import Configuration Configuration.initialize(False) a = Arguments(Configuration) args = a.args diff --git a/wifite/attack/pmkid.py b/wifite/attack/pmkid.py index e7ac5d318..01f3680a5 100755 --- a/wifite/attack/pmkid.py +++ b/wifite/attack/pmkid.py @@ -108,7 +108,7 @@ def capture_pmkid(self): The PMKID hash (str) if found, otherwise None. ''' self.keep_capturing = True - self.timer = Timer(15) + self.timer = Timer(Configuration.pmkid_timeout) # Start hcxdumptool t = Thread(target=self.dumptool_thread) diff --git a/wifite/config.py b/wifite/config.py index 2c907576e..6aee349b2 100755 --- a/wifite/config.py +++ b/wifite/config.py @@ -78,7 +78,10 @@ def initialize(cls, load_interface=True): cls.wpa_handshake_dir = 'hs' # Dir to store handshakes cls.wpa_strip_handshake = False # Strip non-handshake packets cls.ignore_old_handshakes = False # Always fetch a new handshake + + # PMKID cls.use_pmkid_only = False # Only use PMKID Capture+Crack attack + cls.pmkid_timeout = 15 # how much time we should wait for a PMKID hash # Default dictionary for cracking cls.cracked_file = 'cracked.txt' @@ -140,6 +143,7 @@ def load_from_arguments(cls): cls.parse_wep_args(args) cls.parse_wpa_args(args) cls.parse_wps_args(args) + cls.parse_pmkid_args(args) cls.parse_encryption() # EvilTwin @@ -304,10 +308,6 @@ def parse_wpa_args(cls, args): Color.pl('{+} {C}option:{W} will {O}ignore{W} existing handshakes ' + '(force capture)') - if args.use_pmkid_only: - cls.use_pmkid_only = True - Color.pl('{+} {C}option:{W} will ONLY use {C}PMKID{W} attack on WPA networks') - if args.wpa_handshake_dir: cls.wpa_handshake_dir = args.wpa_handshake_dir Color.pl('{+} {C}option:{W} will store handshakes to ' + @@ -380,6 +380,17 @@ def parse_wps_args(cls, args): cls.wps_ignore_lock = True Color.pl('{+} {C}option:{W} will {O}ignore{W} WPS lock-outs') + @classmethod + def parse_pmkid_args(cls, args): + if args.use_pmkid_only: + cls.use_pmkid_only = True + Color.pl('{+} {C}option:{W} will ONLY use {C}PMKID{W} attack on WPA networks') + + if args.pmkid_timeout: + cls.pmkid_timeout = args.pmkid_timeout + Color.pl('{+} {C}option:{W} PMKID attack timeout set to ' + + '{G}%d seconds{W}' % args.pmkid_timeout) + @classmethod def parse_encryption(cls): '''Adjusts encryption filter (WEP and/or WPA and/or WPS)''' From e6735ad2155ae5492048ed9ca63653fa1a5819c6 Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Mon, 3 Sep 2018 21:59:34 +0300 Subject: [PATCH 06/16] Allow the user to specify how much time to wait for the PMKID capture * Added PMKID argument group --- wifite/args.py | 34 ++++++++++++++++------------------ wifite/config.py | 4 +++- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/wifite/args.py b/wifite/args.py index 2be24bf00..80f7cf462 100755 --- a/wifite/args.py +++ b/wifite/args.py @@ -31,6 +31,7 @@ def get_arguments(self): self._add_wep_args(parser.add_argument_group(Color.s('{C}WEP{W}'))) self._add_wpa_args(parser.add_argument_group(Color.s('{C}WPA{W}'))) self._add_wps_args(parser.add_argument_group(Color.s('{C}WPS{W}'))) + self._add_pmkid_args(parser.add_argument_group(Color.s('{C}PMKID{W}'))) self._add_eviltwin_args(parser.add_argument_group(Color.s('{C}EVIL TWIN{W}'))) self._add_command_args(parser.add_argument_group(Color.s('{C}COMMANDS{W}'))) @@ -292,23 +293,6 @@ def _add_wpa_args(self, wpa): wpa.add_argument('-wpa', help=argparse.SUPPRESS, action='store_true', dest='wpa_filter') - wpa.add_argument('--pmkid', - action='store_true', - dest='use_pmkid_only', - help=Color.s('{O}Only{W} use {C}PMKID capture{W}, avoids other WPS & ' + - 'WPA attacks (default: {G}off{W})')) - # Alias - wpa.add_argument('-pmkid', action='store_true', dest='use_pmkid_only', - help=argparse.SUPPRESS) - - wpa.add_argument('--pmkid-timeout', - action='store', - dest='pmkid_timeout', - metavar='[sec]', - type=int, - help=self._verbose('Time to wait for PMKID capture ' + - '(default: {G}%d{W} seconds)' % self.config.pmkid_timeout)) - wpa.add_argument('--hs-dir', action='store', dest='wpa_handshake_dir', @@ -443,6 +427,20 @@ def _add_wps_args(self, wps): wps.add_argument('-wpsto', help=argparse.SUPPRESS, action='store', dest='wps_timeout_threshold', type=int) + def _add_pmkid_args(self, pmkid): + pmkid.add_argument('-pmkid', '--pmkid', + action='store_true', + dest='use_pmkid_only', + help=Color.s('{O}Only{W} use {C}PMKID capture{W}, avoids other WPS & ' + + 'WPA attacks (default: {G}off{W})')) + + pmkid.add_argument('--pmkid-timeout', + action='store', + dest='pmkid_timeout', + metavar='[sec]', + type=int, + help=Color.s('Time to wait for PMKID capture ' + + '(default: {G}%d{W} seconds)' % self.config.pmkid_timeout)) def _add_command_args(self, commands): commands.add_argument('--cracked', @@ -470,7 +468,7 @@ def _add_command_args(self, commands): if __name__ == '__main__': from .util.color import Color - from config import Configuration + from .config import Configuration Configuration.initialize(False) a = Arguments(Configuration) args = a.args diff --git a/wifite/config.py b/wifite/config.py index 0d3883084..3383b2706 100755 --- a/wifite/config.py +++ b/wifite/config.py @@ -78,6 +78,8 @@ def initialize(cls, load_interface=True): cls.wpa_handshake_dir = 'hs' # Dir to store handshakes cls.wpa_strip_handshake = False # Strip non-handshake packets cls.ignore_old_handshakes = False # Always fetch a new handshake + + # PMKID variables cls.use_pmkid_only = False # Only use PMKID Capture+Crack attack cls.pmkid_timeout = 30 # Time to wait for PMKID capture @@ -311,7 +313,7 @@ def parse_wpa_args(cls, args): if args.pmkid_timeout: cls.pmkid_timeout = args.pmkid_timeout - Color.pl('{+} {C}option:{W} will wait {G}%d{W} seconds during {C}PMKID{W} capture') + Color.pl('{+} {C}option:{W} will wait {G}%d seconds{W} during {C}PMKID{W} capture' % args.pmkid_timeout) if args.wpa_handshake_dir: cls.wpa_handshake_dir = args.wpa_handshake_dir From 17b709478be33b86df2d650e7cf8b9746127ae64 Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Mon, 3 Sep 2018 21:59:34 +0300 Subject: [PATCH 07/16] Allow the user to specify how much time to wait for the PMKID capture * Added PMKID argument group --- wifite/args.py | 34 ++++++++++++++++------------------ wifite/config.py | 21 +++++++++++++-------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/wifite/args.py b/wifite/args.py index 2be24bf00..80f7cf462 100755 --- a/wifite/args.py +++ b/wifite/args.py @@ -31,6 +31,7 @@ def get_arguments(self): self._add_wep_args(parser.add_argument_group(Color.s('{C}WEP{W}'))) self._add_wpa_args(parser.add_argument_group(Color.s('{C}WPA{W}'))) self._add_wps_args(parser.add_argument_group(Color.s('{C}WPS{W}'))) + self._add_pmkid_args(parser.add_argument_group(Color.s('{C}PMKID{W}'))) self._add_eviltwin_args(parser.add_argument_group(Color.s('{C}EVIL TWIN{W}'))) self._add_command_args(parser.add_argument_group(Color.s('{C}COMMANDS{W}'))) @@ -292,23 +293,6 @@ def _add_wpa_args(self, wpa): wpa.add_argument('-wpa', help=argparse.SUPPRESS, action='store_true', dest='wpa_filter') - wpa.add_argument('--pmkid', - action='store_true', - dest='use_pmkid_only', - help=Color.s('{O}Only{W} use {C}PMKID capture{W}, avoids other WPS & ' + - 'WPA attacks (default: {G}off{W})')) - # Alias - wpa.add_argument('-pmkid', action='store_true', dest='use_pmkid_only', - help=argparse.SUPPRESS) - - wpa.add_argument('--pmkid-timeout', - action='store', - dest='pmkid_timeout', - metavar='[sec]', - type=int, - help=self._verbose('Time to wait for PMKID capture ' + - '(default: {G}%d{W} seconds)' % self.config.pmkid_timeout)) - wpa.add_argument('--hs-dir', action='store', dest='wpa_handshake_dir', @@ -443,6 +427,20 @@ def _add_wps_args(self, wps): wps.add_argument('-wpsto', help=argparse.SUPPRESS, action='store', dest='wps_timeout_threshold', type=int) + def _add_pmkid_args(self, pmkid): + pmkid.add_argument('-pmkid', '--pmkid', + action='store_true', + dest='use_pmkid_only', + help=Color.s('{O}Only{W} use {C}PMKID capture{W}, avoids other WPS & ' + + 'WPA attacks (default: {G}off{W})')) + + pmkid.add_argument('--pmkid-timeout', + action='store', + dest='pmkid_timeout', + metavar='[sec]', + type=int, + help=Color.s('Time to wait for PMKID capture ' + + '(default: {G}%d{W} seconds)' % self.config.pmkid_timeout)) def _add_command_args(self, commands): commands.add_argument('--cracked', @@ -470,7 +468,7 @@ def _add_command_args(self, commands): if __name__ == '__main__': from .util.color import Color - from config import Configuration + from .config import Configuration Configuration.initialize(False) a = Arguments(Configuration) args = a.args diff --git a/wifite/config.py b/wifite/config.py index 0d3883084..4634a1048 100755 --- a/wifite/config.py +++ b/wifite/config.py @@ -78,6 +78,8 @@ def initialize(cls, load_interface=True): cls.wpa_handshake_dir = 'hs' # Dir to store handshakes cls.wpa_strip_handshake = False # Strip non-handshake packets cls.ignore_old_handshakes = False # Always fetch a new handshake + + # PMKID variables cls.use_pmkid_only = False # Only use PMKID Capture+Crack attack cls.pmkid_timeout = 30 # Time to wait for PMKID capture @@ -141,6 +143,7 @@ def load_from_arguments(cls): cls.parse_wep_args(args) cls.parse_wpa_args(args) cls.parse_wps_args(args) + cls.parse_pmkid_args(args) cls.parse_encryption() # EvilTwin @@ -305,14 +308,6 @@ def parse_wpa_args(cls, args): Color.pl('{+} {C}option:{W} will {O}ignore{W} existing handshakes ' + '(force capture)') - if args.use_pmkid_only: - cls.use_pmkid_only = True - Color.pl('{+} {C}option:{W} will ONLY use {C}PMKID{W} attack on WPA networks') - - if args.pmkid_timeout: - cls.pmkid_timeout = args.pmkid_timeout - Color.pl('{+} {C}option:{W} will wait {G}%d{W} seconds during {C}PMKID{W} capture') - if args.wpa_handshake_dir: cls.wpa_handshake_dir = args.wpa_handshake_dir Color.pl('{+} {C}option:{W} will store handshakes to ' + @@ -385,6 +380,16 @@ def parse_wps_args(cls, args): cls.wps_ignore_lock = True Color.pl('{+} {C}option:{W} will {O}ignore{W} WPS lock-outs') + @classmethod + def parse_pmkid_args(cls, args): + if args.use_pmkid_only: + cls.use_pmkid_only = True + Color.pl('{+} {C}option:{W} will ONLY use {C}PMKID{W} attack on WPA networks') + + if args.pmkid_timeout: + cls.pmkid_timeout = args.pmkid_timeout + Color.pl('{+} {C}option:{W} will wait {G}%d seconds{W} during {C}PMKID{W} capture' % args.pmkid_timeout) + @classmethod def parse_encryption(cls): '''Adjusts encryption filter (WEP and/or WPA and/or WPS)''' From d5bc6cde30072e255b375b801ec089fcb81b39b5 Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Wed, 5 Sep 2018 02:12:10 +0300 Subject: [PATCH 08/16] Removed unnecessary imports --- wifite/tools/dependency.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/wifite/tools/dependency.py b/wifite/tools/dependency.py index c1a11b22e..3d3f90610 100755 --- a/wifite/tools/dependency.py +++ b/wifite/tools/dependency.py @@ -24,15 +24,11 @@ def exists(cls): def run_dependency_check(cls): from ..util.color import Color - from .airmon import Airmon - from .airodump import Airodump from .aircrack import Aircrack - from .aireplay import Aireplay from .ifconfig import Ifconfig from .iwconfig import Iwconfig from .bully import Bully from .reaver import Reaver - from .wash import Wash from .pyrit import Pyrit from .tshark import Tshark from .macchanger import Macchanger From d15708420b9ef9a6009258e06884683403154ca5 Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Wed, 5 Sep 2018 02:34:59 +0300 Subject: [PATCH 09/16] Save checked-for-existance commands inside a list to not check them over and over again (-vvv not spammed anymore) --- wifite/config.py | 3 +++ wifite/util/process.py | 13 +++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/wifite/config.py b/wifite/config.py index d37135d1a..4a1c72e2e 100755 --- a/wifite/config.py +++ b/wifite/config.py @@ -117,6 +117,9 @@ def initialize(cls, load_interface=True): cls.check_handshake = None cls.crack_handshake = False + # A list to cache all checked commands (e.g. `which hashcat` will execute only once) + cls.existing_commands = {} + # Overwrite config values with arguments (if defined) cls.load_from_arguments() diff --git a/wifite/util/process.py b/wifite/util/process.py index 1200d6b3d..a2ca1f852 100755 --- a/wifite/util/process.py +++ b/wifite/util/process.py @@ -43,7 +43,6 @@ def call(command, cwd=None, shell=False): if type(stdout) is bytes: stdout = stdout.decode('utf-8') if type(stderr) is bytes: stderr = stderr.decode('utf-8') - if Configuration.verbose > 1 and stdout is not None and stdout.strip() != '': Color.pe('{P} [stdout] %s{W}' % '\n [stdout] '.join(stdout.strip().split('\n'))) if Configuration.verbose > 1 and stderr is not None and stderr.strip() != '': @@ -54,14 +53,17 @@ def call(command, cwd=None, shell=False): @staticmethod def exists(program): ''' Checks if program is installed on this system ''' + + if program in set(Configuration.existing_commands.keys()): + return Configuration.existing_commands[program] + p = Process(['which', program]) stdout = p.stdout().strip() stderr = p.stderr().strip() - if stdout == '' and stderr == '': - return False - - return True + exist = not stdout == stderr == '' + Configuration.existing_commands.update({program: exist}) + return exist def __init__(self, command, devnull=False, stdout=PIPE, stderr=PIPE, cwd=None, bufsize=0, stdin=PIPE): ''' Starts executing command ''' @@ -211,4 +213,3 @@ def interrupt(self, wait_time=2.0): time.sleep(1) print('yes should stop now') # After program loses reference to instance in 'p', process dies. - From 5b966594473472f0648dd192f86480eb38d43d0d Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Wed, 5 Sep 2018 02:47:49 +0300 Subject: [PATCH 10/16] Closes the color after the user input actually skip pmkid crack if we dont have hashcat installed --- wifite/util/crack.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wifite/util/crack.py b/wifite/util/crack.py index 68ee19bb6..aa001b6c6 100755 --- a/wifite/util/crack.py +++ b/wifite/util/crack.py @@ -38,6 +38,8 @@ def run(cls): if not Configuration.wordlist: Color.p('\n{+} Enter wordlist file to use for cracking: {G}') Configuration.wordlist = raw_input() + Color.p('{W}') + if not os.path.exists(Configuration.wordlist): Color.pl('{!} {R}Wordlist {O}%s{R} not found. Exiting.' % Configuration.wordlist) return @@ -83,6 +85,8 @@ def run(cls): Color.p('\n{+} Enter the {C}cracking tool{W} to use ({C}%s{W}): {G}' % ( '{W}, {C}'.join(available_tools.keys()))) tool_name = raw_input() + Color.p('{W}') + if tool_name not in available_tools: Color.pl('{!} {R}"%s"{O} tool not found, defaulting to {C}aircrack{W}' % tool_name) tool_name = 'aircrack' @@ -92,6 +96,7 @@ def run(cls): if tool_name != 'hashcat' and hs['type'] == 'PMKID': if 'hashcat' in missing_tools: Color.pl('{!} {O}Hashcat is missing, therefore we cannot crack PMKID hash{W}') + continue cls.crack(hs, tool_name) except KeyboardInterrupt: Color.pl('\n{!} {O}Interrupted{W}') @@ -206,6 +211,7 @@ def get_user_selection(cls, 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() + Color.p('{W}') selection = [] for choice in choices.split(','): From 6d52a2f379a6c1ee9d5b370b1340ec9d5948f7cc Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Wed, 5 Sep 2018 02:59:26 +0300 Subject: [PATCH 11/16] Simplified boolean var checks --- wifite/attack/pmkid.py | 2 +- wifite/attack/wpa.py | 2 +- wifite/config.py | 8 ++++---- wifite/model/target.py | 4 ++-- wifite/tools/wash.py | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/wifite/attack/pmkid.py b/wifite/attack/pmkid.py index 01f3680a5..eacd3cb24 100755 --- a/wifite/attack/pmkid.py +++ b/wifite/attack/pmkid.py @@ -76,7 +76,7 @@ def run(self): pmkid_file = None - if Configuration.ignore_old_handshakes == False: + if not Configuration.ignore_old_handshakes: # Load exisitng PMKID hash from filesystem pmkid_file = self.get_existing_pmkid_file(self.target.bssid) if pmkid_file is not None: diff --git a/wifite/attack/wpa.py b/wifite/attack/wpa.py index 199965bbd..672c9314a 100755 --- a/wifite/attack/wpa.py +++ b/wifite/attack/wpa.py @@ -96,7 +96,7 @@ def capture_handshake(self): self.clients = [] # Try to load existing handshake - if Configuration.ignore_old_handshakes == False: + if not Configuration.ignore_old_handshakes: bssid = airodump_target.bssid essid = airodump_target.essid if airodump_target.essid_known else None handshake = self.load_handshake(bssid=bssid, essid=essid) diff --git a/wifite/config.py b/wifite/config.py index 4a1c72e2e..588810d76 100755 --- a/wifite/config.py +++ b/wifite/config.py @@ -196,15 +196,15 @@ def parse_settings_args(cls, args): Color.pl('{+} {C}option:{W} targeting BSSID ' + '{G}%s{W}' % args.target_bssid) - if args.five_ghz == True: + if args.five_ghz: cls.five_ghz = True Color.pl('{+} {C}option:{W} including {G}5Ghz networks{W} in scans') - if args.show_bssids == True: + if args.show_bssids: cls.show_bssids = True Color.pl('{+} {C}option:{W} showing {G}bssids{W} of targets during scan') - if args.no_deauth == True: + if args.no_deauth: cls.no_deauth = True Color.pl('{+} {C}option:{W} will {R}not{W} {O}deauth{W} clients ' + 'during scans or captures') @@ -223,7 +223,7 @@ def parse_settings_args(cls, args): Color.pl('{+} {C}option:{W} {O}ignoring ESSIDs that include {R}%s{W}' % ( args.ignore_essid)) - if args.clients_only == True: + if args.clients_only: cls.clients_only = True Color.pl('{+} {C}option:{W} {O}ignoring targets that do not have ' + 'associated clients') diff --git a/wifite/model/target.py b/wifite/model/target.py index 26e792506..0f5482157 100755 --- a/wifite/model/target.py +++ b/wifite/model/target.py @@ -134,9 +134,9 @@ def to_str(self, show_bssid=False): power = Color.s('{%s}%s' % (color, power)) wps = Color.s('{O} n/a') - if self.wps == True: + if self.wps: wps = Color.s('{G} yes') - elif self.wps == False: + elif not self.wps: wps = Color.s('{O} no') elif self.wps is None: wps = Color.s('{R}lock') diff --git a/wifite/tools/wash.py b/wifite/tools/wash.py index beac694aa..20e33d61a 100755 --- a/wifite/tools/wash.py +++ b/wifite/tools/wash.py @@ -42,7 +42,7 @@ def check_for_wps_and_update_targets(capfile, targets): obj = json.loads(line) bssid = obj['bssid'] locked = obj['wps_locked'] - if locked != True: + if not locked: wps_bssids.add(bssid) else: locked_bssids.add(bssid) From 8140563cea896349561c86da0ec9b406ac833d1b Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Wed, 5 Sep 2018 03:01:01 +0300 Subject: [PATCH 12/16] The pythonic way to perform a bounds check --- wifite/attack/wep.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wifite/attack/wep.py b/wifite/attack/wep.py index cef71cfd9..1f17edee7 100755 --- a/wifite/attack/wep.py +++ b/wifite/attack/wep.py @@ -154,8 +154,7 @@ def run(self): ivs_files = ivs_files[-1] # Use most-recent .ivs file aircrack = Aircrack(ivs_files) - elif Configuration.wep_restart_aircrack > 0 and \ - aircrack.pid.running_time() > Configuration.wep_restart_aircrack: + elif 0 < Configuration.wep_restart_aircrack < aircrack.pid.running_time(): # Restart aircrack after X seconds #Color.pl('\n{+} {C}aircrack{W} ran for more than {C}%d{W} seconds, restarting' % Configuration.wep_restart_aircrack) aircrack.stop() From cf193bae95fa2cbc73d623bcce9b3ebc5ca686ca Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Wed, 5 Sep 2018 03:15:20 +0300 Subject: [PATCH 13/16] Few minor corrections Make sure all changes are compatible with python2 --- wifite/__main__.py | 9 ++++----- wifite/attack/all.py | 2 +- wifite/attack/wep.py | 6 +++--- wifite/attack/wpa.py | 2 +- wifite/model/handshake.py | 2 +- wifite/tools/aircrack.py | 1 - wifite/tools/aireplay.py | 3 +-- wifite/tools/airmon.py | 10 +++++----- wifite/tools/airodump.py | 6 +++--- wifite/tools/hashcat.py | 1 - wifite/tools/pyrit.py | 2 +- 11 files changed, 20 insertions(+), 24 deletions(-) diff --git a/wifite/__main__.py b/wifite/__main__.py index 314bcb1f6..d6df796e6 100755 --- a/wifite/__main__.py +++ b/wifite/__main__.py @@ -9,7 +9,6 @@ from .util.color import Color import os -import sys class Wifite(object): @@ -53,8 +52,8 @@ def start(self): Configuration.get_monitor_mode_interface() self.scan_and_attack() - - def print_banner(self): + @staticmethod + def print_banner(): '''Displays ASCII art of the highest caliber.''' Color.pl(r' {G} . {GR}{D} {W}{G} . {W}') Color.pl(r' {G}.´ · .{GR}{D} {W}{G}. · `. {G}wifite {D}%s{W}' % Configuration.version) @@ -63,8 +62,8 @@ def print_banner(self): Color.pl(r' {G} ` {GR}{D}/¯¯¯\{W}{G} ´ {W}') Color.pl('') - - def scan_and_attack(self): + @staticmethod + def scan_and_attack(): ''' 1) Scans for targets, asks user to select targets 2) Attacks each target diff --git a/wifite/attack/all.py b/wifite/attack/all.py index 6db4d3718..976466a54 100755 --- a/wifite/attack/all.py +++ b/wifite/attack/all.py @@ -59,7 +59,7 @@ def attack_single(cls, target, targets_remaining): # WPS if not Configuration.use_pmkid_only: - if target.wps != False and AttackWPS.can_attack_wps(): + if not target.wps and AttackWPS.can_attack_wps(): # Pixie-Dust if Configuration.wps_pixie: attacks.append(AttackWPS(target, pixie_dust=True)) diff --git a/wifite/attack/wep.py b/wifite/attack/wep.py index 1f17edee7..92be0742d 100755 --- a/wifite/attack/wep.py +++ b/wifite/attack/wep.py @@ -222,9 +222,9 @@ def run(self): Color.pl('\n{!} restarting {C}aireplay{W} after' + ' {C}%d{W} seconds of no new IVs' % stale_seconds) - aireplay = Aireplay(self.target, \ - wep_attack_type, \ - client_mac=client_mac, \ + aireplay = Aireplay(self.target, + wep_attack_type, + client_mac=client_mac, replay_file=replay_file) time_unchanged_ivs = time.time() last_ivs_count = airodump_target.ivs diff --git a/wifite/attack/wpa.py b/wifite/attack/wpa.py index 672c9314a..64f09a3cf 100755 --- a/wifite/attack/wpa.py +++ b/wifite/attack/wpa.py @@ -171,7 +171,7 @@ def capture_handshake(self): if handshake is None: # No handshake, attack failed. - Color.pl('\n{!} {O}WPA handshake capture {R}FAILED:{O} Timed out after %d seconds' % (Configuration.wpa_attack_timeout)) + Color.pl('\n{!} {O}WPA handshake capture {R}FAILED:{O} Timed out after %d seconds' % Configuration.wpa_attack_timeout) return handshake else: # Save copy of handshake to ./hs/ diff --git a/wifite/model/handshake.py b/wifite/model/handshake.py index 630357047..fd4ccb825 100755 --- a/wifite/model/handshake.py +++ b/wifite/model/handshake.py @@ -183,7 +183,7 @@ def print_pairs(pairs, capfile, tool=None): tool_str = '{C}%s{W}: ' % tool.rjust(8) if len(pairs) == 0: - Color.pl('{!} %s.cap file {R}does not{O} contain a valid handshake{W}' % (tool_str)) + Color.pl('{!} %s.cap file {R}does not{O} contain a valid handshake{W}' % capfile) return for (bssid, essid) in pairs: diff --git a/wifite/tools/aircrack.py b/wifite/tools/aircrack.py index bb0bbe228..26d7b1999 100755 --- a/wifite/tools/aircrack.py +++ b/wifite/tools/aircrack.py @@ -101,7 +101,6 @@ def crack_handshake(handshake, show_command=False): # 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 = '' diff --git a/wifite/tools/aireplay.py b/wifite/tools/aireplay.py index 07cb6b777..90481d06c 100755 --- a/wifite/tools/aireplay.py +++ b/wifite/tools/aireplay.py @@ -250,8 +250,7 @@ def get_aireplay_command(target, attack_type, if Configuration.interface is None: raise Exception('Wireless interface must be defined (-i)') - cmd = ['aireplay-ng'] - cmd.append('--ignore-negative-one') + cmd = ['aireplay-ng', '--ignore-negative-one'] if client_mac is None and len(target.clients) > 0: # Client MAC wasn't specified, but there's an associated client. Use that. diff --git a/wifite/tools/airmon.py b/wifite/tools/airmon.py index a2a45381b..9cbda290e 100755 --- a/wifite/tools/airmon.py +++ b/wifite/tools/airmon.py @@ -121,7 +121,7 @@ def start_bad_driver(iface): iface_type_path = os.path.join('/sys/class/net', iface, 'type') if os.path.exists(iface_type_path): with open(iface_type_path, 'r') as f: - if (int(f.read()) == Airmon.ARPHRD_IEEE80211_RADIOTAP): + if int(f.read()) == Airmon.ARPHRD_IEEE80211_RADIOTAP: return iface return None @@ -140,7 +140,7 @@ def stop_bad_driver(iface): iface_type_path = os.path.join('/sys/class/net', iface, 'type') if os.path.exists(iface_type_path): with open(iface_type_path, 'r') as f: - if (int(f.read()) == Airmon.ARPHRD_ETHER): + if int(f.read()) == Airmon.ARPHRD_ETHER: return iface return None @@ -283,7 +283,7 @@ def ask(): # Assume we're using the device already in montior mode iface = monitor_interfaces[0] Color.clear_entire_line() - Color.pl('{+} Using {G}%s{W} already in monitor mode' % iface); + Color.pl('{+} Using {G}%s{W} already in monitor mode' % iface) Airmon.base_interface = None return iface @@ -308,7 +308,7 @@ def ask(): choice = 1 else: # Multiple interfaces found - question = Color.s('{+} Select wireless interface ({G}1-%d{W}): ' % (count)) + question = Color.s('{+} Select wireless interface ({G}1-%d{W}): ' % count) choice = raw_input(question) iface = a.get(choice) @@ -373,7 +373,7 @@ def terminate_conflicting_processes(): @staticmethod def put_interface_up(iface): - Color.p('{!} {O}putting interface {R}%s up{O}...' % (iface)) + Color.p('{!} {O}putting interface {R}%s up{O}...' % iface) Ifconfig.up(iface) Color.pl(' {G}done{W}') diff --git a/wifite/tools/airodump.py b/wifite/tools/airodump.py index f85015e65..a4beb0942 100755 --- a/wifite/tools/airodump.py +++ b/wifite/tools/airodump.py @@ -17,8 +17,8 @@ class Airodump(Dependency): dependency_name = 'airodump-ng' dependency_url = 'https://www.aircrack-ng.org/install.html' - def __init__(self, interface=None, channel=None, encryption=None,\ - wps=False, target_bssid=None, output_file_prefix='airodump',\ + def __init__(self, interface=None, channel=None, encryption=None, + wps=False, target_bssid=None, output_file_prefix='airodump', ivs_only=False, skip_wps=False, delete_existing_files=True): '''Sets up airodump arguments, doesn't start process yet.''' @@ -224,7 +224,7 @@ def get_targets_from_csv(csv_filename): # The current row corresponds to a 'Client' (computer) try: client = Client(row) - except (IndexError, ValueError) as e: + except (IndexError, ValueError): # Skip if we can't parse the client row continue diff --git a/wifite/tools/hashcat.py b/wifite/tools/hashcat.py index 89aa01731..416b00444 100755 --- a/wifite/tools/hashcat.py +++ b/wifite/tools/hashcat.py @@ -26,7 +26,6 @@ def crack_handshake(handshake, show_command=False): hccapx_file = HcxPcapTool.generate_hccapx_file( handshake, show_command=show_command) - key = None # Crack hccapx for additional_arg in ([], ['--show']): command = [ diff --git a/wifite/tools/pyrit.py b/wifite/tools/pyrit.py index 90e16920a..76b829ad4 100755 --- a/wifite/tools/pyrit.py +++ b/wifite/tools/pyrit.py @@ -39,7 +39,7 @@ def bssid_essid_with_handshakes(capfile, bssid=None, essid=None): for line in pyrit.stdout().split('\n'): mac_regex = ('[a-zA-Z0-9]{2}:' * 6)[:-1] - match = re.search("^#\d+: AccessPoint (%s) \('(.*)'\):$" % (mac_regex), line) + match = re.search("^#\d+: AccessPoint (%s) \('(.*)'\):$" % mac_regex, line) if match: # We found a new BSSID and ESSID (current_bssid, current_essid) = match.groups() From d739d6734a8d76d2cd35de340babebcba469a0f8 Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Wed, 5 Sep 2018 03:29:22 +0300 Subject: [PATCH 14/16] Added hcxtools installation to dockerfile --- Dockerfile | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 2d956ba1e..098777ea7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,7 +44,7 @@ RUN make install # Workdir / WORKDIR / -#Install and configure hashcat +# Install and configure hashcat RUN mkdir hashcat && \ cd hashcat && \ wget https://hashcat.net/files_legacy/${HASHCAT_VERSION}.7z && \ @@ -54,6 +54,14 @@ RUN mkdir hashcat && \ #Add link for binary RUN ln -s /hashcat/hashcat-cli64.bin /usr/bin/hashcat +# Install hcxtools +RUN git clone https://github.com/ZerBea/hcxtools.git +WORKDIR /hcxtools/ +RUN make +RUN make install + +# Workdir / +WORKDIR / # Install reaver RUN git clone https://github.com/gabrielrcouto/reaver-wps.git From a26e41ff6ca1d1d74847ccf5f402273807078ff4 Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Thu, 6 Sep 2018 03:07:57 +0300 Subject: [PATCH 15/16] Avoid unresolved reference error when 4way not cracked --- wifite/tools/hashcat.py | 1 + 1 file changed, 1 insertion(+) diff --git a/wifite/tools/hashcat.py b/wifite/tools/hashcat.py index 416b00444..30ff8b26e 100755 --- a/wifite/tools/hashcat.py +++ b/wifite/tools/hashcat.py @@ -27,6 +27,7 @@ def crack_handshake(handshake, show_command=False): handshake, show_command=show_command) # Crack hccapx + key = None # Avoid unresolved reference when hccapx not cracked for additional_arg in ([], ['--show']): command = [ 'hashcat', From 64d3ac01413ee983b758fa18ab6e5a20eef490f9 Mon Sep 17 00:00:00 2001 From: WhiteOnBlackCode Date: Thu, 6 Sep 2018 04:46:34 +0300 Subject: [PATCH 16/16] Don't attempt to access the existing_cammands if the config not initialized yet --- wifite/util/process.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/wifite/util/process.py b/wifite/util/process.py index a2ca1f852..7168f8d83 100755 --- a/wifite/util/process.py +++ b/wifite/util/process.py @@ -54,15 +54,17 @@ def call(command, cwd=None, shell=False): def exists(program): ''' Checks if program is installed on this system ''' - if program in set(Configuration.existing_commands.keys()): - return Configuration.existing_commands[program] + if Configuration.initialized: # Maybe we already checked this program + if program in set(Configuration.existing_commands.keys()): + return Configuration.existing_commands[program] p = Process(['which', program]) stdout = p.stdout().strip() stderr = p.stderr().strip() exist = not stdout == stderr == '' - Configuration.existing_commands.update({program: exist}) + if Configuration.initialized: + Configuration.existing_commands.update({program: exist}) return exist def __init__(self, command, devnull=False, stdout=PIPE, stderr=PIPE, cwd=None, bufsize=0, stdin=PIPE):