Do you want to see where an IP is located? Which ports/ services it has available? The Shodan API gives you the ability to quickly lookup information for an IP.
The shodan Python package is required for this tutorial and a valid API key, which is available for free with every Shodan account. You can install it using easy_install or pip:
pip install --user shodan
You can get your Shodan API key from your account page at:
Looking up IPs via the main Shodan REST API requires at least a Shodan Membership (one-time payment of $49 for lifetime account upgrade). For free IP lookups check out the InternetDB API.
To lookup information about an IP we will use the Shodan.host() method. Getting started with the basics is straight-forward:
import shodan
api = shodan.Shodan('YOUR API KEY')
info = api.host('8.8.8.8')
The above code requests information about Google's DNS resolver 8.8.8.8 and stores it in the info variable. Here is a closer look at the data that the info object now holds:
{
"data": [
{
"asn": "AS15169",
"hash": -553166942,
"ip": 134744072,
"isp": "Google",
"transport": "udp",
"data": "\nRecursion: enabled",
"port": 53,
"hostnames": [
"google-public-dns-a.google.com"
],
"location": {
"city": null,
"region_code": null,
"area_code": null,
"longitude": -97.822,
"country_code3": "USA",
"latitude": 37.751000000000005,
"postal_code": null,
"dma_code": null,
"country_code": "US",
"country_name": "United States"
},
"timestamp": "2018-03-16T03:06:34.553526",
"domains": [
"google.com"
],
"org": "Google",
"os": null,
"_shodan": {
"crawler": "6ff540e4d43ec69d8de2a7b60e1de2d9ddb406dc",
"options": {},
"module": "dns-udp",
"id": null
},
"opts": {},
"ip_str": "8.8.8.8"
}
],
"city": null,
"region_code": null,
"tags": [],
"ip": 134744072,
"isp": "Google",
"area_code": null,
"dma_code": null,
"last_update": "2018-03-16T03:06:34.553526",
"country_code3": "USA",
"latitude": 37.751000000000005,
"hostnames": [
"google-public-dns-a.google.com"
],
"postal_code": null,
"longitude": -97.822,
"country_code": "US",
"org": "Google",
"country_name": "United States",
"ip_str": "8.8.8.8",
"os": null,
"asn": "AS15169",
"ports": [
53
]
}
The result from api.host() contains information about the services it runs, where it's located, the hosting provider and more. There are a few top-level properties of note:
There are a few common reasons to look at a history of an IP:
We can get a full history of an IP address by providing an optional history=True parameter:
import shodan
api = shodan.Shodan('YOUR API KEY')
info = api.host('8.8.8.8', history=True)
The resulting info object will have the same structure as before but the top-level data property now contains a list of all the banners that were ever seen for that IP.
The Corporate API plan gives you the ability to lookup 100 IPs per request. If you're building a data processing pipeline that wants to do a lot of IP enrichment then doing bulk IP lookups is the way to go. And using them is nearly the same as doing individual IP lookups:
import shodan
api = shodan.Shodan('YOUR CORPORATE API KEY')
hosts = api.host([
'8.8.8.8',
'8.8.4.4',
])
for info in hosts:
# Each record in the "hosts" list is what an individual IP lookup returns
print(info['ip_str'])
# The above is equivalent to doing
info = api.host('8.8.8.8')
# ...
info = api.host('8.8.4.4')
Instead of giving the Shodan.host() method an IP address we can also give it a list of IPs. The result of a bulk IP lookup is a list of objects where each object contains the same information you'd see when doing an individual IP lookup.