diff --git a/tests/files/airodump-weird-ssids.csv b/tests/files/airodump-weird-ssids.csv new file mode 100644 index 0000000..ac57f39 --- /dev/null +++ b/tests/files/airodump-weird-ssids.csv @@ -0,0 +1,13 @@ + +BSSID, First time seen, Last time seen, channel, Speed, Privacy, Cipher, Authentication, Power, # beacons, # IV, LAN IP, ID-length, ESSID, Key +AA:BB:CC:DD:EE:FF, 2018-04-06 18:21:23, 2018-04-06 18:21:24, 10, 54, WPA2, CCMP,PSK, -34, 5, 0, 0. 0. 0. 0, 24, Comma\, no trailing space, +AA:BB:CC:DD:EE:FF, 2018-04-06 18:19:17, 2018-04-06 18:19:19, 10, 54, WPA2, CCMP,PSK, -35, 18, 0, 0. 0. 0. 0, 20, \"Quoted ESSID\, Comma\, no trailing spaces. \", +AA:BB:CC:DD:EE:FF, 2018-04-06 18:35:29, 2018-04-06 18:35:30, 10, 54, WPA2, CCMP,PSK, -31, 12, 0, 0. 0. 0. 0, 22, "Comma\, Trailing space ", +AA:BB:CC:DD:EE:FF, 2018-04-06 18:22:45, 2018-04-06 18:22:46, 10, 54, WPA2, CCMP,PSK, -29, 15, 0, 0. 0. 0. 0, 30, "\"quote\" comma\, trailing space ", +AA:BB:CC:DD:EE:FF, 2018-04-06 18:50:11, 2018-04-06 18:50:17, 10, 54, WPA2, CCMP,PSK, -20, 43, 0, 0. 0. 0. 0, 19, \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00, + + + + +Station MAC, First time seen, Last time seen, Power, # packets, BSSID, Probed ESSIDs + diff --git a/tests/test_Airodump.py b/tests/test_Airodump.py new file mode 100644 index 0000000..5d085b6 --- /dev/null +++ b/tests/test_Airodump.py @@ -0,0 +1,52 @@ +#!/usr/bin/python2.7 +# -*- coding: utf-8 -*- + +import sys +sys.path.insert(0, '..') + +from wifite.tools.airodump import Airodump + +import unittest + +class TestAirodump(unittest.TestCase): + ''' Test suite for Wifite's interaction with the Airodump tool ''' + + + def test_airodump_weird_characters(self): + csv_filename = self.getFile('airodump-weird-ssids.csv') + targets = Airodump.get_targets_from_csv(csv_filename) + + target = targets[0] + expected = 'Comma, no trailing space' + assert target.essid == expected, 'Expected ESSID (%s) but got (%s)' % (expected, target.essid) + + target = targets[1] + expected = '"Quoted ESSID, Comma, no trailing spaces. "' + assert target.essid == expected, 'Expected ESSID (%s) but got (%s)' % (expected, target.essid) + + target = targets[2] + expected = 'Comma, Trailing space ' + assert target.essid == expected, 'Expected ESSID (%s) but got (%s)' % (expected, target.essid) + + target = targets[3] + expected = '"quote" comma, trailing space ' + assert target.essid == expected, 'Expected ESSID (%s) but got (%s)' % (expected, target.essid) + + # Hidden access point + target = targets[4] + assert target.essid_known == False, 'ESSID full of null characters should not be known' + expected = None + assert target.essid == expected, 'Expected ESSID (%s) but got (%s)' % (expected, target.essid) + assert target.essid_len == 19, 'ESSID length shold be 19, but got %s' % target.essid_len + + + def getFile(self, filename): + ''' Helper method to parse targets from filename ''' + import os, inspect + this_file = os.path.abspath(inspect.getsourcefile(self.getFile)) + this_dir = os.path.dirname(this_file) + return os.path.join(this_dir, 'files', filename) + + +if __name__ == '__main__': + unittest.main() diff --git a/wifite/config.py b/wifite/config.py index 225a36e..d434de1 100755 --- a/wifite/config.py +++ b/wifite/config.py @@ -12,7 +12,7 @@ class Configuration(object): initialized = False # Flag indicating config has been initialized temp_dir = None # Temporary directory - version = '2.1.1' + version = '2.1.2' @staticmethod def initialize(load_interface=True): diff --git a/wifite/model/target.py b/wifite/model/target.py index 3d79c87..e7648d7 100755 --- a/wifite/model/target.py +++ b/wifite/model/target.py @@ -52,14 +52,18 @@ class Target(object): self.essid_known = True self.essid_len = int(fields[12].strip()) - self.essid = fields[13].strip() - if self.essid == '\\x00' * self.essid_len or self.essid.strip() == '': + self.essid = fields[13] + if self.essid == '\\x00' * self.essid_len or \ + self.essid == 'x00' * self.essid_len or \ + self.essid.strip() == '': # Don't display "\x00..." for hidden ESSIDs self.essid = None # '(%s)' % self.bssid self.essid_known = False self.wps = None + self.decloaked = False # If ESSID was hidden but we decloaked it. + self.clients = [] self.validate() @@ -84,7 +88,7 @@ class Target(object): Specifically formatted for the "scanning" table view. ''' - max_essid_len = 25 + max_essid_len = 24 essid = self.essid if self.essid_known else "(%s)" % self.bssid # Trim ESSID (router name) if needed if len(essid) > max_essid_len: @@ -99,6 +103,10 @@ class Target(object): # Unknown ESSID essid = Color.s("{O}%s" % essid) + # Add a "*" if we decloaked the ESSID + decloaked_char = '*' if self.decloaked else ' ' + essid += Color.s("{P}%s" % decloaked_char) + if show_bssid: bssid = Color.s('{O}%s ' % self.bssid) else: diff --git a/wifite/tools/airodump.py b/wifite/tools/airodump.py index 91786c0..ccfa72d 100755 --- a/wifite/tools/airodump.py +++ b/wifite/tools/airodump.py @@ -45,7 +45,7 @@ class Airodump(object): # For tracking decloaked APs (previously were hidden) self.decloaking = False - self.decloaked_targets = [] + self.decloaked_bssids = set() self.decloaked_times = {} # Map of BSSID(str) -> epoch(int) of last deauth @@ -161,7 +161,8 @@ class Airodump(object): if old_target.bssid != new_target.bssid: continue if new_target.essid_known and not old_target.essid_known: # We decloaked a target! - self.decloaked_targets.append(new_target) + new_target.decloaked = True + self.decloaked_bssids.add(new_target.bssid) if self.pid.poll() is not None: raise Exception('Airodump has stopped') @@ -185,7 +186,11 @@ class Airodump(object): if type(line) is bytes: line = line.decode('utf-8') line = line.replace('\0', '') lines.append(line) - csv_reader = csv.reader(lines, delimiter=',') + csv_reader = csv.reader(lines, + delimiter=',', + quoting=csv.QUOTE_ALL, + skipinitialspace=True, + escapechar='\\') hit_clients = False for row in csv_reader: @@ -317,4 +322,3 @@ if __name__ == '__main__': Color.pl(' {G}%s %s' % (str(idx).rjust(3), target.to_str())) Configuration.delete_temp() - diff --git a/wifite/util/scanner.py b/wifite/util/scanner.py index 8162c71..ae45049 100755 --- a/wifite/util/scanner.py +++ b/wifite/util/scanner.py @@ -48,6 +48,10 @@ class Scanner(object): # We found the target we want return + for target in self.targets: + if target.bssid in airodump.decloaked_bssids: + target.decloaked = True + self.print_targets() target_count = len(self.targets) @@ -61,11 +65,6 @@ class Scanner(object): outline += " {G}%d{W} target(s)," % target_count outline += " {G}%d{W} client(s)." % client_count outline += " {O}Ctrl+C{W} when ready " - decloaked = airodump.decloaked_targets - if len(decloaked) > 0: - outline += "(decloaked" - outline += " {C}%d{W} ESSIDs:" % len(decloaked) - outline += " {G}%s{W}) " % ", ".join([x.essid for x in decloaked]) Color.clear_entire_line() Color.p(outline)