def find_mac(mac_addr): mac_data = MacLookup() mac_data.update_vendors() try: return mac_data.lookup(mac_addr) except KeyError: return "Unknown"
def extract_devices(self): """ Extract devices from the captured packets. Returns: pandas.DataFrame: Device parameters extracted from the captured packets. """ devs = pd.DataFrame( columns=["MAC", "Vendor", "Times", "Frame Subtypes"]) if (self.packets.empty): return devs macs = self.packets["MAC"].unique() ML = MacLookup() ML.update_vendors() for mac in macs: frames = self.packets.loc[self.packets["MAC"] == mac] if (mac[1] == "2" or mac[1] == "6" or mac[1] == "a" or mac[1] == "e" or mac[1] == "A" or mac[1] == "E"): vendor = "Randomized" else: try: vendor = ML.lookup(mac) except KeyError: vendor = "Unknown" mins = np.unique( np.array([(60 * tm.hour + tm.minute) for tm in frames["Time"]])) subtypes = frames["Frame Subtype"].unique() devs.loc[len(devs)] = [mac, vendor, mins, subtypes] return devs
def get_manufacturer(mac): search_manufacturer = MacLookup() try: manufacture = search_manufacturer.lookup(mac) except: manufacture = "Unknown" return manufacture
def get_hosts(): scanner = nmap.PortScanner() print("starting scan") start = time.time() scanner.scan("172.16.80.0/23", "22", arguments="-n") print("completed scan", round(time.time() - start, 2)) addresses = scanner.all_hosts() vendor_lookup = MacLookup() local_interface_map = get_local_ipv4_interface_map() hosts = [] print("getting mac address of network cards") start = time.time() for address in addresses: mac = get_mac_address(ip=address) if not mac and address in local_interface_map: mac = get_mac_address(interface=local_interface_map[address]) try: vendor = vendor_lookup.lookup(mac) if mac else None except KeyError: print("error processing mac for", address) hosts.append({"ip": address, "mac": mac, "vendor": vendor}) print("mac address acquired", round(time.time() - start, 2)) return hosts
class NmapMacScan(NmapBasic): def __init__(self, networks, unknown="unknown"): super().__init__(networks) self.unknown = unknown self.mac_search = MacLookup() def update_mac(self, ip): """ Update Mac info :param ip: IP address (ie: 192.168.1.1) :return: True if MAC is found, False otherwise """ mac = getmac.get_mac_address(ip=ip) if mac is None: return False else: self.scan_results[ip]["macaddress"] = mac return True def update_vendor(self, ip): """ Update MAC vendor if Mac is found :param ip: IP address (ie: 192.168.1.1) :return: None """ logging.debug("Updating MAC table") self.mac_search.update_vendors() vendor_fetch = self.mac_search.lookup( self.scan_results[ip]["macaddress"]) self.scan_results[ip]["vendor"] = vendor_fetch def correct_missing_mac(self, host): """ Correct description if macaddress is not found :param host: host key in scan_results :return: None """ if not self.scan_results[host]["macaddress"]: self.scan_results[host]["description"] = self.unknown self.scan_results[host].pop("macaddress") def scan(self): """ Scan defined networks and conditionally check for mac vendor :return: scan_results = list() """ for host, v in self.scan_results.items(): if v.get("macaddress") or self.update_mac(host): self.update_vendor(ip=host) self.correct_missing_mac(host) return self.scan_results def run(self): return self.scan()
def create_mac_table(key, lst, lookup=False): td = [[key]] if lookup: td[0].append("vendor") m = MacLookup() for i in lst: try: if lookup: td.append([i, m.lookup(i)]) else: td.append([i]) except Exception: td.append([i, ""]) return td
class MacAddresses: def __init__(self): self.__mac_lookup = MacLookup() self.__mac_lookup.load_vendors() self.__mac_addresses = self.__fetch_mac_addresses() def __call__(self): return self.__mac_addresses # MACアドレスの取得 def __fetch_mac_addresses(self): mac_addresses = {} for name, interface in ifcfg.interfaces().items(): address = interface['ether'] mac_addresses[name] = { 'address': address, 'vendor': self.__lookup_org_by_mac_address(address) if address is not None else None, } return mac_addresses # MACアドレスからベンダを照会する # mac_vendor_lookupが存在しないMACアドレスを投げると例外吐いて死にやがるのでこういう邪悪なコードになりました def __lookup_org_by_mac_address(self, mac_address): oui = MacAddresses.translate_oui(mac_address) return self.__mac_lookup.lookup( mac_address ) if oui in self.__mac_lookup.async_lookup.prefixes else None # MACアドレスからOUIを抽出して返す @staticmethod def translate_oui(mac_address): oui = mac_address.replace(':', '').replace('-', '').upper() try: int(oui, 16) except ValueError: raise InvalidMacAddressException( '{} contains unexpected character'.format(mac_address)) if len(oui) > 12: raise InvalidMacAddressException( '{} is not a valid MAC address (too long)'.format(mac_address)) if type(oui) == str: oui = oui.encode('utf8') return oui[:6]
class PiHoleSummary: __mac_vendors = None def __init__(self, config): self.__ph = pihole.PiHole(config['pi-hole']['ip']) self.__ph.authenticate(config['pi-hole']['pass']) self.__ph.refresh() self.__mac_vendors = MacLookup() self.__mac_vendors.loop.run_until_complete(self.__mac_vendors.async_lookup.load_vendors()) def get_stats(self): return { "status": self.__ph.status, "blocked_ads_percentage": float(self.__ph.ads_percentage), "total_blocked": int(self.__ph.blocked.replace(',', '')), "total_queries": int(self.__ph.total_queries.replace(',', '')), "top_devices": self.__get_device_manufacturers(self.__ph.top_devices) } def __get_device_manufacturers(self, devices): vendors = [] for d in devices.keys(): ip_addr = d.split('|')[-1] mac_addr = get_mac_address(ip=ip_addr) v = ip_addr try: v = self.__mac_vendors.lookup(mac_addr)[0:8] except Exception as e: pass vendors.append(v) return vendors
def create_workbook(): """ Create an Excel workbook to store values retrieved from switches """ #Setup logfile and naming based on date/time. Create directory if needed. current_time = dt.datetime.now().strftime("%Y-%m-%d-%H-%M-%S") log_dir = "logs" pathlib.Path(log_dir).mkdir(exist_ok=True) filename = str("DISCOVERY-LOG") + "-" + current_time + ".txt" log_filepath = log_dir + "/" + filename # Create the log file logfile = open(log_filepath, "w") wb = openpyxl.Workbook() groupname = "MixGrouping1" #TODO: Replace with function that takes list of location codes. wb_name = "NACFACTS-" + groupname + "-" + current_time + ".xlsx" #Define the regex keywords that we want to look for in interface descriptions desc_keywords = "(ASR|ENCS|UPLINK|CIRCUIT|ISP|SWITCH|TRUNK|ESXI|VMWARE)" #Create sheets and column headers facts_ws = wb.create_sheet("Facts") facts_ws.append([ 'Switch Hostname', 'Vendor', 'Model', 'OS Version', 'Serial Number', 'Uptime' ]) interfaces_ws = wb.create_sheet("Interfaces") interfaces_ws.append([ 'Switch', 'Interface name', 'Description', 'Admin Status', 'Oper Status', 'Speed' ]) mactablevendor_ws = wb.create_sheet("Mac Table Vendors") mactablevendor_ws.append(['Switch', 'Interface', 'MACaddr', 'Vendor OUI']) lldpneighbor_ws = wb.create_sheet("LLDP Neighbors") lldpneighbor_ws.append([ 'Local Switch', 'Local Port', 'Remote System ID', 'Remote System Name', 'Remote System Description', 'Remote Port ID', 'Remote Port Description', 'Remote Capability', 'Remote Vendor' ]) multimacports_ws = wb.create_sheet("Multi Mac Ports") multimacports_ws.append(['Switch', 'Interface', 'Count', 'Vendor MACs']) portexclusions_ws = wb.create_sheet("Port Exclusion Recommendations") portexclusions_ws.append( ['Switch', 'Interface', 'Reason', 'Port Description']) devicefailures_ws = wb.create_sheet("Failed Devices") devicefailures_ws.append(['Switch', 'Hostname', 'Error']) """ Initialize Nornir settings and set the right inventory targets and filters """ nr = InitNornir(config_file="config.yaml", core={"raise_on_error": False}) #target_devices = nr.filter(hostname='10.83.8.163') target_devices = nr.filter(site='herndon-dev') #target_devices = nr.filter(tag='mix') #Initialize nested dictionary for tracking recomended ports and reasoning to exclude from NAC. portexclusions = defaultdict( lambda: defaultdict(lambda: defaultdict(list))) #portexclusions = {'SwitchName': {'Gi1/1:' {'description': 'trunk to mdf', macvendor: 'VMWare', Reasoning: ['Port is trunk', 'multimacs'] }} print('Collecting information from the following Nornir inventory hosts:', target_devices.inventory.hosts.keys()) logfile.write( 'Collecting information from the following Nornir inventory hosts:' + str(target_devices.inventory.hosts.keys()) + '\n') logfile.write('Interesting Interface keywords: ' + desc_keywords + '\n') print("Grabbing Data With Nornir/Napalm - Start Clock\n") starttime = time.perf_counter() napalm_results = target_devices.run( task=napalm_get, getters=[ 'mac_address_table', 'facts', 'lldp_neighbors_detail', 'interfaces' ], name="Get Switch info: Facts, MAC Table, LLDP, and Interfaces") stoptime = time.perf_counter() print( f"Done Grabbing Data\n Execution took: {stoptime - starttime:0.4f} seconds" ) for host, task_results in napalm_results.items(): #Check for switches that failed and continue. Nornir automatically removes failed devices from future tasks. if task_results.failed: print(' ######', '\n!Failed Host in task_results:>', host, 'will be removed from future tasks!\n', '######', '\n') logfile.write('!Failed Host in task_results:> ' + host + ' will be removed from future tasks!\n') continue print("Start processing Host - ", str(host), '\n') logfile.write('Start processing Host - ' + str(host) + '\n') facts_result = task_results[0].result['facts'] #print("Facts_Results are:> (task_results[0].result['facts'] >>\n)", facts_result) lldp_result = task_results[0].result['lldp_neighbors_detail'] #print("lldp_result are:> (task_results[0].result['lldp_neighbors_detail'] >>\n)", lldp_result) mactable_result = task_results[0].result['mac_address_table'] #print("mactable_result are:> (task_results[0].result['mac_address_table'] >>\n)", mactable_result) interfaces_result = task_results[0].result['interfaces'] #print("interfaces_result are:> (task_results[0].result['interfaces'] >>\n)", interfaces_result) """PROCESS MAC TABLE RESULTS - Lookup MAC OUI Vendors and Determine Ports with multiple MACs assigned.""" macQ = MacLookup() #loop through each switch in the Nornir Task Result object print("Start processing Host - Mac_Results:", str(host), '\n') logfile.write("Start processing Host - Mac_Results: " + str(host) + '\n') #unnecessary since captured above? if task_results.failed: print(' ######', '\n!Failed Host in task_results (MACTABLE):>', host, 'will be removed from future tasks!\n', '######', '\n') continue #Store the actual serialized mac table dict for the current switch vendor_mactable = defaultdict(list) interfaces = defaultdict(list) multimacinterfaces = defaultdict(dict) #Loop through each Host's MAC Table and Create dictionary of interfaces and the vendor MACs that are attached. for entry in mactable_result: if not entry[ 'interface']: #skip mac address not assigned to interfaces continue try: vendor = macQ.lookup(entry['mac']) except: vendor = "Unknown" interface_value = entry['interface'] vendor_value = vendor mac_value = entry['mac'] #Store relevant values for worksheet row and append to sheet. line = [host, interface_value, mac_value, vendor_value] mactablevendor_ws.append(line) #Append Vendor lookup results to vendor_mactable so we can use them for port exclusion recommendations. vendor_mactable[entry['interface']].append(vendor_value) #build dictionary of interfaces containing lists of vendors and identify ports with multiple MACs. for iface, value in vendor_mactable.items(): #print(iface, value) if len(value) > 1: #print(iface, '>', value) interfaces[iface].extend(value) line = [ host, iface, len(interfaces[iface]), str(interfaces[iface]) ] multimacports_ws.append(line) #Append to portexlcusions dictionary portexclusions[host][iface]['reason'].append('multimac') #print('vendor mactable\n\n', vendor_mactable) #print('interfact dict \n\n', interfaces) print("End Processing Host - Mac_Results: " + str(host) + "\n") logfile.write("End Processing Host - Mac_Results: " + str(host) + "\n") """ Get Facts from all inventory targets using nornir napalm task=get_facts and output results to facts_ws """ print("Start processing Host - Get Facts:", str(host), '\n') logfile.write("Start processing Host - Get Facts: " + str(host) + '\n') hostname_result = facts_result['hostname'] vendor_result = facts_result['vendor'] model_result = facts_result['model'] version_result = facts_result['os_version'] serial_result = facts_result['serial_number'] uptime_result = facts_result['uptime'] #HP Devices will return a list of interfaces with get_facts if facts_result['interface_list']: interfacelist_result = facts_result['interface_list'] line = [ host, vendor_result, model_result, version_result, serial_result, uptime_result ] facts_ws.append(line) print("End Processing Host - Get Facts: " + str(host) + "\n") logfile.write("End Processing Host - Get Facts: " + str(host) + "\n") """PROCESS LLDP NEIGHBOR DETAIL RESULTS - .""" print("Start processing Host - Get LLDP Neighbors:", str(host), '\n') logfile.write("Start processing Host - Get LLDP Neighbors: " + str(host) + '\n') for interface in lldp_result: #print(lldp_detail) remotesysid = lldp_result[interface][0]['remote_chassis_id'] remotesysname = lldp_result[interface][0]['remote_system_name'] remotesysdescription = lldp_result[interface][0][ 'remote_system_description'] remoteportid = lldp_result[interface][0]['remote_port'] remoteportdesc = lldp_result[interface][0][ 'remote_port_description'] remotecapability = lldp_result[interface][0]['remote_system_capab'] try: remotevendor = macQ.lookup(remotesystemid) except: remotevendor = "Unknown" line = [ host, interface, remotesysid, remotesysname, remotesysdescription, remoteportid, remoteportdesc, str(remotecapability), remotevendor ] lldpneighbor_ws.append(line) if ('router' in remotecapability) or ('bridge' in remotecapability): #TODO: generalize for all interfaces and move to function if re.search('TenGigabit', str(interface), re.IGNORECASE): digits = re.search('([0-9]*\/?[0-9]*\/?[0-9]*$)', str(interface)) interface = 'Te' + digits.group() elif re.search('TwoGigabit', str(interface), re.IGNORECASE): digits = re.search('([0-9]*\/?[0-9]*\/?[0-9]*$)', str(interface)) interface = 'Tw' + digits.group() elif re.search('^Gigabit', str(interface), re.IGNORECASE): digits = re.search('([0-9]*\/?[0-9]*\/?[0-9]*$)', str(interface)) interface = 'Gi' + digits.group() portexclusions[host][interface]['reason'].append( 'LLDP Neighbor' + str(remotecapability)) #print(host, interface, remotecapability) print("End Processing Host - Get LLDP Neighors: " + str(host) + "\n") logfile.write("End Processing Host - Get LLDP Neighors: " + str(host) + "\n") """ Get Interfaces, check descriptions for keywords and append to port exclusions. """ print("Start processing Host - Get Interfaces:", str(host), '\n') logfile.write("Start processing Host - Get Interfaces: " + str(host) + '\n') for interface in interfaces_result: #if 'C9500-16X' in host: interface_id = interface adminstatus = interfaces_result[interface]['is_enabled'] operstatus = interfaces_result[interface]['is_up'] description = interfaces_result[interface]['description'] speed = interfaces_result[interface]['speed'] line = [ host, interface_id, description, adminstatus, operstatus, speed ] interfaces_ws.append(line) #Check for Exclusion keywords and add interfaces to portexclusion dictionary then append to portexlusion_ws. #TODO: Replace search literals with variable at top for quicker modification. keyword = re.search(desc_keywords, str(description), re.IGNORECASE) if keyword: #Normalize Interface names because different napalm getters return full interfaces name and some return shortened names which result in multiple dictionary keys being created. #TODO: generalize for all interfaces and move to function if re.search('TenGigabit', str(interface), re.IGNORECASE): digits = re.search('([0-9]*\/?[0-9]*\/?[0-9]*$)', str(interface)) interface = 'Te' + digits.group() elif re.search('TwoGigabit', str(interface), re.IGNORECASE): digits = re.search('([0-9]*\/?[0-9]*\/?[0-9]*$)', str(interface)) interface = 'Tw' + digits.group() elif re.search('^Gigabit', str(interface), re.IGNORECASE): digits = re.search('([0-9]*\/?[0-9]*\/?[0-9]*$)', str(interface)) interface = 'Gi' + digits.group() reasondescript = 'Description contains: ' + keyword.group() portexclusions[host][interface]['reason'].append( reasondescript) portexclusions[host][interface]['description'] = str( description) print("End processing Host - Get Interfaces:", str(host), '\n') logfile.write("End processing Host - Get Interfaces: " + str(host) + '\n') """ Export all entries from portexlusions dictionary to portexclusions_ws so that port exclusion recommendations show up in the workbook. """ for host, value in portexclusions.items(): print("Start processing Host - Port Exclusions:", str(host), '\n') logfile.write("Start processing Host - Port Exclusions: " + str(host) + '\n') for interface in portexclusions[host]: line = [ host, interface, str(portexclusions[host][interface]['reason']), str(portexclusions[host][interface]['description']) ] portexclusions_ws.append(line) print("End processing Host - Port Exclusions:", str(host), '\n') logfile.write("End processing Host - Port Exclusions: " + str(host) + '\n') #check if there are any failed hosts and save failed switches to worksheet if nr.data.failed_hosts: print( "The following switches failed during a task and were not added to the workbook:", nr.data.failed_hosts, '\n') logfile.write( "The following switches failed during a task and were not added to the workbook: " + str(nr.data.failed_hosts) + '\n') for host in nr.data.failed_hosts: error = napalm_results[host][0].exception #print(target_devices.inventory.hosts[host].keys()) hostname = target_devices.inventory.get_hosts_dict( )[host]['hostname'] line = [host, hostname, str(error)] devicefailures_ws.append(line) wb.remove(wb["Sheet"]) #catch potential save errors on workbook. try: wb.save(wb_name) print("Workbook -", wb_name, "- Created") logfile.write("Workbook - " + wb_name + " Created\n") except Exception as e: print( "\n######", e, "######\nFailed to Save workbook, please close it if open and ensure you have access to save location" ) logfile.close()
def create_workbook(): """ Create an Excel workbook to store values retrieved from switches """ wb = openpyxl.Workbook() groupname = "Grouping1" #TODO: Replace with function that takes list of location codes. wb_name = "NACFACTS -" + groupname + ".xlsx" #Create sheets and column headers facts_ws = wb.create_sheet("Facts") facts_ws.append([ 'Switch Hostname', 'Vendor', 'Model', 'OS Version', 'Serial Number', 'Uptime' ]) interfaces_ws = wb.create_sheet("Interfaces") interfaces_ws.append([ 'Switch', 'Interface name', 'Description', 'Admin Status', 'Oper Status', 'Speed' ]) mactablevendor_ws = wb.create_sheet("Mac Table Vendors") mactablevendor_ws.append(['Switch', 'Interface', 'MACaddr', 'Vendor OUI']) lldpneighbor_ws = wb.create_sheet("LLDP Neighbors") lldpneighbor_ws.append([ 'Local Switch', 'Local Port', 'Remote System ID', 'Remote System Name', 'Remote System Description', 'Remote Port ID', 'Remote Port Description', 'Remote Capability', 'Remote Vendor' ]) multimacports_ws = wb.create_sheet("Multi Mac Ports") multimacports_ws.append(['Switch', 'Interface', 'Count', 'Vendor MACs']) portexclusions_ws = wb.create_sheet("Port Exclusion Recommendations") portexclusions_ws.append( ['Switch', 'Interface', 'Reason', 'port description']) """ Initialize Nornir settings and set the right inventory targets and filters """ nr = InitNornir(config_file="config.yaml", core={"raise_on_error": False}) #accessHosts = nr.filter(hostname='10.83.8.163') accessHosts = nr.filter(site='herndon-dev') #accessHosts = nr.filter(type='network_device') #accessHosts = nr.filter(role='FIAB') #accessHosts = nr.filter(site='home') #Initialize nested dictionary for tracking recomended ports and reasoning to exclude from NAC. portexclusions = defaultdict( lambda: defaultdict(lambda: defaultdict(list))) #portexclusions = {'SwitchName': {'Gi1/1:' {'description': 'trunk to mdf', macvendor: 'VMWare', Reasoning: ['Port is trunk', 'multimacs'] }} """ Get Mac Table results from all inventory targets using nornir napalm task=get_mac_table, lookup Vendor MACOUI and store in mactablevendor_ws """ #mac_results = accessHosts.run(task=get_mac_table_napalm, name="Get MAC Table") #print('Print hosts before .run\n', nr.inventory) #print(len(accessHosts)) print('Collecting information from the following Nornir inventory hosts:', accessHosts.inventory.hosts.keys()) #try: mac_results = accessHosts.run(task=napalm_get, getters=['mac_address_table']) #except Exception as e: #print('ERROR!!!\n\n', e) macQ = MacLookup() #loop through each switch in the Nornir Task Result object for host, task_results in mac_results.items(): print("Start processing Host - Mac_Results:", str(host), '\n') #Check for switches that failed and pass. Nornir automatically removes failed devices from future tasks. #TODO: Log or print failures for further review. if task_results.failed: print(' ######', '\n!Failed Host in task_results:>', host, 'will be removed from future tasks!\n', '######', '\n') continue #Store the actual serialized mac table dict for the current switch mac_results_host = task_results[0].result vendor_mactable = defaultdict(list) interfaces = defaultdict(list) multimacinterfaces = defaultdict(dict) #Loop through each Host's MAC Table and Create dictionary of interfaces and the vendor MACs that are attached. for entry in mac_results_host['mac_address_table']: if not entry[ 'interface']: #skip mac address not assigned to interfaces continue try: vendor = macQ.lookup(entry['mac']) except: vendor = "Unknown" interface_value = entry['interface'] vendor_value = vendor mac_value = entry['mac'] #Store relevant values for worksheet row and append to sheet. line = [host, interface_value, mac_value, vendor_value] mactablevendor_ws.append(line) #Append Vendor lookup results to vendor_mactable so we can use them for port exclusion recommendations. vendor_mactable[entry['interface']].append(vendor_value) #build dictionary of interfaces containing lists of vendors and identify ports with multiple MACs. for iface, value in vendor_mactable.items(): #print(iface, value) if len(value) > 1: #print(iface, '>', value) interfaces[iface].extend(value) line = [ host, iface, len(interfaces[iface]), str(interfaces[iface]) ] #print(line) multimacports_ws.append(line) #Append to portexlcusions dictionary portexclusions[host][iface]['reason'].append('multimac') #print('vendor mactable\n\n', vendor_mactable) #print('interfact dict \n\n', interfaces) print("End Processing Host - Mac_Results: " + str(host) + "\n") #exit() """ Get Facts from all inventory targets using nornir napalm task=get_facts and output results to facts_ws """ facts = accessHosts.run(task=napalm_get, getters=["facts"]) #print('Check nornir inventory after potential failure > accesshosts keys:>', accessHosts.inventory.hosts.keys()) #Loop through each host's task results and store values to append lines to facts_ws #AggregatedResult (napalm_get): {'C9300-48-UXM-1': MultiResult: [Result: "napalm_get"], 'C9500-16X': MultiResult: [Result: "napalm_get"]} for host, task_results in facts.items(): print("Start processing Host - Get Facts:", str(host), '\n') facts_result = task_results[0].result vendor_result = facts_result['facts']['vendor'] model_result = facts_result['facts']['model'] version_result = facts_result['facts']['os_version'] serial_result = facts_result['facts']['serial_number'] uptime_result = facts_result['facts']['uptime'] line = [ host, vendor_result, model_result, version_result, serial_result, uptime_result ] facts_ws.append(line) print("End Processing Host - Get Facts: " + str(host) + "\n") """ get_lldp_neighbors for all invetnory targets using nornir napalm task=get_lldp_neighbors, perform mac vendoroui lookup on chassisid and output all results to lldpneighbors_ws """ lldpneighbors = accessHosts.run(task=napalm_get, getters=["lldp_neighbors_detail"]) for host, task_results in lldpneighbors.items(): print("Start processing Host - Get LLDP Neighbors:", str(host), '\n') #Store results from Nornir aggregated result object lldp_result = task_results[0].result #store actual result dicitonary from the Nornir result object. lldp_detail = lldp_result['lldp_neighbors_detail'] for interface in lldp_detail: #print(lldp_detail) remotesysid = lldp_detail[interface][0]['remote_chassis_id'] remotesysname = lldp_detail[interface][0]['remote_system_name'] remotesysdescription = lldp_detail[interface][0][ 'remote_system_description'] remoteportid = lldp_detail[interface][0]['remote_port'] remoteportdesc = lldp_detail[interface][0][ 'remote_port_description'] remotecapability = lldp_detail[interface][0]['remote_system_capab'] try: remotevendor = macQ.lookup(remotesystemid) except: remotevendor = "Unknown" line = [ host, interface, remotesysid, remotesysname, remotesysdescription, remoteportid, remoteportdesc, str(remotecapability), remotevendor ] #print(line) lldpneighbor_ws.append(line) if ('router' in remotecapability) or ('bridge' in remotecapability): #TODO: generalize for all interfaces and move to function if re.search('TenGigabit', str(interface), re.IGNORECASE): digits = re.search('([0-9]*\/?[0-9]*\/?[0-9]*$)', str(interface)) interface = 'Te' + digits.group() elif re.search('TwoGigabit', str(interface), re.IGNORECASE): digits = re.search('([0-9]*\/?[0-9]*\/?[0-9]*$)', str(interface)) interface = 'Tw' + digits.group() elif re.search('^Gigabit', str(interface), re.IGNORECASE): digits = re.search('([0-9]*\/?[0-9]*\/?[0-9]*$)', str(interface)) interface = 'Gi' + digits.group() portexclusions[host][interface]['reason'].append( 'LLDP Neighbor' + str(remotecapability)) #print(host, interface, remotecapability) print("End Processing Host - Get LLDP Neighors: " + str(host) + "\n") """ Get Interfaces, check descriptions for keywords and append to port exclusions. """ getinterfaces = accessHosts.run(task=napalm_get, getters=["interfaces"]) for host, task_results in getinterfaces.items(): print("Start processing Host - Get Interfaces:", str(host), '\n') interfaces_result = task_results[0].result interfaces_result = interfaces_result['interfaces'] for interface in interfaces_result: #if 'C9500-16X' in host: #print(interface_id) interface_id = interface adminstatus = interfaces_result[interface]['is_enabled'] operstatus = interfaces_result[interface]['is_up'] description = interfaces_result[interface]['description'] speed = interfaces_result[interface]['speed'] line = [ host, interface_id, description, adminstatus, operstatus, speed ] #print(line) interfaces_ws.append(line) #Check for Exclusion keywords and add interfaces to portexclusion dictionary then append to portexlusion_ws. #TODO: Replace search literals with variable at top for quicker modification. keyword = re.search( '(ASR|ENCS|UPLINK|CIRCUIT|ISP|SWITCH|TRUNK|ESXI|VMWARE)', str(description), re.IGNORECASE) if keyword: #Normalize Interface names because different napalm getters return full interfaces name and some return shortened names which result in multiple dictionary keys being created. #TODO: generalize for all interfaces and move to function if re.search('TenGigabit', str(interface), re.IGNORECASE): digits = re.search('([0-9]*\/?[0-9]*\/?[0-9]*$)', str(interface)) interface = 'Te' + digits.group() elif re.search('TwoGigabit', str(interface), re.IGNORECASE): digits = re.search('([0-9]*\/?[0-9]*\/?[0-9]*$)', str(interface)) interface = 'Tw' + digits.group() elif re.search('^Gigabit', str(interface), re.IGNORECASE): digits = re.search('([0-9]*\/?[0-9]*\/?[0-9]*$)', str(interface)) interface = 'Gi' + digits.group() reasondescript = 'Description contains: ' + keyword.group() portexclusions[host][interface]['reason'].append( reasondescript) portexclusions[host][interface]['description'] = str( description) print("End processing Host - Get Interfaces:", str(host), '\n') """ Export all entries from portexlusions dictionary to portexclusions_ws so that port exclusion recommendations show up in the workbook. """ for host, value in portexclusions.items(): print("Start processing Host - Port Exclusions:", str(host), '\n') #print(host) for interface in portexclusions[host]: #print(host, interface, portexclusions[host][interface]['reason'], portexclusions[host][interface]['description']) line = [ host, interface, str(portexclusions[host][interface]['reason']), str(portexclusions[host][interface]['description']) ] portexclusions_ws.append(line) print("End processing Host - Port Exclusions:", str(host), '\n') """ Get VLANs... in Napalm-automation:develop train, needed for identifying switchport mode trunk. """ #vlans = accessHosts.run(task=napalm_get, getters=['vlan'], name="Get VLANs") #print_result(vlans) if nr.data.failed_hosts: print( "The following switches failed during a task and were not added to the workbook:", nr.data.failed_hosts) #TODO: save failed switches to worksheet wb.remove(wb["Sheet"]) #catch potential save errors on workbook. try: wb.save(wb_name) print("\nWorkbook Created") except Exception as e: print( "\n######", e, "######\nFailed to Save workbook, please close it if open and ensure you have access to save location" )
def findVendor(macAdress): mac = MacLookup() try: return mac.lookup(macAdress) except: pass
network = ipaddress.ip_network("%s/%s" % (addr, netmask), strict=False) start = network.network_address + 1 end = network.broadcast_address maclookup = MacLookup() nmap = nmap.PortScanner() #for ipint in range(int(start), int(end)): for ipint in range(int(start), int(start) + 1): ip = ipaddress.IPv4Address(ipint) ipstr = str(ip) hosts_info[ipstr] = {} mac = arpreq.arpreq(ip) vendor = None if mac is not None: vendor = maclookup.lookup(mac) scan_result = {} nmap.scan(hosts=ipstr, ports='1-1000', arguments='-sS -O') scan_result['os'] = nmap[ipstr]['osmatch'][0]['name'] scan_result['open_tcp'] = [p for p in nmap[ipstr]['tcp']] #nmap.scan(hosts=ipstr, ports='1-1000', arguments='-sU') #print(nmap[ipstr]['udp']) hardware_info = [mac, vendor] hosts_info[ipstr]['hardware'] = hardware_info hosts_info[ipstr]['scan_result'] = scan_result pprint.pprint(hosts_info)
#Ensure ethdev devices are updated within web for ethdev in macsEth0: found = None for item in devices["controllerDevices"]: if item["MAC"] == ethdev["MAC"]: if item["IPv4"] != ethdev["IPv4"]: item["IPv4"] = ethdev["IPv4"] item["online"] = 1 found = True if not found: devices["controllerDevices"].append({ "UserName": "******", "Vendor": str(mac.lookup(ethdev["MAC"])), "MAC": ethdev["MAC"], "IPv4": ethdev["IPv4"], "online": 1 }) #Check for offline devices for item in devices["controllerDevices"]: found = None for ethdev in macsEth0: if item["MAC"] == ethdev["MAC"]: found = True break if not found:
stop_time = datetime.now() total_time = stop_time - start_time print("\n Scan Complete!") print("Scan Duration: %s" % (total_time)) print() ML = MacLookup() to_write = [] for a in ans: mac = a[1].hwsrc ip = a[1].psrc try: lkup = ML.lookup(str(mac)) to_write.append((ip, mac, lkup)) print(lkup) except Exception as e: print(e) to_write.append((ip, mac, "U N K N O W N")) filename = "AROSEMENA_AYALA_" + ( 'WLAN' if interface == 'Wi-Fi' else 'LAN') + '_' + str( stop_time.year) + '.' + str(stop_time.month) + '.' + str( stop_time.day) + '.' + str(stop_time.hour) + '.' + str( stop_time.minute) + '.' + str(stop_time.second) + '.txt' directory = 'results' if not os.path.exists(directory): os.makedirs(directory)
def execute_arpscan_fm_mp(self, node, link, node_id, src_ip): print('loading arp-scan.log...') self.mlogger.writelog("loading arp-scan.log...", "info") try: res = subprocess.check_output( 'awk \'BEGIN {OFS="\t"}{print($5, $3)}\' ./arp-scan.log', shell=True).decode('utf-8') #print(res) self.mlogger.writelog("arpscan result = \n" + res, "info") except: print("arp-scan file error!!") self.mlogger.writelog("arpscan fm mp error", "error") mac = MacLookup() #mac.update_vendors() # Update time a year iplist = re.split('\t|\n', res) iplist.pop(-1) #print(iplist) maclist = [] if len(iplist) == 0: print("No exist devices from arpscan...") self.mlogger.writelog("No exist devices from arpscan...", "info") return node_id for num in range(1, len(iplist), 2): #print(iplist[num]) try: maclist.append(mac.lookup(iplist[num])) except: maclist.append("unknown") #print(maclist) keys = ['id', 'mac'] decrement_count = 0 print("len(iplist) = {}".format(len(iplist))) for num in range(0, len(iplist), 2): d = dict(zip(keys, iplist[num:num + 2])) already_scanned = 0 for node_num in range(0, len(node), 1): if node[node_num]["id"] == d["id"]: node[node_num]["vendor"] = maclist.pop(0) already_scanned = 1 decrement_count += 1 break print("ipaddr = {}".format(d["id"])) print("decrement_count = {}".format(decrement_count)) if already_scanned == 0: d['vendor'] = maclist.pop(0) d['group'] = node_id d['os'] = 'unknown' d['node_id'] = num // 2 + node_id - decrement_count #d['node_id'] = (num//2 + 1 + node_id) - decrement_count d['session'] = "" d['ics_protocol'] = {} d['ics_device'] = 0 d['secret_data'] = 0 d['goap'] = { "Symbol_GetLanNodes": True, "Symbol_TcpScan": None, "Symbol_UdpScan": None, "Symbol_IdentOs": None, "Symbol_LateralMovement": None, "Symbol_ArpPoisoning": None, "Symbol_GetNetworkInfo": None, "Symbol_DCCheck": None, "Symbol_LogonUserInfo": None, "Symbol_DomainUser": None, "Symbol_LocalUser": None, "Symbol_ValidUser": None, "Symbol_CreateUser": None, "Symbol_GetOsPatch": None, "Symbol_PrivilegeEscalation": None, "Symbol_ProcessInfo": None, "Symbol_ProcessMigrate": None, "Symbol_MainDriveInfo": None, "Symbol_SearchMainDrive": None, "Symbol_NwDriveInfo": None, "Symbol_SearchNwDrive": None, "GoalSymbol_GetLocalSecretInfo": None, "GoalSymbol_GetNwSecretInfo": None, "Symbol_PacketInfo": None, "Symbol_GetIcsProtocol": None, "Symbol_GetIcsDevice": None, "GoalSymbol_AttackIcs": None } d['local_account_list'] = [] d['local_account_pass'] = [] d['local_account_hash'] = [] d['domain_account_list'] = [] d['domain_account_pass'] = [] d['domain_account_hash'] = [] d['dc'] = [] d['domain_info'] = [] d['process_list'] = [] d['security_process'] = [] d['ipconfig_info'] = [] d['netstat_info'] = [] d['network_drive'] = [] d['local_drive'] = [] d['pcap_list'] = [] d['os_patches'] = [] d['local_vuln_list'] = [] node.append(d) #decrement_count = 0 #print(node) keys = ['target'] decrement_count = 0 duplicate_count = 0 for num in range(0, len(iplist), 2): d = dict(zip(keys, iplist[num:num + 1])) already_scanned = 0 for node_num in range(0, len(link), 1): if link[node_num]["target"] == d["target"]: already_scanned = 1 duplicate_count += 1 decrement_count += 1 break print("link ipaddr = {}".format(d["target"])) print("link decrement_count = {}".format(decrement_count)) if already_scanned == 0: d['source'] = src_ip d['node_id'] = num // 2 + node_id - decrement_count #d['node_id'] = (num//2 + 1 + node_id) - decrement_count d['value'] = 1 link.append(d) #decrement_count = 0 node_id = num // 2 + 1 + node_id - duplicate_count print("arpscan node_id = {}".format(node_id)) # test return node_id