Setting up Client, Target, and Airodump wrappers

Fixed bugs in Process and other related classes.
This commit is contained in:
derv82
2015-05-27 20:26:30 -07:00
parent 33dff208ed
commit 1f2ebc9914
6 changed files with 290 additions and 42 deletions

152
py/Airodump.py Normal file
View File

@@ -0,0 +1,152 @@
#!/usr/bin/python
from Process import Process
from Configuration import Configuration
from Target import Target
from Client import Client
import os
class Airodump(object):
''' Wrapper around airodump-ng program '''
def __init__(self, interface, channel=None, encryption=None, wps=False):
''' Constructor, sets things up '''
self.targets = []
self.interface = interface
self.channel = channel
self.encryption = encryption
self.wps = wps
def __enter__(self):
'''
Setting things up for this context.
Called at start of 'with Airodump(...) as x:'
'''
self.delete_airodump_temp_files()
self.csv_file_prefix = Configuration.temp() + "airodump";
# Build the command
command = [
'airodump-ng',
self.interface,
'-a', # Only show associated clients
'-w', self.csv_file_prefix # Output file prefix
]
if self.channel:
command.extend(['-c', str(self.channel)])
if self.encryption:
command.extend(['--enc', self.encryption])
if self.wps:
command.extend(['--wps'])
# Start the process
self.pid = Process(command, devnull=True)
return self
def __exit__(self, type, value, traceback):
'''
Tearing things down since the context is being exited.
Called after 'with Airodump(...)' goes out of scope.
'''
# Kill the process
self.pid.interrupt()
self.pid.kill()
# Delete temp files
self.delete_airodump_temp_files()
def delete_airodump_temp_files(self):
''' Deletes airodump* files in the temp directory '''
for fil in os.listdir(Configuration.temp()):
if fil.startswith('airodump'):
os.remove(Configuration.temp() + fil)
def get_targets(self, wpa_wep_only=True):
''' Parses airodump's CSV file, returns list of Targets '''
# Find the .CSV file
csv_filename = None
for fil in os.listdir(Configuration.temp()):
if fil.startswith('airodump') and fil.endswith('csv'):
# Found the file
csv_filename = Configuration.temp() + fil
break
if csv_filename == None or not os.path.exists(csv_filename):
# No file found
return self.targets
targets = []
# Parse the .CSV file
import csv
with open(csv_filename, 'rb') as csvopen:
csv_reader = csv.reader(csvopen, delimiter=',')
for row in csv_reader:
# Each "row" is a list of fields for a target/client
if len(row) == 0: continue
if row[0].strip() == 'BSSID':
# This is the "header" for the list of Targets
hit_clients = False
continue
elif row[0].strip() == 'Station MAC':
# This is the "header" for the list of Clients
hit_clients = True
continue
if hit_clients:
# The current row corresponds to a "Client" (computer)
client = Client(row)
if 'not associated' in client.bssid:
# Ignore unassociated clients
continue
# Add this client to the appropriate Target
for t in targets:
if t.bssid == client.bssid:
t.clients.append(client)
break
else:
# The current row corresponds to a "Target" (router)
target = Target(row)
if target.essid_len == 0:
# Ignore empty/blank ESSIDs
continue
if wpa_wep_only and 'WPA' not in target.encryption and 'WEP' not in target.encryption:
# Ignore non-WPA and non-WEP encrypted networks
continue
if self.encryption and self.encryption not in target.encryption:
# We're looking for a specific type of encryption
continue
targets.append(target)
# Sort by power
targets.sort(key=lambda x: x.power, reverse=True)
self.targets = targets
return self.targets
if __name__ == '__main__':
''' Example usage. wlan0mon should be in Monitor Mode '''
with Airodump('wlan0mon', channel=6) as airodump:
from time import sleep
sleep(7)
targets = airodump.get_targets()
for t in targets:
print 'Target>', t
Configuration.delete_temp()

View File

@@ -1,19 +0,0 @@
#!/usr/bin/python
class CapFile(object):
"""
Holds data about an access point's .cap file,
including filename, AP's ESSID & BSSID.
"""
def __init__(self, filename, ssid, bssid):
self.filename = filename
self.ssid = ssid
self.bssid = bssid
def __str__(self):
return self.filename
if __name__ == '__main__':
c = CapFile("cap-01.cap", "My Router", "AA:BB:CC:DD:EE:FF")
print c

View File

