Saturday, November 28, 2015

Vendor lookup for AT&T: Who's on your network?

Happy Thanksgiving! 

Hope you enjoyed time with family, friends, relaxing or shopping this weekend.

Many times I find myself looking up a mac address on a network to figure out who the vendor is.
Identifying the vendor for a mac address is helpful when trying to identify nodes on your network which have obscure hostnames. This can also help identify mac spoofing and make investigating devices on your network much easier.

Typically, if I find myself performing a repetitive task I try to automate it using python. So let's get started. 

AT&T Provides their users with a nice table at the home page of the router which requires no authentication. Just access to the network.

AT&T Homepage Screenshot (Hostnames and second half of MAC omitted)

GOAL: Load table into dataframe and perform vendor lookup for each MAC

If you're not familiar with dataframes, I encourage you to read pandas data structures intro. At it's core a dataframe is a container for Series objects (lists) within pandas. The value of converting a table into a dataframe is the powerful collection of analytical methods associated with each dataframe object. 

For a while, I've looked for reasons to try pandas read_html method. Finally... the perfect occasion! read_html uses python modules such as lmxl, beautifulSoup, and html5lib to extract attributes out of a web page, transform the data, and load it into a dataframe.

Using chrome's inspection tool to look for a unique attribute I found width=800 was unique to the table.
Chrome inspector

TIP: read_html requires the <table> tag in your data. If you want to use pd.read_html and your data does not have a table tag you can add it by concatenating your data '<table> %s </table>' % data

Let's extract and load the data:

import requests
import pandas as pd

#Address for AT&T Modem
pull_macs_url = ''

#load data into dataframe using the width attribute
df = pd.read_html(pull_macs_url, attrs={'width':'800'}, header=0)[0]

Let's verify our data loaded by printing out the dataframe.


Device IPv4 Address / Name MAC Address Status Connection Allocation
0 / removed 40:b7:f3:removed on Ethernet dhcp
1 / removed bc:c8:10:removed on Ethernet dhcp
2 / removed 00:23:74:removed on HPNA dhcp
3 / removed 00:1f:c4:removed on HPNA dhcp

Success! We have our dataframe, now we need to:

  1. Isolate the MAC Addresses into a single Series
  2. Find a MAC database
  3. Write a function to apply to our dataframe which will run against the MAC Addresses
  4. Add the vendor to a new Series (column) in the dataframe.
To Isolate the MAC Addresses we simply retrieve the column in the dataframe (This can be done in one step later, but for clarity I've made this a separate step)
mac_addresses = df['MAC Address']

The MAC Vendor API I found is located at They provide 10,000 requests per day and no registration or API key is required. A sample request might look like:

If cannot associate a vendor to a MAC it will return a 404. This is good to know so we can check the status code in our function.

Here is the function I went with:

def vendor_loookup(mac):
    from urllib.parse import quote_plus
    vendor = None
        vendor_lookup = '' % quote_plus(mac)
        vendor_response = requests.get(vendor_lookup)
        if vendor_response.status_code != 200:
            vendor = 'No Vendor Found'
            vendor = vendor_response.text
        vendor = 'Error'
    return vendor

Now we need to apply our function to the MAC addresses, add the vendor to a new column and display the results

df['Vendor'] = mac_addresses.apply(vendor_loookup)

Device IPv4 Address / Name MAC Address Status Connection Allocation Vendor
1 / removed bc:c8:10:removed on Ethernet dhcp CISCO SPVTG
2 /removed00:23:74:removed on HPNA dhcp ARRIS GROUP, INC.
5 / removed 00:19:9d:removed off Wireless dhcp VIZIO, INC.
14 / removed 90:b6:86:removed off Wireless dhcp MURATA MANUFACTURING CO., LTD.
15 / removed 00:22:5f:removed on Wireless dhcp LITEON TECHNOLOGY CORPORATION
16 / removed 5c:f6:dc:removed on Wireless static SAMSUNG ELECTRONICS CO.,LTD
17 / removed c6:12:f5:removed on Ethernet dhcp No Vendor Found
18 / removed 18:59:33:removed on Ethernet dhcp CISCO SPVTG
19 / removed bc:c8:10:removed on Ethernet dhcp CISCO SPVTG
20 / removed 00:1f:a7:removed on Wireless dhcp SONY COMPUTER ENTERTAINMENT INC.
21 / removed f0:24:75:removed off Wireless dhcp APPLE, INC.
22 / removed 30:59:b7:removed off Wireless dhcp MICROSOFT

Now we have our mac addresses associated with vendors. Time to harness the power of pandas and group by vendor to help illustrate groupings.

Vendor_DF = pd.DataFrame(df.groupby(['Vendor', 'Device IPv4 Address / Name', 'MAC Address']).size())
Vendor_DF = Vendor_DF.drop(0, axis=1)

And finally... we have MAC addresses grouped by vendor. This can help identify rogue nodes and provide insight to what devices are on your network. 

Vendor Device IPv4 Address / Name MAC Address
APPLE, INC. / bobs-iPad f0:24:75:removed / macbook ac:bc:32:removed / removed 7c:d1:c3:removed
ARRIS GROUP, INC. / removed 40:b7:f3:removed / removed 00:23:74:removed / removed 00:1f:c4:removed / removed 00:25:f1:removed / removed cc:7d:37:removed
CISCO SPVTG / removed 18:59:33:removed / removed bc:c8:10:removed / Cisco_AP_ATT bc:c8:10:removed
GAINSPAN CORP. / removed 00:1d:c9:removed
H&D WIRELESS / removed 78:c4:0e:removed
HEWLETT PACKARD / removed 6c:c2:17:removed / removed 3c:4a:92:removed
LG INNOTEK / removed 94:44:44:removed
MICROSOFT / Xbox-SystemOS 30:59:b7:removed / Xbox-SystemOS 30:59:b7:removed
MURATA MANUFACTURING CO., LTD. / removed 90:b6:86:removed / removed 90:b6:86:removed
No Vendor Found / removed c6:12:f5:removed / removed c6:12:f5:removed / removed c6:12:f5:removed / removed c6:12:f5:removed / removed c6:12:f5:removed / removed c6:12:f5:removed / removed c6:12:f5:removed / removed c4:2f:ac:removed
SAMSUNG ELECTRO MECHANICS / removed dc:71:44:removed
SAMSUNG ELECTRO MECHANICS CO., LTD. / removed f0:25:b7:removed
SAMSUNG ELECTRONICS CO.,LTD / removed 5c:f6:dc:removed / removed 38:2d:e8:removed
SHENZHEN BILIAN ELECTRONIC CO.,LTD / removed 20:f4:1b:removed
SONY COMPUTER ENTERTAINMENT INC. / removed 00:1f:a7:removed
VIZIO, INC. / removed 00:19:9d:removed / removed 00:19:9d:removed

This was a basic introduction to identifying nodes on your network and how to correlate mac addresses to vendors using pandas with python.

All code can found on my github account.

No comments:

Post a Comment