Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Download host data from Shodan given a list of IPs or CIDRs
#!/usr/bin/env python3
import os
import sys
import json
import time
import random
import string
import shodan
import ipaddress
'''
Given a list of IPs or CIDR ranges, downloads host data from Shodan and saves tar.gz
0. pip install shodan, ipaddress
1. export SHODAN_API_KEY=nnnnnnn
2. python3 bulk-ip-shodan-download.py <ip/cidr list>
'''
API_KEY = os.environ['SHODAN_API_KEY']
api = shodan.Shodan(API_KEY)
def write_line(arr, file_handle):
for d in arr['data']:
line = {}
line.update(d)
file_handle.write(json.dumps(line) + "\n")
def write_results(results,fname):
with open(fname,'w') as f:
if isinstance(results,dict):
write_line(results, f)
else:
for e in results:
write_line(e, f)
def main():
if len(sys.argv) < 2:
print("Usage: {} <IP/CIDR list file>".format(sys.argv[0]))
exit(1)
with open(sys.argv[1],'r') as f:
ip_list = f.readlines()
ip_array = []
for e in ip_list:
for host in ipaddress.ip_network(e.strip(), False):
ip_array.append(host.compressed)
ip_array = list(set(ip_array))
print("Requesting info on {} IPs...".format(len(ip_array)))
# requests must be split into 100s
for ip in [ip_array[i*100:(i+1)*100] for i in range((len(ip_array) + 100-1) // 100)]:
try:
print("[+] Host info request for {}".format(ip))
hosts = api.host(ip)
try:
fname = ''.join(random.choices(string.ascii_uppercase + string.digits, k=8))
fname += ".json"
print("[+] Saving {} results to {}".format(len(hosts), fname))
write_results(hosts,fname)
except Exception as e:
print('[-] Error: %s' % e)
print(e)
time.sleep(1)
except shodan.exception.APIError as e:
print("[-] No info for these IPs...")
print("[-] shodan.exception.APIError: %s" % e)
time.sleep(1)
print("[!] Completed")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment