Decloaked ESSIDs will have a "*" next to their name. For #78 While testing, I found that Wifite did not parse Airodump's CSV correctly. Specifically, ESSIDs with commas or trailing spaces. Fixed in this commit. Also fixed hidden ESSID detection introduced by the new CSV parsing logic.
160 lines
5.3 KiB
Python
Executable File
160 lines
5.3 KiB
Python
Executable File
#!/usr/bin/python2.7
|
|
# -*- coding: utf-8 -*-
|
|
|
|
from ..util.color import Color
|
|
|
|
import re
|
|
|
|
class Target(object):
|
|
'''
|
|
Holds details for a "Target" aka Access Point (e.g. router).
|
|
'''
|
|
|
|
def __init__(self, fields):
|
|
'''
|
|
Initializes & stores target info based on fields.
|
|
Args:
|
|
Fields - List of strings
|
|
INDEX KEY EXAMPLE
|
|
0 BSSID (00:1D:D5:9B:11:00)
|
|
1 First time seen (2015-05-27 19:28:43)
|
|
2 Last time seen (2015-05-27 19:28:46)
|
|
3 channel (6)
|
|
4 Speed (54)
|
|
5 Privacy (WPA2)
|
|
6 Cipher (CCMP TKIP)
|
|
7 Authentication (PSK)
|
|
8 Power (-62)
|
|
9 beacons (2)
|
|
10 # IV (0)
|
|
11 LAN IP (0. 0. 0. 0)
|
|
12 ID-length (9)
|
|
13 ESSID (HOME-ABCD)
|
|
14 Key ()
|
|
'''
|
|
self.bssid = fields[0].strip()
|
|
self.channel = fields[3].strip()
|
|
|
|
self.encryption = fields[5].strip()
|
|
if 'WPA' in self.encryption:
|
|
self.encryption = 'WPA'
|
|
elif 'WEP' in self.encryption:
|
|
self.encryption = 'WEP'
|
|
if len(self.encryption) > 4:
|
|
self.encryption = self.encryption[0:4].strip()
|
|
|
|
self.power = int(fields[8].strip())
|
|
if self.power < 0:
|
|
self.power += 100
|
|
|
|
self.beacons = int(fields[9].strip())
|
|
self.ivs = int(fields[10].strip())
|
|
|
|
self.essid_known = True
|
|
self.essid_len = int(fields[12].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()
|
|
|
|
def validate(self):
|
|
''' Checks that the target is valid. '''
|
|
if self.channel == "-1":
|
|
raise Exception("Ignoring target with Negative-One (-1) channel")
|
|
|
|
# Filter broadcast/multicast BSSIDs, see https://github.com/derv82/wifite2/issues/32
|
|
bssid_broadcast = re.compile(r"^(ff:ff:ff:ff:ff:ff|00:00:00:00:00:00)$", re.IGNORECASE)
|
|
if bssid_broadcast.match(self.bssid):
|
|
raise Exception("Ignoring target with Broadcast BSSID (%s)" % self.bssid)
|
|
|
|
bssid_multicast = re.compile(r"^(01:00:5e|01:80:c2|33:33)", re.IGNORECASE)
|
|
if bssid_multicast.match(self.bssid):
|
|
raise Exception("Ignoring target with Multicast BSSID (%s)" % self.bssid)
|
|
|
|
def to_str(self, show_bssid=False):
|
|
'''
|
|
*Colored* string representation of this Target.
|
|
Specifically formatted for the "scanning" table view.
|
|
'''
|
|
|
|
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:
|
|
essid = essid[0:max_essid_len-3] + '...'
|
|
else:
|
|
essid = essid.rjust(max_essid_len)
|
|
|
|
if self.essid_known:
|
|
# Known ESSID
|
|
essid = Color.s("{C}%s" % essid)
|
|
else:
|
|
# 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:
|
|
bssid = ''
|
|
|
|
channel_color = "{G}"
|
|
if int(self.channel) > 14:
|
|
channel_color = "{C}"
|
|
channel = Color.s("%s%s" % (channel_color, str(self.channel).rjust(3)))
|
|
|
|
encryption = self.encryption.rjust(4)
|
|
if 'WEP' in encryption:
|
|
encryption = Color.s("{G}%s" % encryption)
|
|
elif 'WPA' in encryption:
|
|
encryption = Color.s("{O}%s" % encryption)
|
|
|
|
power = '%sdb' % str(self.power).rjust(3)
|
|
if self.power > 50:
|
|
color ='G'
|
|
elif self.power > 35:
|
|
color = 'O'
|
|
else:
|
|
color = 'R'
|
|
power = Color.s('{%s}%s' % (color, power))
|
|
|
|
wps = Color.s('{O} n/a')
|
|
if self.wps == True:
|
|
wps = Color.s('{G} yes')
|
|
elif self.wps == False:
|
|
wps = Color.s('{R} no')
|
|
else:
|
|
wps = Color.s('{O} n/a')
|
|
|
|
clients = ' '
|
|
if len(self.clients) > 0:
|
|
clients = Color.s('{G} ' + str(len(self.clients)))
|
|
|
|
result = '%s %s%s %s %s %s %s' % (
|
|
essid, bssid, channel, encryption, power, wps, clients)
|
|
result += Color.s("{W}")
|
|
return result
|
|
|
|
|
|
if __name__ == '__main__':
|
|
fields = 'AA:BB:CC:DD:EE:FF,2015-05-27 19:28:44,2015-05-27 19:28:46,1,54,WPA2,CCMP TKIP,PSK,-58,2,0,0.0.0.0,9,HOME-ABCD,'.split(',')
|
|
t = Target(fields)
|
|
t.clients.append("asdf")
|
|
t.clients.append("asdf")
|
|
print(t.to_str())
|
|
|