예제 #1
0
def find_mac(mac_addr):
    mac_data = MacLookup()
    mac_data.update_vendors()
    try:
        return mac_data.lookup(mac_addr)
    except KeyError:
        return "Unknown"
예제 #2
0
    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
예제 #3
0
def get_manufacturer(mac):
    search_manufacturer = MacLookup()
    try:
        manufacture = search_manufacturer.lookup(mac)
    except:
        manufacture = "Unknown"
    return manufacture
예제 #4
0
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()
예제 #6
0
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
예제 #7
0
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]
예제 #8
0
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
예제 #9
0
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()
예제 #10
0
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"
        )
예제 #11
0
def findVendor(macAdress):
    mac = MacLookup()
    try:
        return mac.lookup(macAdress)
    except:
        pass
예제 #12
0
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)
예제 #13
0
#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:
예제 #14
0
    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)
예제 #15
0
    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