diff --git a/wifite/attack/wep.py b/wifite/attack/wep.py index 1812303..41acf80 100755 --- a/wifite/attack/wep.py +++ b/wifite/attack/wep.py @@ -77,7 +77,8 @@ class AttackWEP(Attack): # Start Aireplay process. aireplay = Aireplay(self.target, wep_attack_type, - client_mac=client_mac) + client_mac=client_mac, + replay_file=replay_file) time_unchanged_ivs = time.time() # Timestamp when IVs last changed previous_ivs = 0 @@ -90,7 +91,9 @@ class AttackWEP(Attack): if client_mac is None and len(airodump_target.clients) > 0: client_mac = airodump_target.clients[0].station - status = "%d/{C}%d{W} IVs" % (airodump_target.ivs, Configuration.wep_crack_at_ivs) + total_ivs = airodump_target.ivs + + status = "%d/{C}%d{W} IVs" % (total_ivs, Configuration.wep_crack_at_ivs) if fakeauth_proc: if fakeauth_proc and fakeauth_proc.status: status += ", {G}fakeauth{W}" @@ -123,28 +126,31 @@ class AttackWEP(Attack): Color.p("and {C}cracking{W}") # Check number of IVs, crack if necessary - if airodump_target.ivs > Configuration.wep_crack_at_ivs: + if total_ivs > Configuration.wep_crack_at_ivs: if not aircrack: # Aircrack hasn't started yet. Start it. - ivs_file = airodump.find_files(endswith='.ivs')[0] - aircrack = Aircrack(ivs_file) + ivs_files = airodump.find_files(endswith='.ivs') + if len(ivs_files) > 0: + aircrack = Aircrack(ivs_files[-1]) elif not aircrack.is_running(): # Aircrack stopped running. - Color.pl('\n{!} {O}aircrack stopped running!{W}') - ivs_file = airodump.find_files(endswith='.ivs')[0] - Color.pl('{+} {C}aircrack{W} stopped, restarting...') - self.fake_auth() - aircrack = Aircrack(ivs_file) + #Color.pl('\n{+} {C}aircrack{W} stopped, restarting...') + ivs_files = airodump.find_files(endswith='ivs') + if len(ivs_files) > 0: + aircrack = Aircrack(ivs_files[-1]) + # TODO: Why do we need fakeauth when aircrack stops? + #self.fake_auth() ''' elif Configuration.wep_restart_aircrack > 0 and \ aircrack.pid.running_time() > Configuration.wep_restart_aircrack: # Restart aircrack after X seconds aircrack.stop() - ivs_file = airodump.find_files(endswith='.ivs')[0] + ivs_files = airodump.find_files(endswith='.ivs') Color.pl('\n{+} {C}aircrack{W} ran for more than {C}%d{W} seconds, restarting' % Configuration.wep_restart_aircrack) - aircrack = Aircrack(ivs_file) + if len(ivs_files) > 0: + aircrack = Aircrack(ivs_files[-1]) ''' @@ -277,15 +283,24 @@ class AttackWEP(Attack): # Deauth clients & retry deauth_count = 1 Color.clear_entire_line() + Color.p("\r{+} {O}Deauthenticating *broadcast*{W} (all clients)...") Aireplay.deauth(target.bssid, essid=target.essid) + + attacking_mac = Ifconfig.get_mac(Configuration.interface) for client in target.clients: + if attacking_mac.lower() == client.station.lower(): + continue # Don't deauth ourselves. + Color.clear_entire_line() Color.p("\r{+} {O}Deauthenticating client {C}%s{W}..." % client.station) + Aireplay.deauth(target.bssid, client_mac=client.station, essid=target.essid) deauth_count += 1 + Color.clear_entire_line() Color.pl("\r{+} Sent {C}%d {O}deauths{W}" % deauth_count) + # Re-insert current attack to top of list of attacks remaining attacks_remaining.insert(0, current_attack) return False # Don't stop diff --git a/wifite/tools/aircrack.py b/wifite/tools/aircrack.py index 6f69fcd..68e9414 100755 --- a/wifite/tools/aircrack.py +++ b/wifite/tools/aircrack.py @@ -10,7 +10,9 @@ import os class Aircrack(object): def __init__(self, ivs_file=None): - self.cracked_file = Configuration.temp() + 'wepkey.txt' + self.cracked_file = os.path.abspath( + os.path.join( + Configuration.temp(), 'wepkey.txt')) # Delete previous cracked files if os.path.exists(self.cracked_file): @@ -20,8 +22,11 @@ class Aircrack(object): 'aircrack-ng', '-a', '1', '-l', self.cracked_file, - ivs_file ] + if type(ivs_file) is str: + ivs_file = [ivs_file] + + command.extend(ivs_file) self.pid = Process(command, devnull=True) diff --git a/wifite/tools/aireplay.py b/wifite/tools/aireplay.py index 282ed0a..52d8e93 100755 --- a/wifite/tools/aireplay.py +++ b/wifite/tools/aireplay.py @@ -150,7 +150,7 @@ class Aireplay(Thread): matches = offset_re.match(line) if matches: self.xor_percent = matches.group(1) - self.status = "Generating .xor (%s)..." % matches.group(1) + self.status = "Generating .xor (%s)..." % self.xor_percent # (DONE) Saving keystream in replay_dec-0516-202246.xor saving_re = re.compile(r"Saving keystream in (.*\.xor)") @@ -207,7 +207,7 @@ class Aireplay(Thread): saving_re = re.compile(r"Saving keystream in (.*\.xor)") matches = saving_re.match(line) if matches: - self.status = 'saving keystream to %s' % saving_re.group(1) + self.status = 'saving keystream to %s' % matches.group(1) # XX:XX:XX Now you can build a packet with packetforge-ng out of that 1500 bytes keystream diff --git a/wifite/tools/airodump.py b/wifite/tools/airodump.py index c5467a7..77dfd14 100755 --- a/wifite/tools/airodump.py +++ b/wifite/tools/airodump.py @@ -15,7 +15,7 @@ class Airodump(object): def __init__(self, interface=None, channel=None, encryption=None,\ wps=False, target_bssid=None, output_file_prefix='airodump',\ - ivs_only=False, skip_wps=False): + ivs_only=False, skip_wps=False, delete_existing_files=True): '''Sets up airodump arguments, doesn't start process yet.''' Configuration.initialize() @@ -46,6 +46,8 @@ class Airodump(object): self.decloaked_bssids = set() self.decloaked_times = {} # Map of BSSID(str) -> epoch(int) of last deauth + self.delete_existing_files = delete_existing_files + def __enter__(self): ''' @@ -53,7 +55,8 @@ class Airodump(object): Called at start of 'with Airodump(...) as x:' Actually starts the airodump process. ''' - self.delete_airodump_temp_files() + if self.delete_existing_files: + self.delete_airodump_temp_files(self.output_file_prefix) self.csv_file_prefix = Configuration.temp() + self.output_file_prefix @@ -88,30 +91,35 @@ class Airodump(object): # Kill the process self.pid.interrupt() - # Delete temp files - self.delete_airodump_temp_files() + if self.delete_existing_files: + self.delete_airodump_temp_files(self.output_file_prefix) def find_files(self, endswith=None): + return self.find_files_by_output_prefix(self.output_file_prefix, endswith=endswith) + + @classmethod + def find_files_by_output_prefix(cls, output_file_prefix, endswith=None): ''' Finds all files in the temp directory that start with the output_file_prefix ''' result = [] temp = Configuration.temp() for fil in os.listdir(temp): - if not fil.startswith(self.output_file_prefix): + if not fil.startswith(output_file_prefix): continue - if not endswith or fil.endswith(endswith): + if endswith is None or fil.endswith(endswith): result.append(os.path.join(temp, fil)) return result - def delete_airodump_temp_files(self): + @classmethod + def delete_airodump_temp_files(cls, output_file_prefix): ''' Deletes airodump* files in the temp directory. Also deletes replay_*.cap and *.xor files in pwd. ''' # Remove all temp files - for fil in self.find_files(): + for fil in cls.find_files_by_output_prefix(output_file_prefix): os.remove(fil) # Remove .cap and .xor files from pwd @@ -119,12 +127,18 @@ class Airodump(object): if fil.startswith('replay_') and fil.endswith('.cap') or fil.endswith('.xor'): os.remove(fil) + # Remove replay/cap/xor files from temp + temp_dir = Configuration.temp() + for fil in os.listdir(temp_dir): + if fil.startswith('replay_') and fil.endswith('.cap') or fil.endswith('.xor'): + os.remove(os.path.join(temp_dir, fil)) + def get_targets(self, apply_filter=True): ''' Parses airodump's CSV file, returns list of Targets ''' # Find the .CSV file csv_filename = None - for fil in self.find_files(endswith='-01.csv'): + for fil in self.find_files(endswith='.csv'): csv_filename = fil # Found the file break diff --git a/wifite/util/process.py b/wifite/util/process.py index 5e1bb39..33f2a7f 100755 --- a/wifite/util/process.py +++ b/wifite/util/process.py @@ -2,6 +2,9 @@ # -*- coding: utf-8 -*- import time +import signal +import os + from subprocess import Popen, PIPE from ..util.color import Color @@ -139,27 +142,31 @@ class Process(object): ''' Returns number of seconds since process was started ''' return int(time.time() - self.start_time) - def interrupt(self): + def interrupt(self, wait_time=2.0): ''' Send interrupt to current process. - If process fails to exit within 1 second, terminates it. + If process fails to exit within `wait_time` seconds, terminates it. ''' - from signal import SIGINT, SIGTERM - from os import kill - from time import sleep try: pid = self.pid.pid - kill(pid, SIGINT) + cmd = self.command + if type(cmd) is list: + cmd = ' '.join(cmd) - wait_time = 0 # Time since Interrupt was sent + if Configuration.verbose > 1: + Color.pe('\n {C}[?] {W} sending interrupt to PID %d (%s)' % (pid, cmd)) + + os.kill(pid, signal.SIGINT) + + start_time = time.time() # Time since Interrupt was sent while self.pid.poll() is None: # Process is still running - wait_time += 0.1 - sleep(0.1) - if wait_time > 1: - # We waited over 1 second for process to die - # Terminate it and move on - kill(pid, SIGTERM) + time.sleep(0.1) + if time.time() - start_time > wait_time: + # We waited too long for process to die, terminate it. + if Configuration.verbose > 1: + Color.pe('\n {C}[?] {W} Waited > %0.2f seconds for process to die, killing it' % wait_time) + os.kill(pid, signal.SIGTERM) self.pid.terminate() break