nexmon – Rev 1

Subversion Repositories:
Rev:
#!/usr/bin/python
#airodump parsing lib
#returns in an array of client and Ap information
#part of the airdrop-ng project
from sys import exit as Exit
class airDumpParse:
        def parser(self,file):
                """
                One Function to call to parse a file and return the information
                """
                fileOpenResults = self.airDumpOpen(file)
                parsedResults   = self.airDumpParse(fileOpenResults)
                capr            = self.clientApChannelRelationship(parsedResults)
                rtrnList        = [capr,parsedResults]
                return rtrnList
                
        def airDumpOpen(self,file):
                """
                Takes one argument (the input file) and opens it for reading
                Returns a list full of data
                """
                try:
                        openedFile = open(file, "r")
                except TypeError:
                        print "Missing Airodump-ng file"
                        Exit(1)
                except IOError:
                        print "Error Airodump File",file,"does not exist"
                        Exit(1)
                data = openedFile.xreadlines()
                cleanedData = []
                for line in data:
                        cleanedData.append(line.rstrip())
                openedFile.close()
                return cleanedData
        
        def airDumpParse(self,cleanedDump):
                """
                Function takes parsed dump file list and does some more cleaning.
                Returns a list of 2 dictionaries (Clients and APs)
                """
                try: #some very basic error handeling to make sure they are loading up the correct file
                        try:
                                apStart = cleanedDump.index('BSSID, First time seen, Last time seen, Channel, Speed, Privacy, Power, # beacons, # data, LAN IP, ESSID')
                        except Exception:
                                apStart = cleanedDump.index('BSSID, First time seen, Last time seen, channel, Speed, Privacy, Cipher, Authentication, Power, # beacons, # IV, LAN IP, ID-length, ESSID, Key')
                        del cleanedDump[apStart] #remove the first line of text with the headings
                        try:
                                stationStart = cleanedDump.index('Station MAC, First time seen, Last time seen, Power, # packets, BSSID, Probed ESSIDs')
                        except Exception:
                                stationStart = cleanedDump.index('Station MAC, First time seen, Last time seen, Power, # packets, BSSID, ESSID')
                except Exception:
                        print "You Seem to have provided an improper input file please make sure you are loading an airodump txt file and not a pcap"
                        Exit(1)
        
                del cleanedDump[stationStart] #Remove the heading line
                clientList = cleanedDump[stationStart:] #Splits all client data into its own list
                del cleanedDump[stationStart:] #The remaining list is all of the AP information
                apDict = self.apTag(cleanedDump)
                clientDict = self.clientTag(clientList)
                resultDicts = [clientDict,apDict] #Put both dictionaries into a list
                return resultDicts
        
        def apTag(self,devices):
                """
                Create a ap dictionary with tags of the data type on an incoming list
                """
                dict = {}
                for entry in devices:
                        ap = {}
                        string_list = entry.split(',')
                        #sorry for the clusterfuck but i swear it all makse sense this is builiding a dic from our list so we dont have to do postion calls later
                        len(string_list)
                        if len(string_list) == 15:
                                ap = {"bssid":string_list[0].replace(' ',''),
                                        "fts":string_list[1],
                                        "lts":string_list[2],
                                        "channel":string_list[3].replace(' ',''),
                                        "speed":string_list[4],
                                        "privacy":string_list[5].replace(' ',''),
                                        "cipher":string_list[6],
                                        "auth":string_list[7],
                                        "power":string_list[8],
                                        "beacons":string_list[9],
                                        "iv":string_list[10],
                                        "ip":string_list[11],
                                        "id":string_list[12],
                                        "essid":string_list[13][1:],
                                        "key":string_list[14]}
                        elif len(string_list) == 11:
                                ap = {"bssid":string_list[0].replace(' ',''),
                                        "fts":string_list[1],
                                        "lts":string_list[2],
                                        "channel":string_list[3].replace(' ',''),
                                        "speed":string_list[4],
                                        "privacy":string_list[5].replace(' ',''),
                                        "power":string_list[6],
                                        "beacons":string_list[7],
                                        "data":string_list[8],
                                        "ip":string_list[9],
                                        "essid":string_list[10][1:]}
                        if len(ap) != 0:
                                dict[string_list[0]] = ap
                return dict
        
        def clientTag(self,devices):
                """
                Create a client dictionary with tags of the data type on an incoming list
                """
                dict = {}
                for entry in devices:
                        client = {}
                        string_list = entry.split(',')
                        if len(string_list) >= 7:
                                client = {"station":string_list[0].replace(' ',''),
                                        "fts":string_list[1],
                                        "lts":string_list[2],
                                        "power":string_list[3],
                                        "packets":string_list[4],
                                        "bssid":string_list[5].replace(' ',''),
                                        "probe":string_list[6:][0:]}
                        if len(client) != 0:
                                dict[string_list[0]] = client
                return dict
        
        def clientApChannelRelationship(self,data):
                """
                parse the dic for the relationships of client to ap
                """
                clients = data[0]
                AP = data[1]
                NA = [] #create a var to keep the not associdated clients
                NAP = [] #create a var to keep track of associated clients to AP's we cant see
                apCount = {} #count number of Aps dict is faster the list stored as BSSID:number of essids
                apClient = {} #dict that stores bssid and clients as a nested list
                for key in (clients):
                        mac = clients[key] #mac is the MAC address of the client
                        if mac["bssid"] != ' (notassociated) ': #one line of of our dictionary of clients
                                if AP.has_key(mac["bssid"]): # if it is check to see its an AP we can see and have info on
                                        if apClient.has_key(mac["bssid"]): 
                                                apClient[mac["bssid"]].extend([key]) #if key exists append new client
                                        else: 
                                                apClient[mac["bssid"]] = [key] #create new key and append the client
                                else: NAP.append(key) # stores the clients that are talking to an access point we cant see
                        else: NA.append(key) #stores the lines of the not assocated AP's in a list
                return apClient