@@ -1,11 +1,41 @@
#!/usr/bin/python
class Client: class Client(object):
""" '''
Holds data for a Client (device connected to Access Point/Router) Holds details for a "Client" - a wireless device (e.g. computer)
""" that is associated with an Access Point (e.g. router)
'''
def __init__(self, bssid, station, power): def __init__(self, fields):
self.bssid = bssid '''
self.station = station Initializes & stores client info based on fields.
self.power = power Args:
Fields - List of strings
INDEX KEY
0 Station MAC (client's MAC address)
1 First time seen,
2 Last time seen,
3 Power,
4 # packets,
5 BSSID, (Access Point's MAC address)
6 Probed ESSIDs
'''
self.station = fields[0].strip()
self.power = int(fields[3].strip())
self.packets = int(fields[4].strip())
self.bssid = fields[5].strip()
def __str__(self):
''' String representation of a Client '''
result = ''
for (key,value) in self.__dict__.iteritems():
result += key + ': ' + str(value)
result += ','
return result
if __name__ == '__main__':
fields = '54:35:30:23:62:8E, 2015-05-27 19:43:47, 2015-05-27 19:43:47, -67, 2, (not associated) ,HOME-1102'.split(',')
c = Client(fields)
print c

View File

@@ -5,9 +5,10 @@ import os
class Configuration(object): class Configuration(object):
''' Stores configuration variables for Wifite. ''' ''' Stores configuration variables for Wifite. '''
temp_dir = None
def __init__(self): def __init__(self):
''' Sets up default initial configuration values ''' ''' Sets up default initial configuration values '''
self.temp_dir = None # Temporary directory
self.version = 2.00 # Program version self.version = 2.00 # Program version
self.tx_power = 0 # Wifi transmit power (0 is default) self.tx_power = 0 # Wifi transmit power (0 is default)
@@ -64,13 +65,15 @@ class Configuration(object):
if args.wordlist: self.wordlist = args.wordlist if args.wordlist: self.wordlist = args.wordlist
def temp(self): @staticmethod
def temp():
''' Creates and/or returns the temporary directory ''' ''' Creates and/or returns the temporary directory '''
if self.temp_dir == None: if Configuration.temp_dir == None:
self.temp_dir = self.create_temp() Configuration.temp_dir = Configuration.create_temp()
return self.temp_dir return Configuration.temp_dir
def create_temp(self): @staticmethod
def create_temp():
''' Creates and returns a temporary directory ''' ''' Creates and returns a temporary directory '''
from tempfile import mkdtemp from tempfile import mkdtemp
tmp = mkdtemp(prefix='wifite') tmp = mkdtemp(prefix='wifite')
@@ -78,13 +81,14 @@ class Configuration(object):
tmp += os.sep tmp += os.sep
return tmp return tmp
def delete_temp(self): @staticmethod
def delete_temp():
''' Remove temp files and folder ''' ''' Remove temp files and folder '''
if self.temp_dir == None: return if Configuration.temp_dir == None: return
if os.path.exists(self.temp_dir): if os.path.exists(Configuration.temp_dir):
for f in os.listdir(self.temp_dir): for f in os.listdir(Configuration.temp_dir):
os.remove(self.temp_dir + f) os.remove(Configuration.temp_dir + f)
os.rmdir(self.temp_dir) os.rmdir(Configuration.temp_dir)
def exit_gracefully(self, code=0): def exit_gracefully(self, code=0):

View File

@@ -34,15 +34,20 @@ class Process(object):
return True return True
def __init__(self, command): def __init__(self, command, devnull=False):
''' Starts executing command ''' ''' Starts executing command '''
if type(command) == str: if type(command) == str:
# Commands have to be a list # Commands have to be a list
command = command.split(' ') command = command.split(' ')
self.command = command
self.out = None self.out = None
self.err = None self.err = None
self.pid = Popen(command, stdout=PIPE, stderr=PIPE) if devnull:
sout = Process.devnull()
serr = Process.devnull()
else:
sout = PIPE
serr = PIPE
self.pid = Popen(command, stdout=sout, stderr=serr)
def stdout(self): def stdout(self):
''' Waits for process to finish, returns stdout output ''' ''' Waits for process to finish, returns stdout output '''

76
py/Target.py Normal file
View File

@@ -0,0 +1,76 @@
#!/usr/bin/python
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_len = int(fields[12].strip())
self.essid = fields[13].strip()
if self.essid == '\\x00' * self.essid_len:
# Don't display "\x00..." for hidden ESSIDs
self.essid = '(hidden, length: %s)' % self.essid_len
self.clients = []
def __str__(self):
''' String representation of this Target '''
result = ''
for (key,value) in self.__dict__.iteritems():
if key == 'clients': continue
result += key + ': ' + str(value)
result += ', '
for client in self.clients:
result += 'client: %s' % client.station
result += ','
if result.endswith(', '):
result = result[:-2]
return result
if __name__ == '__main__':
fields = '00:AC:E0:71:74:E0, 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-74E2, '.split(',')
t = Target(fields)
print t