Documentation, code-formatting, and refactoring.
* Added some docs, updated existing docs. * Use single-quotes for strings when possible. * Color.pexception() prints exception and stack trace.
This commit is contained in:
@@ -12,7 +12,7 @@ class Attack(object):
|
||||
self.target = target
|
||||
|
||||
def run(self):
|
||||
raise Exception("Unimplemented method: run")
|
||||
raise Exception('Unimplemented method: run')
|
||||
|
||||
def wait_for_target(self, airodump):
|
||||
'''Waits for target to appear in airodump.'''
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
class Client(object):
|
||||
'''
|
||||
Holds details for a "Client" - a wireless device (e.g. computer)
|
||||
Holds details for a 'Client' - a wireless device (e.g. computer)
|
||||
that is associated with an Access Point (e.g. router)
|
||||
'''
|
||||
|
||||
|
||||
@@ -9,19 +9,23 @@ from ..tools.pyrit import Pyrit
|
||||
import re, os
|
||||
|
||||
class Handshake(object):
|
||||
|
||||
def __init__(self, capfile, bssid=None, essid=None):
|
||||
self.capfile = capfile
|
||||
self.bssid = bssid
|
||||
self.essid = essid
|
||||
|
||||
|
||||
def divine_bssid_and_essid(self):
|
||||
'''
|
||||
Tries to find BSSID and ESSID from cap file.
|
||||
Sets this instances 'bssid' and 'essid' instance fields.
|
||||
'''
|
||||
|
||||
# We can get BSSID from the .cap filename if Wifite captured it.
|
||||
# ESSID is stripped of non-printable characters, so we can't rely on that.
|
||||
if self.bssid is None:
|
||||
hs_regex = re.compile(r"^.*handshake_\w+_([0-9A-F\-]{17})_.*\.cap$", re.IGNORECASE)
|
||||
hs_regex = re.compile(r'^.*handshake_\w+_([0-9A-F\-]{17})_.*\.cap$', re.IGNORECASE)
|
||||
match = hs_regex.match(self.capfile)
|
||||
if match:
|
||||
self.bssid = match.group(1).replace('-', ':')
|
||||
@@ -33,7 +37,8 @@ class Handshake(object):
|
||||
pairs = self.pyrit_handshakes() # Find bssid/essid pairs that have handshakes in Pyrit
|
||||
|
||||
if len(pairs) == 0 and not self.bssid and not self.essid:
|
||||
raise Exception("Cannot find BSSID or ESSID in cap file") # Tshark and Pyrit failed us, nothing else we can do.
|
||||
# Tshark and Pyrit failed us, nothing else we can do.
|
||||
raise Exception('Cannot find BSSID or ESSID in cap file')
|
||||
|
||||
if not self.essid and not self.bssid:
|
||||
# We do not know the bssid nor the essid
|
||||
@@ -60,6 +65,7 @@ class Handshake(object):
|
||||
self.essid = essid
|
||||
break
|
||||
|
||||
|
||||
def has_handshake(self):
|
||||
if not self.bssid or not self.essid:
|
||||
self.divine_bssid_and_essid()
|
||||
@@ -75,27 +81,26 @@ class Handshake(object):
|
||||
|
||||
|
||||
def tshark_handshakes(self):
|
||||
''' Returns True if tshark identifies a handshake, False otherwise '''
|
||||
'''Returns list[tuple] of BSSID & ESSID pairs (ESSIDs are always `None`).'''
|
||||
tshark_bssids = Tshark.bssids_with_handshakes(self.capfile, bssid=self.bssid)
|
||||
return [(bssid, None) for bssid in tshark_bssids]
|
||||
|
||||
|
||||
def cowpatty_command(self):
|
||||
return [
|
||||
def cowpatty_handshakes(self):
|
||||
'''Returns list[tuple] of BSSID & ESSID pairs (BSSIDs are always `None`).'''
|
||||
if not Process.exists('cowpatty'):
|
||||
return []
|
||||
if not self.essid:
|
||||
return [] # We need a essid for cowpatty :(
|
||||
|
||||
command = [
|
||||
'cowpatty',
|
||||
'-r', self.capfile,
|
||||
'-s', self.essid,
|
||||
'-c' # Check for handshake
|
||||
]
|
||||
|
||||
def cowpatty_handshakes(self):
|
||||
''' Returns True if cowpatty identifies a handshake, False otherwise '''
|
||||
if not Process.exists('cowpatty'):
|
||||
return []
|
||||
if not self.essid:
|
||||
return [] # We need a essid for cowpatty :(
|
||||
|
||||
proc = Process(self.cowpatty_command(), devnull=False)
|
||||
proc = Process(command, devnull=False)
|
||||
for line in proc.stdout().split('\n'):
|
||||
if 'Collected all necessary data to mount crack against WPA' in line:
|
||||
return [(None, self.essid)]
|
||||
@@ -103,14 +108,15 @@ class Handshake(object):
|
||||
|
||||
|
||||
def pyrit_handshakes(self):
|
||||
''' Returns list of BSSID,ESSID tuples if pyrit identifies a handshake'''
|
||||
return Pyrit.bssid_essid_with_handshakes(self.capfile, bssid=self.bssid, essid=self.essid)
|
||||
'''Returns list[tuple] of BSSID & ESSID pairs.'''
|
||||
return Pyrit.bssid_essid_with_handshakes(
|
||||
self.capfile, bssid=self.bssid, essid=self.essid)
|
||||
|
||||
|
||||
def aircrack_handshakes(self):
|
||||
'''Returns tuple (BSSID,None) if aircrack thinks self.capfile contains a handshake / can be cracked'''
|
||||
if not self.bssid:
|
||||
return [] # Aircrack requires BSSID
|
||||
return [] # Aircrack requires BSSID
|
||||
|
||||
command = 'echo "" | aircrack-ng -a 2 -w - -b %s "%s"' % (self.bssid, self.capfile)
|
||||
(stdout, stderr) = Process.call(command)
|
||||
@@ -125,9 +131,15 @@ class Handshake(object):
|
||||
'''Prints analysis of handshake capfile'''
|
||||
self.divine_bssid_and_essid()
|
||||
|
||||
Handshake.print_pairs(self.tshark_handshakes(), self.capfile, 'tshark')
|
||||
Handshake.print_pairs(self.pyrit_handshakes(), self.capfile, 'pyrit')
|
||||
Handshake.print_pairs(self.cowpatty_handshakes(), self.capfile, 'cowpatty')
|
||||
if Tshark.exists():
|
||||
Handshake.print_pairs(self.tshark_handshakes(), self.capfile, 'tshark')
|
||||
|
||||
if Pyrit.exists():
|
||||
Handshake.print_pairs(self.pyrit_handshakes(), self.capfile, 'pyrit')
|
||||
|
||||
if Process.exists('cowpatty'):
|
||||
Handshake.print_pairs(self.cowpatty_handshakes(), self.capfile, 'cowpatty')
|
||||
|
||||
Handshake.print_pairs(self.aircrack_handshakes(), self.capfile, 'aircrack')
|
||||
|
||||
|
||||
@@ -171,7 +183,7 @@ class Handshake(object):
|
||||
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}' % (tool_str))
|
||||
return
|
||||
|
||||
for (bssid, essid) in pairs:
|
||||
@@ -208,24 +220,27 @@ class Handshake(object):
|
||||
hs.analyze()
|
||||
Color.pl('')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('With BSSID & ESSID specified:')
|
||||
hs = Handshake('./tests/files/handshake_has_1234.cap', bssid='18:d6:c7:6d:6b:18', essid='YZWifi')
|
||||
hs.analyze()
|
||||
print("has_hanshake() =", hs.has_handshake())
|
||||
print('has_hanshake() =', hs.has_handshake())
|
||||
|
||||
print('\nWith BSSID, but no ESSID specified:')
|
||||
hs = Handshake('./tests/files/handshake_has_1234.cap', bssid='18:d6:c7:6d:6b:18')
|
||||
hs.analyze()
|
||||
print("has_hanshake() =", hs.has_handshake())
|
||||
print('has_hanshake() =', hs.has_handshake())
|
||||
|
||||
print('\nWith ESSID, but no BSSID specified:')
|
||||
hs = Handshake('./tests/files/handshake_has_1234.cap', essid='YZWifi')
|
||||
hs.analyze()
|
||||
print("has_hanshake() =", hs.has_handshake())
|
||||
print('has_hanshake() =', hs.has_handshake())
|
||||
|
||||
print('\nWith neither BSSID nor ESSID specified:')
|
||||
hs = Handshake('./tests/files/handshake_has_1234.cap')
|
||||
hs.analyze()
|
||||
print("has_hanshake() =", hs.has_handshake())
|
||||
|
||||
try:
|
||||
hs.analyze()
|
||||
print('has_hanshake() =', hs.has_handshake())
|
||||
except Exception as e:
|
||||
Color.pl('{O}Error during Handshake.analyze(): {R}%s{W}' % e)
|
||||
|
||||
@@ -11,16 +11,16 @@ class CrackResult(object):
|
||||
''' Abstract class containing results from a crack session '''
|
||||
|
||||
# File to save cracks to, in PWD
|
||||
cracked_file = "cracked.txt"
|
||||
cracked_file = 'cracked.txt'
|
||||
|
||||
def __init__(self):
|
||||
self.date = int(time.time())
|
||||
|
||||
def dump(self):
|
||||
raise Exception("Unimplemented method: dump()")
|
||||
raise Exception('Unimplemented method: dump()')
|
||||
|
||||
def to_dict(self):
|
||||
raise Exception("Unimplemented method: to_dict()")
|
||||
raise Exception('Unimplemented method: to_dict()')
|
||||
|
||||
def save(self):
|
||||
''' Adds this crack result to the cracked file and saves it. '''
|
||||
@@ -63,7 +63,7 @@ class CrackResult(object):
|
||||
@classmethod
|
||||
def load_all(cls):
|
||||
if not os.path.exists(cls.cracked_file): return []
|
||||
with open(cls.cracked_file, "r") as json_file:
|
||||
with open(cls.cracked_file, 'r') as json_file:
|
||||
json = loads(json_file.read())
|
||||
return json
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import re
|
||||
|
||||
class Target(object):
|
||||
'''
|
||||
Holds details for a "Target" aka Access Point (e.g. router).
|
||||
Holds details for a 'Target' aka Access Point (e.g. router).
|
||||
'''
|
||||
|
||||
def __init__(self, fields):
|
||||
@@ -56,7 +56,7 @@ class Target(object):
|
||||
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
|
||||
# Don't display '\x00...' for hidden ESSIDs
|
||||
self.essid = None # '(%s)' % self.bssid
|
||||
self.essid_known = False
|
||||
|
||||
@@ -70,26 +70,26 @@ class Target(object):
|
||||
|
||||
def validate(self):
|
||||
''' Checks that the target is valid. '''
|
||||
if self.channel == "-1":
|
||||
raise Exception("Ignoring target with Negative-One (-1) channel")
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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.
|
||||
Specifically formatted for the 'scanning' table view.
|
||||
'''
|
||||
|
||||
max_essid_len = 24
|
||||
essid = self.essid if self.essid_known else "(%s)" % self.bssid
|
||||
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] + '...'
|
||||
@@ -98,30 +98,30 @@ class Target(object):
|
||||
|
||||
if self.essid_known:
|
||||
# Known ESSID
|
||||
essid = Color.s("{C}%s" % essid)
|
||||
essid = Color.s('{C}%s' % essid)
|
||||
else:
|
||||
# Unknown ESSID
|
||||
essid = Color.s("{O}%s" % essid)
|
||||
essid = Color.s('{O}%s' % essid)
|
||||
|
||||
# Add a "*" if we decloaked the ESSID
|
||||
# Add a '*' if we decloaked the ESSID
|
||||
decloaked_char = '*' if self.decloaked else ' '
|
||||
essid += Color.s("{P}%s" % decloaked_char)
|
||||
essid += Color.s('{P}%s' % decloaked_char)
|
||||
|
||||
if show_bssid:
|
||||
bssid = Color.s('{O}%s ' % self.bssid)
|
||||
else:
|
||||
bssid = ''
|
||||
|
||||
channel_color = "{G}"
|
||||
channel_color = '{G}'
|
||||
if int(self.channel) > 14:
|
||||
channel_color = "{C}"
|
||||
channel = Color.s("%s%s" % (channel_color, str(self.channel).rjust(3)))
|
||||
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)
|
||||
encryption = Color.s('{G}%s' % encryption)
|
||||
elif 'WPA' in encryption:
|
||||
encryption = Color.s("{O}%s" % encryption)
|
||||
encryption = Color.s('{O}%s' % encryption)
|
||||
|
||||
power = '%sdb' % str(self.power).rjust(3)
|
||||
if self.power > 50:
|
||||
@@ -146,14 +146,14 @@ class Target(object):
|
||||
|
||||
result = '%s %s%s %s %s %s %s' % (
|
||||
essid, bssid, channel, encryption, power, wps, clients)
|
||||
result += Color.s("{W}")
|
||||
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")
|
||||
t.clients.append('asdf')
|
||||
t.clients.append('asdf')
|
||||
print(t.to_str())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user