From 345472f3790d4ceca24596df2475feeecf9807ab Mon Sep 17 00:00:00 2001 From: derv82 Date: Thu, 4 Jun 2015 23:41:56 -0700 Subject: [PATCH] Save cracked networks to file. Verbose configuration options. --- Wifite.py | 74 +++++++++++++++++++++++++++++++----- py/Aircrack.py | 2 +- py/Airodump.py | 11 ++++-- py/Arguments.py | 4 +- py/AttackWPS.py | 1 + py/Configuration.py | 92 ++++++++++++++++++++++++++++++++++----------- 6 files changed, 147 insertions(+), 37 deletions(-) diff --git a/Wifite.py b/Wifite.py index 3fbf252..bb6bfcc 100755 --- a/Wifite.py +++ b/Wifite.py @@ -6,10 +6,63 @@ from py.Color import Color from py.AttackWEP import AttackWEP from py.AttackWPA import AttackWPA from py.AttackWPS import AttackWPS +from py.CrackResult import CrackResult +from py.Handshake import Handshake + +from json import loads +import os class Wifite(object): - def __init__(self): - pass + + def main(self): + ''' Either performs action based on arguments, or starts attack scanning ''' + Configuration.initialize(load_interface=False) + + if Configuration.show_cracked: + self.display_cracked() + + elif Configuration.check_handshake: + self.check_handshake(Configuration.check_handshake) + + elif Configuration.crack_wpa: + # TODO: Crack .cap file at crack_wpa + Color.pl('{!} Unimplemented method: crack_wpa') + pass + elif Configuration.crack_wep: + # TODO: Crack .cap file at crack_wep + Color.pl('{!} Unimplemented method: crack_wep') + pass + elif Configuration.update: + # TODO: Get latest version from github + Color.pl('{!} Unimplemented method: update') + pass + else: + self.run() + + def display_cracked(self): + ''' Show cracked targets from cracked.txt ''' + Color.pl('{+} displaying {C}cracked target(s){W}') + name = CrackResult.cracked_file + if not os.path.exists(name): + Color.pl('{!} {O}file {C}%s{O} not found{W}' % name) + return + f = open(name, 'r') + json = loads(f.read()) + f.close() + for (index, item) in enumerate(json): + Color.pl('\n{+} Cracked target #%d:' % (index + 1)) + cr = CrackResult.load(item) + cr.dump() + + def check_handshake(self, capfile): + ''' Analyzes .cap file for handshake ''' + Color.pl('{+} checking for handshake in .cap file {C}%s{W}' % capfile) + if not os.path.exists(capfile): + Color.pl('{!} {O}.cap file {C}%s{O} not found{W}' % capfile) + return + hs = Handshake(capfile) + hs.analyze() + def run(self): ''' @@ -27,29 +80,30 @@ class Wifite(object): for t in targets: Color.pl('{+} starting attacks against {C}%s{W} ({C}%s{W})' % (t.bssid, t.essid)) - if 'WEP' in t.encryption: # TODO: and configuration.use_wep + if 'WEP' in t.encryption: attack = AttackWEP(t) attack.run() elif 'WPA' in t.encryption: - if t.wps: # TODO: and Configuration.use_wps + if t.wps: attack = AttackWPS(t) if attack.run(): # We cracked it. break - else: # TODO: and Configuration.use_wpa + else: # WPS failed, try WPA handshake. attack = AttackWPA(t) attack.run() - else: # TODO: and Configuration.use_wpa + else: # Not using WPS, try WPA handshake. attack = AttackWPA(t) attack.run() else: - # TODO: Error: Can't attack - encryption not WEP or WPA + Color.pl("{!} {R}Error: {O}unable to attack: encryption not WEP or WPA") + continue pass - # TODO: if attack.successful: - # TODO: Save attack.crack_result + if attack.success: + attack.crack_result.save() pass def print_banner(self): @@ -73,7 +127,7 @@ if __name__ == '__main__': w = Wifite() try: w.print_banner() - w.run() + w.main() except Exception, e: Color.pl('\n{!} {R}Error:{O} %s{W}' % str(e)) from traceback import format_exc diff --git a/py/Aircrack.py b/py/Aircrack.py index 90ffb80..1ccc2b3 100644 --- a/py/Aircrack.py +++ b/py/Aircrack.py @@ -71,7 +71,7 @@ class Aircrack(object): if __name__ == '__main__': from time import sleep - Configuration.initialize() + Configuration.initialize(False) a = Aircrack('tests/files/wep-crackable.ivs') while a.is_running(): sleep(1) diff --git a/py/Airodump.py b/py/Airodump.py index 7cece41..c862040 100644 --- a/py/Airodump.py +++ b/py/Airodump.py @@ -11,10 +11,12 @@ import os class Airodump(object): ''' Wrapper around airodump-ng program ''' - def __init__(self, interface=None, channel=None, encryption=None, \ - wps=False, target_bssid=None, output_file_prefix='airodump', \ - ivs_only=False): - ''' Constructor, sets things up ''' + def __init__(self, interface=None, channel=None, encryption=None,\ + wps=False, target_bssid=None, output_file_prefix='airodump',\ + ivs_only=False): + ''' + Sets up airodump arguments, doesn't start process yet + ''' Configuration.initialize() @@ -42,6 +44,7 @@ class Airodump(object): ''' Setting things up for this context. Called at start of 'with Airodump(...) as x:' + Actually starts the airodump process. ''' self.delete_airodump_temp_files() diff --git a/py/Arguments.py b/py/Arguments.py index c77bfb0..f896b38 100644 --- a/py/Arguments.py +++ b/py/Arguments.py @@ -215,9 +215,11 @@ class Arguments(object): if __name__ == '__main__': from Color import Color from Configuration import Configuration - Configuration.initialize() + Configuration.initialize(False) a = Arguments(Configuration) + ''' args = a.args for (key,value) in sorted(args.__dict__.iteritems()): Color.pl('{C}%s: {G}%s{W}' % (key.ljust(21),value)) + ''' diff --git a/py/AttackWPS.py b/py/AttackWPS.py index b4c7770..c161a06 100644 --- a/py/AttackWPS.py +++ b/py/AttackWPS.py @@ -14,6 +14,7 @@ class AttackWPS(Attack): def __init__(self, target): super(AttackWPS, self).__init__(target) self.success = False + self.crack_result = None def run(self): ''' Run all WPS-related attacks ''' diff --git a/py/Configuration.py b/py/Configuration.py index e33205f..ee532b1 100644 --- a/py/Configuration.py +++ b/py/Configuration.py @@ -1,5 +1,7 @@ #!/usr/bin/python +from Color import Color + import os class Configuration(object): @@ -10,7 +12,7 @@ class Configuration(object): version = 2.00 @staticmethod - def initialize(): + def initialize(load_interface=True): ''' Sets up default initial configuration values. Also sets config values based on command-line arguments. @@ -78,7 +80,7 @@ class Configuration(object): Configuration.wps_skip_rate_limit = True # Skip rate-limited WPS APs # Commands - Configuration.cracked = False + Configuration.show_cracked = False Configuration.check_handshake = None Configuration.crack_wpa = None Configuration.crack_wep = None @@ -87,6 +89,11 @@ class Configuration(object): # Overwrite config values with arguments (if defined) Configuration.load_from_arguments() + if load_interface and Configuration.interface == None: + # Interface wasn't defined, select it! + from Airmon import Airmon + Configuration.interface = Airmon.ask() + @staticmethod def load_from_arguments(): @@ -94,50 +101,92 @@ class Configuration(object): from Arguments import Arguments args = Arguments(Configuration).args - if args.channel: Configuration.target_channel = args.channel - if args.interface: Configuration.interface = args.interface - if args.target_bssid: Configuration.target_bssid = args.target_bssid - if args.target_essid: Configuration.target_essid = args.target_essid + if args.channel: + Configuration.target_channel = args.channel + Color.pl('{+} {C}option:{W} scanning for targets on channel {G}%s{W}' % args.channel) + if args.interface: + Configuration.interface = args.interface + Color.pl('{+} {C}option:{W} using wireless interface {G}%s{W}' % args.interface) + if args.target_bssid: + Configuration.target_bssid = args.target_bssid + Color.pl('{+} {C}option:{W} targeting BSSID {G}%s{W}' % args.target_bssid) + if args.target_essid: + Configuration.target_essid = args.target_essid + Color.pl('{+} {C}option:{W} targeting ESSID {G}%s{W}' % args.target_essid) + # WEP - if args.wep_filter: Configuration.wep_filter = args.wep_filter - if args.wep_pps: Configuration.wep_pps = args.wep_pps - if args.wep_timeout: Configuration.wep_timeout = args.wep_timeout - if args.require_fakeauth: Configuration.require_fakeauth = False + if args.wep_filter: + Configuration.wep_filter = args.wep_filter + if args.wep_pps: + Configuration.wep_pps = args.wep_pps + Color.pl('{+} {C}option:{W} using {G}%d{W} packets-per-second on WEP attacks' % args.wep_pps) + if args.wep_timeout: + Configuration.wep_timeout = args.wep_timeout + Color.pl('{+} {C}option:{W} WEP attack timeout set to {G}%d seconds{W}' % args.wep_timeout) + if args.require_fakeauth: + Configuration.require_fakeauth = False + Color.pl('{+} {C}option:{W} fake-authentication is {G}required{W} for WEP attacks') if args.wep_crack_at_ivs: Configuration.wep_crack_at_ivs = args.wep_crack_at_ivs + Color.pl('{+} {C}option:{W} will start cracking WEP keys at {G}%d IVs{W}' % args.wep_crack_at_ivs) if args.wep_restart_stale_ivs: Configuration.wep_restart_stale_ivs = args.wep_restart_stale_ivs + Color.pl('{+} {C}option:{W} will restart aireplay after {G}%d seconds{W} of no new IVs' % args.wep_restart_stale_ivs) if args.wep_restart_aircrack: Configuration.wep_restart_aircrack = args.wep_restart_aircrack + Color.pl('{+} {C}option:{W} will restart aircrack every {G}%d seconds{W}' % args.wep_restart_aircrack) # WPA - if args.wpa_filter: Configuration.wpa_filter = args.wpa_filter - if args.wordlist: Configuration.wordlist = args.wordlist + if args.wpa_filter: + Configuration.wpa_filter = args.wpa_filter + if args.wordlist: + if os.path.exists(args.wordlist): + Configuration.wordlist = args.wordlist + Color.pl('{+} {C}option:{W} using wordlist {G}%s{W} to crack WPA handshakes' % args.wordlist) + else: + Color.pl('{+} {C}option:{O} wordlist {R}%s{O} was not found, using {R}%s{W}' % (args.wordlist, Configuration.wordlist)) if args.wpa_deauth_timeout: Configuration.wpa_deauth_timeout = args.wpa_deauth_timeout + Color.pl('{+} {C}option:{W} will timeout WPA deauth tries after {G}%d seconds{W}' % args.wpa_deauth_timeout) if args.wpa_attack_timeout: Configuration.wpa_attack_timeout = args.wpa_attack_timeout + Color.pl('{+} {C}option:{W} will timeout WPA attacks after {G}%d seconds{W}' % args.wpa_attack_timeout) if args.wpa_handshake_dir: Configuration.wpa_handshake_dir = args.wpa_handshake_dir + Color.pl('{+} {C}option:{W} will store handshakes to {G}%s{W}' % args.wpa_handshake_dir) # WPS - if args.wps_filter: Configuration.wps_filter = args.wps_filter - if args.reaver_only: Configuration.reaver_only = args.reaver_only - if args.no_reaver: Configuration.no_reaver = args.no_reaver - if args.pixie_only: Configuration.pixie_only = args.pixie_only + if args.wps_filter: + Configuration.wps_filter = args.wps_filter + if args.reaver_only: + Configuration.reaver_only = args.reaver_only + Color.pl('{+} {C}option:{W} will *only* use {G}reaver{W} to attack WPA targets' % args.reaver_only) + if args.no_reaver: + Configuration.no_reaver = args.no_reaver + Color.pl('{+} {C}option:{W} will *never* use {G}reaver{W} to attack WPA targets' % args.no_reaver) + if args.pixie_only: + Configuration.pixie_only = args.pixie_only + Color.pl('{+} {C}option:{W} will only use {G}WPS pixie-dust attack{W} on WPS targets' % args.pixie_only) if args.wps_pixie_timeout: Configuration.wps_pixie_timeout = args.wps_pixie_timeout + Color.pl('{+} {C}option:{W} WPS pixie-dust attack will timeout after {G}%d seconds{W}' % args.wps_pixie_timeout) if args.wps_pin_timeout: Configuration.wps_pin_timeout = args.wps_pin_timeout + Color.pl('{+} {C}option:{W} WPS PIN attack will timeout after {G}%d seconds{W}' % args.wps_pin_timeout) if args.wps_max_retries: Configuration.wps_max_retries = args.wps_max_retries + Color.pl('{+} {C}option:{W} will stop WPS attack after {G}%d retries{W}' % args.wps_max_retries) if args.wps_fail_threshold: Configuration.wps_fail_threshold = args.wps_fail_threshold + Color.pl('{+} {C}option:{W} will stop WPS attack after {G}%d failures{W}' % args.wps_fail_threshold) if args.wps_timeout_threshold: Configuration.wps_timeout_threshold = args.wps_timeout_threshold + Color.pl('{+} {C}option:{W} will stop WPS attack after {G}%d timeouts{W}' % args.wps_timeout_threshold) if args.wps_ignore_rate_limit: Configuration.wps_skip_rate_limit = not args.wps_ignore_rate_limit + else: + Color.pl('{+} {C}option:{W} will {G}NOT{W} ignore WPS rate limits') # Adjust encryption filter if Configuration.wep_filter or \ @@ -149,17 +198,18 @@ class Configuration(object): if Configuration.wpa_filter: Configuration.encryption_filter.append('WPA') if Configuration.wps_filter: Configuration.encryption_filter.append('WPS') + if len(Configuration.encryption_filter) == 3: + Color.pl('{+} {C}option:{W} targeting {G}all encrypted networks{W}') + else: + Color.pl('{+} {C}option:{W} targeting networks with encryption: {G}%s{W}' + % ' or '.join(Configuration.encryption_filter)) + # Commands if args.cracked: Configuration.show_cracked = True if args.crack_wpa: Configuration.crack_wpa = args.crack_wpa if args.crack_wep: Configuration.crack_wep = args.crack_wep if args.update: Configuration.update = True if args.check_handshake: Configuration.check_handshake = args.check_handshake - - if Configuration.interface == None: - # Interface wasn't defined, select it! - from Airmon import Airmon - Configuration.interface = Airmon.ask() @staticmethod