def search(self, domain): """ call Shodan API and save result list to self.raw_results """ api = Shodan(self.SHODAN_API) query = "ssl.cert.subject.cn:" + domain log(f"**Querying Shodan with Search query {query}\n", "INFO") self.raw_results = list(api.search_cursor(query))
def main(): API_KEY = getpass.getpass("输入你的APIKEY:") try: os.system("clear") api = Shodan(API_KEY) results = api.search("port:3389 os:windows", limit=None, page=10) except: os.system('clear') print("\nWDNMD,别搞事啊!!") exit(0) print("共有:{}个结果".format(results['total'])) FINAL = get_results(results).get_result() try: id = int(input('1.存入数据库\n2.存入文件\n你的选择:')) except: os.system('clear') print("\nWDNMD,别搞事啊!!") exit(0) if id ==1: db_action(FINAL) elif id == 2: save_to_file(FINAL) else: os.system('clear') print("\nWDNMD,别搞事啊!!") exit(0)
def __init__(self): self.key = Core.shodan_key() if self.key is None: raise MissingKey('Shodan') self.api = Shodan(self.key) self.hostdatarow = [] self.tracker: OrderedDict = OrderedDict()
def shodansearch(self): # shodan script by Sir809 ask = input("Do you have a Shodan API key?: ").lower() if ask == "yes": pass else: self.start() apikey = input("Enter API key: ") try: api = Shodan(apikey) url = input("Ip:> ") print("\n") h = api.host(url) except shodan.exception.APIError: print(Fore.RED + "Invalid API key!") self.start() print(Fore.GREEN + ''' IP: {} Country: {} City: {} ISP: {} Org: {} Ports: {} OS: {} '''.format(h['ip_str'], h['country_name'], h['city'], h['isp'], h['org'], h['ports'], h['os']))
def sameico(self, url): import json ''' 使用shodan查找和目标使用相同图标的网站 :param url: 访问的url :param ip_lis: 对该ip_lis进行添加最后进行返回 :return: ''' print("开始进行相同图标网站的查询") url = "http://" + url api = Shodan(config.shodan_api) url = url + "/favicon.ico" res = [] try: hash = self.getfaviconhash(url) if hash: query = "http.favicon.hash:{}".format(hash) # print(query) print("[+] The same ico get") for hosts in api.search_cursor(query): res.append(hosts['ip_str']) return res except: pass print("相同图标网站查询结束找到了 " + str(len(res))) self.ms.text_print.emit(self.sameinfo, stander_output('通过相同的网站图标寻找', res)) return res
def __init__(self, dirname='Images', search=None, path=None, timeout=4, pages=0, verbose=False): self.search = search self.path = path self.dirname = dirname self.timeout = timeout self.pages = pages self.verbose = verbose self.api = None try: keyfile = open('shodan_api_key', 'r') key = keyfile.readline() keyfile.close() self.api = Shodan(key) except FileNotFoundError: print('Key file not found') DIR_NUMBER = 2 while os.path.exists(self.dirname): self.dirname = self.dirname.strip('0987654321') + str(DIR_NUMBER) DIR_NUMBER += 1
class ShodanConnector: @exception_handler(expected_exception=ShodanConnectorInitError) def __init__(self, api_key=DefaultValues.SHODAN_API_KEY): self.api = Shodan(api_key) self.results: list = [] self.shodan_results_count: int = 0 self.real_results_count: int = 0 @exception_handler(expected_exception=ShodanConnectorSearchError) def search( self, query: str, max_records=DefaultValues.SHODAN_DEFAULT_RESULTS_QUANTITY ) -> None: try: self.results = list(self.api.search_cursor(query))[:max_records] self.shodan_results_count = self.api.count(query).get("total") except (APIError, APITimeout) as api_error: print(f"Shodan API error: {api_error}") self.real_results_count = len(list(self.results)) def get_results(self) -> list: return self.results def get_shodan_count(self) -> int: return self.shodan_results_count def get_real_count(self) -> int: return self.real_results_count def get_vulnerabilities(self) -> dict: return { host["ip_str"]: host["vulns"] for host in self.results if host.get("vulns") }
def __init__(self, host): self.host = host self.key = "oCiMsgM6rQWqiTvPxFHYcExlZgg7wvTt" if self.key == "": print "You need an API key in order to use SHODAN database. You can get one here: http://www.shodanhq.com/" sys.exit() self.api = Shodan(self.key)
def __init__(self, ips_list, services_config): """ Initialize Shodan Parser from results file. :param list(str) ips_list: list of ip addresses :param ServicesConfig services_config: Services configuration """ self.services_config = services_config self.api = None self.api_key = None self.ips_list = ips_list # config = os.path.expanduser("~/.shodan_api_key") # if not FileUtils.can_read(config): # logger.error("Shodan key file doesn't exists in {0}".format(config)) # else: # self.api_key = FileUtils.read(config).rstrip() # if self.api_key is not None \ # or self.api_key is not '': # self.api = Shodan(self.api_key) # else: # logger.error("Error missing shodan api key in {0}".format(config)) # return if 'shodan' in API_KEYS.keys() and API_KEYS['shodan']: self.api_key = API_KEYS['shodan'] self.api = Shodan(self.api_key) else: logger.error('Shodan API key is missing in "apikeys.py"') return None
def _shodan_report_(self, evidence): """ Return True if the call to the shodan API has worked properly """ try: api = Shodan(API_KEY_SHODAN) ips = [] for key, val in tqdm(evidence.items(), desc="Hostname resolution"): if "ip" not in key: ips.append(self.hostname_resolver(val)) else: ips.append(val) ip_info = {} for key, val in tqdm(enumerate(ips), desc="Wait for Shodan report", total=len(ips)): try: ip_info['ip' + str(key)] = api.host(val) json_writer("./shodan_report/ip" + str(key), ip_info['ip' + str(key)]) except Exception as e: print('Error: {}: {}'.format(val, e), end="\r") pass time.sleep(2) except Exception as e: print('Error: {}'.format(e)) sys.exit(1) return True
def shodan_scan_task(id): SHODAN_API_KEY = keys['keys']['shodan'] device = Device.objects.get(id=id) api = Shodan(SHODAN_API_KEY) try: # Search Shodan results = api.host(device.ip) # Show the results total = len(results['ports']) for counter, i in enumerate(results['data']): product = '' tags = "" if 'product' in i: product = i['product'] if 'tags' in i: tags = i['tags'] print(counter) device1 = ShodanScan(device=device, products=product, ports=str(i['port']), module=i['_shodan']['module'], tags=tags) device1.save() current_task.update_state(state='PROGRESS', meta={'current': counter, 'total': total, 'percent': int((float(counter) / total) * 100)}) return {'current': total, 'total': total, 'percent': 100} except Exception as e: print(e.args)
def get_shodan_data(indicator, shodan_api_key): data = {} if shodan_api_key: try: shodan_api = Shodan(shodan_api_key) shodan_query = shodan_api.host(indicator) shodan_ports = [] shodan_tags = shodan_query.get('tags') shodan_list_tags = [] if shodan_tags: for tag in shodan_tags: shodan_list_tags.append(tag) else: shodan_tags = 'None' data['shodan_tags'] = ", ".join(shodan_list_tags) data['shodan_region'] = shodan_query.get('region_code', 'None') data['shodan_postal'] = shodan_query.get('postal_code', 'None') data['shodan_country'] = shodan_query.get('country_code', 'None') data['shodan_city'] = shodan_query.get('city', 'None') for item in shodan_query.get('data', []): shodan_ports.append(str(item['port'])) data['shodan_ports'] = ", ".join(shodan_ports) data['shodan_hostnames'] = str( shodan_query.get('hostnames', 'None')) data['shodan_org'] = shodan_query.get('org', 'None') except Exception as err: print('Shodan error for indicator{}: {}'.format( indicator, traceback.format_exception(type(err), err, err.__traceback__))) return data
def Shodan_start(self, text, page): try: data = '' self.Ui.action_start.setEnabled(False) self.Ui.pushButton_start.setEnabled(False) api = Shodan(self.shodan_key) self.Ui.textEdit_log.append(self.getTime() + '正在查询数据,请稍等...') eventlet.monkey_patch(thread=False) try: timeout = int(self.Ui.comboBox_timeout.currentText()) with eventlet.Timeout(timeout, True): search = api.search(text, int(page)) except: self.Ui.textEdit_log.append(self.getTime() + '获取数据超时') self.Ui.action_start.setEnabled(True) self.Ui.pushButton_start.setEnabled(True) return for result in search['matches']: # print(result) ip = result['ip_str'].strip() port = result['port'] data += 'http://' + str(ip) + ':' + str(port) + '\n' self.Ui.textEdit_result.append(data.strip()) self.Ui.textEdit_log.append(self.getTime() + "查询结束!") except Exception as e: self.Ui.textEdit_log.append(self.getTime() + str(e)) self.Ui.action_start.setEnabled(True) self.Ui.pushButton_start.setEnabled(True) self.Ui.action_start.setEnabled(True) self.Ui.pushButton_start.setEnabled(True)
class ShodanIO(Module): def __init__(self, b): super().__init__(b) self.key = self.bot.config.get('apikeys', 'shodan') if not self.key: raise SakariException('Couln\'t find api key for Shodan.') self.shodan = Shodan(self.key) @Command('shodan') def query(self, c, e, args): try: result = self.shodan.count(' '.join(args)) c.privmsg(get_target(c, e), 'Found {} results.'.format(result)) except APIError as er: c.privmsg(get_target(c, e), '\x02Error:\x0f {}'.format(er.value)) @Command('shost', 'shodanhost') def host(self, c, e, args): try: result = self.shodan.host(args[0]) if result: c.privmsg(get_target(c, e), 'Available ports: {' + ', '.join([str(n['port']) for n in result['data']]) + '}.') except APIError as er: c.privmsg(get_target(c, e), '\x02Error:\x0f {}'.format(er.value))
def shodan_search(term): """ Search in shodan using the dork received as parameter and return a list of IPs. """ from shodan import Shodan api = Shodan(SHODAN_API_KEY) try: results = api.search(term) except Exception, e: print 'Error: %s' % e
def enable_all_triggers(api_client: shodan.Shodan, alert: {}): """Enable all triggers of a Shodan alert.""" available_triggers = api_client.alert_triggers() enabled_triggers = list(alert['triggers'].keys()) for trigger in available_triggers: if trigger['name'] not in enabled_triggers: LOGGER.debug('Enable %s trigger.', trigger['name']) api_client.enable_alert_trigger(alert['id'], trigger['name'])
def create_alert(name, ip, expires): myip = get_my_ip() api = Shodan(settings.API_KEY) if myip != '': try: create_alert = api.create_alert(name=name, ip=ip, expires=expires) return create_alert except Exception as e: return ''
def shodan_search(fav_hash): ip = None shodan = Shodan(get_api_key()) try: search = shodan.search(f"http.favicon.hash:{fav_hash}") for result in search["matches"]: ip = result['ip_str'] except: print("Shodan Search Error") return ip
def apicheck(): api = Shodan('key') try: # Search Shodan results = api.search('thinkphp') # Show the results print('Results found: {}'.format(results['total'])) for result in results['matches']: url = "http://" + result['ip_str'] checkall(url) except: pass
def main(): api = Shodan('T3YseGLAzQ6pmPAW4qfVyHKAi20gHfX6') h = api.host('84.199.0.254') print(h) print(''' Direccion: {} Ciudad: {} ISP: {} Organizacion: {} Puertos: {} '''.format(h['ip_str'], h['city'], h['isp'], h['org'], h['ports']))
def ShodanMethod(ip): currentPorts = "" api = Shodan('hYOKzljNkOxZI8C2aoJDQX2LdDjhAKEz') try: ipinfo = api.host(ip) except: return "None" for key in ipinfo.keys(): if key == "ports": currentPorts = ipinfo[key] return currentPorts
def fetch_from_shodan(): try: api = Shodan(SHODAN_API_KEY) results = api.host(TARGET) services = [] vulns = [] for port in results["ports"]: services.append({ "name": "unknown", "port": port, "protocol": "unknown" }) for cve in results.get("vulns", []): cve_data_url = f'https://cve.circl.lu/api/cve/{cve}' cve_data = requests.get(cve_data_url).json() if 'cvss' not in cve_data or 'ip' not in cve_data: continue name = cve severity = 'med' # exampel severity mapping if cve_data['cvss'] > 6.5: severity = 'high' if cve_data['cvss'] > 8: severity = 'critical' if cve_data['capec']: name = cve_data['capec'][0]['name'] desc = cve_data['capec'][0]['summary'] vulns.append({ "name": name, "desc": desc, "severity": severity, "refs": cve_data['references'], "type": "Vulnerability", }) faraday_info = { "hosts": [{ "ip": int2ip(results['ip']), "description": "hsot found using shodan api", "hostnames": results.get('hostnames', []), "os": results.get('os') or '', "services": services, "vulnerabilities": vulns }] } print(json.dumps(faraday_info)) except APIError as exception: print('Error: {}'.format(exception))
def fetch_from_shodan(): try: api = Shodan(SHODAN_API_KEY) results = api.host(TARGET) services = [] vulns = [] for port in results["ports"]: services.append({ "name": "unknown", "port": port, "protocol": "unknown" }) for cve in results.get("vulns", []): cve_data_url = f"https://cve.circl.lu/api/cve/{cve}" cve_data = requests.get(cve_data_url).json() if "cvss" not in cve_data or "ip" not in cve_data: continue name = cve severity = "med" # exampel severity mapping if cve_data["cvss"] > 6.5: severity = "high" if cve_data["cvss"] > 8: severity = "critical" if cve_data["capec"]: name = cve_data["capec"][0]["name"] desc = cve_data["capec"][0]["summary"] vulns.append({ "name": name, "desc": desc, "severity": severity, "refs": cve_data["references"], "type": "Vulnerability", }) faraday_info = { "hosts": [{ "ip": int2ip(results["ip"]), "description": "hsot found using shodan api", "hostnames": results.get("hostnames", []), "os": results.get("os") or "", "services": services, "vulnerabilities": vulns, }] } print(json.dumps(faraday_info)) except APIError as exception: print("Error: {}".format(exception))
def query_shodan(crtsh_results, args): """ check shodan for infra using certificate serial number Params: crtsh_results - list of ssl cert serials to query shodan shodan_key - a string representing a Shodan API token """ # for each certifcate returned from crt.sh, query Shodan using the serial # number and return IP addresses for hosts that match shodan_key = args.token api = Shodan(shodan_key) shodan_results = [] print("[+] Querying Shodan for certificate serial numbers") for cert in crtsh_results: shodan_result = {} serial_num = cert['serial_number'] common_name = cert['common_name'] query = f'ssl.cert.serial:{serial_num}' shodan_result['cert_serial'] = serial_num shodan_result['cert_common_name'] = common_name shodan_result['ips'] = [] shodan_result['hostnames'] = [] print(f'[+] Checking serial {serial_num}') try: result = api.search(query) except Exception as e: print(f'Error: {e}') sys.exit(1) else: time.sleep(1) if result['total'] != 0: print( f'[!] Found infrastructure for serial: {serial_num} and common name: {common_name}' ) for service in result['matches']: print(service['ip_str']) shodan_result['ips'].append(service['ip_str']) for hostname in service['hostnames']: print(hostname) shodan_result['hostnames'].append(hostname) else: if global_verbose == True: print(f'[+] No results found for serial: {serial_num}') continue shodan_results.append(shodan_result) return shodan_results
def main(): if parser.query and parser.api: api = Shodan(parser.api) try: b = api.search(parser.query) print('Total targets: {}'.format(b['total'])) for i in b['matches']: print('Target found: {}'.format(i['ip_str'])) except: print('An error has occurred') else: print('Both params (query and api) are required')
def sd(self): #shodan conf = configparser.ConfigParser() conf.read("config.ini") API_KEY = conf.get("shodan", "key") api = Shodan(API_KEY) sdsearch = self.lineEdit_3.text() #搜索 pages = self.lineEdit_4.text() #页数 for mun in range(1, int(pages) + int(1)): results = api.search(sdsearch, page=mun) for result in results['matches']: ip = result['ip_str'] port = result['port'] self.textEdit_3.append(str(ip) + ':' + str(port))
def extend_cert_list(): with open('config.json', 'r') as config: data = json.load(config) shodan_key = data['shodan_key'] if not shodan_key: return shodan_api = Shodan(shodan_key) http_banners = [] mmh3_hashes = set() with open('cert_list.txt', 'r') as cert_list: for _, target in enumerate(cert_list): try: target = target.strip() print(target) s = socket.socket() tport = 80 s.connect((target, tport)) head_request = str.encode('HEAD / HEAD/1.1\nHost: ' + target + '\n\n') s.send(head_request) http_banner = s.recv(1024).decode() http_banners.append(http_banner) s.close() except socket.error as socketerror: print("Error: ", socketerror) print('Continuing to next entry on cert list') s.close() continue for http_banner in http_banners: h = mmh3.hash(http_banner) mmh3_hashes.add(h) mmh3_hashes.remove(0) with open('extended_cert_list.txt', 'w+') as extended_cert_list: try: for h in mmh3_hashes: query = f'hash:{h}' results = shodan_api.search(query) print(f'Total for hash {h}: {results["total"]}') for result in results['matches']: hostnames = result['hostnames'] for hostname in hostnames: extended_cert_list.write(f'{hostname}\n') except: print('Potential API Error. Please upgrade your shodan account to support filter/paging')
def get_ip_data_from_shodan(api_key): api = Shodan(api_key) # https://developer.shodan.io/api # search = 'scada country:"DE"' # search = "s7-300 country:'DE'" ## Siemens SIMATIC S7-300 (maybe Honeypots) search = "Wasserwerk" # search = "flowChief" # search = "http.title:'Secure Access SSL VPN' country:'DE'" ## PulseSecure, maybe CVE-2021-2289 print("Query shodan ...") data = api.search(query=search) for d in tqdm.tqdm(data["matches"]): yield d
def account_info(self): try: if not self.api_key: colorprint.red("[-] Shodan api cant not be Null") sys.exit() api = Shodan(self.api_key) account_info = api.info() msg = "[+] Available Shodan query credits: %d" % account_info.get( 'query_credits') colorprint.green(msg) except APIError as e: colorprint.red(e) sys.exit() return True
def account_info(self): try: if not self.api_key: outputscreen.error("[-] Shodan api cant not be Null") sys.exit() api = Shodan(self.api_key) account_info = api.info() msg = "[+] Available Shodan query credits: %d" % account_info.get( 'query_credits') outputscreen.success(msg) except APIError as e: outputscreen.error(e) sys.exit() return True
def main(scope_file, tcp_services_file, api_file, outfile): missing = [] f = open(api_file, "r") apikey = (f.read()) f.close() api = Shodan(str(apikey.strip())) scope = open(scope_file, "r") for scope_line in scope: try: IPNetwork(str(scope_line)) except: error = (str(scope_line) + ": ", sys.exc_info()[1]) debug_print(error) continue for ip in IPNetwork(str(scope_line)): try: ipinfo = api.host(str(ip)) except: error = (str(ip) + ": ", sys.exc_info()[1]) debug_print(error) continue host_print(ipinfo) for port in ipinfo['ports']: full_string = (str(ip) + ",TCP," + str(port)) debug_print(full_string) with open(tcp_services_file, "r+") as file: for line in file: if full_string in line: debug_print("match") break else: if arguments["scan"] is True: if (nmap_scan(str(ip), str(port))) is True: missing.append(str(ip) + "," + str(port)) else: missing.append(str(ip) + "," + str(port)) print("Your matrix file is missing: ") print("=============================") print("IP, Port") for ip_port in missing: print(ip_port) if outfile is not None: f = open(outfile, "w") f.write("IP Address, Port\n") for ip_port in missing: f.write(ip_port + "\n") f.close()
def devices_nearby(lat, lon, id, query): SHODAN_API_KEY = keys['keys']['shodan'] device = Device.objects.get(id=id) api = Shodan(SHODAN_API_KEY) fail = 0 # Shodan sometimes fails with no reason, sleeping when it happens and it prevents rate limitation try: # Search Shodan results = api.search("geo:" + lat + "," + lon + ",15 " + query) except: fail = 1 print('fail1') if fail == 1: try: results = api.search("geo:" + lat + "," + lon + ",15 " + query) except Exception as e: print(e) try: # Show the results total = len(results['matches']) for counter, result in enumerate(results['matches']): if 'product' in result: product = result['product'] else: product = "" current_task.update_state(state='PROGRESS', meta={ 'current': counter, 'total': total, 'percent': int((float(counter) / total) * 100) }) device1 = DeviceNearby(device=device, ip=result['ip_str'], product=product, org=result['org'], port=str(result['port']), lat=str(result['location']['latitude']), lon=str(result['location']['longitude'])) device1.save() return {'current': total, 'total': total, 'percent': 100} except Exception as e: print(e)
def my_shodan(ip): from shodan import Shodan SHODAN_API_KEY = "sphexJZnbzincTbmgrmofXwGNjusg4Wr" api = Shodan(SHODAN_API_KEY) try: host = api.host(ip) except: sys.exit("\n[-] Shodan err,please check your domain or network!!!") print("[+] Shodan search:" + '\n' + '-' * 40) print(""" IP:%s Organization:%s OS:%s """ % (host['ip_str'], host.get('org','n/a'), host.get('os','n/a'))) for item in host['data']: print "Port:%s\nBanner:%s" % (item['port'], item['data'])
def info_domains(self, domain): results = Shodan.search(self, 'hostname:%s' % domain) if 'matches' in results: all_domains = list(set([item for r in results['matches'] for item in r['hostnames']])) ips = list(set([r['ip_str'] for r in results['matches']])) ports = list(set([r['port'] for r in results['matches']])) transports = list(set([r['transport'] for r in results['matches']])) isp = list(set([r['isp'] for r in results['matches'] if 'isp' in r])) asn = list(set([r['asn'] for r in results['matches'] if 'asn' in r])) orgs = list(set([r['org'] for r in results['matches'] if 'org' in r])) return {'all_domains': all_domains, 'ips': ips, 'ports': ports, 'transports': transports, 'isp': isp, 'asn': asn, 'orgs': orgs }
class SearchShodan: def __init__(self): self.key = Core.shodan_key() if self.key is None: raise MissingKey(True) self.api = Shodan(self.key) self.hostdatarow = [] def search_ip(self, ip): try: ipaddress = ip results = self.api.host(ipaddress) technologies = [] servicesports = [] for result in results['data']: try: for key in result['http']['components'].keys(): technologies.append(key) except KeyError: pass port = str(result.get('port')) product = str(result.get('product')) servicesports.append(str(product)+':'+str(port)) technologies = list(set(technologies)) self.hostdatarow = [ str(results.get('ip_str')), str(results.get('hostnames')).strip('[]\''), str(results.get('org')), str(servicesports).replace('\'', '').strip('[]'), str(technologies).replace('\'', '').strip('[]')] except exception.APIError: print(f'{ipaddress}: Not in Shodan') self.hostdatarow = [ipaddress, "Not in Shodan", "Not in Shodan", "Not in Shodan", "Not in Shodan"] except Exception as e: print(f'Error occurred in the Shodan IP search module: {e}') finally: return self.hostdatarow
def __init__(self, api_key): Shodan.__init__(self, api_key)
def host(self, ips, history=False, minify=False): host = Shodan.host(self, ips, history=history, minify=minify) if host: return host
#! /usr/bin/env python # coding=UTF-8 # Filename: Leverett-Wightman-cost.py # Template python-shodan code from: # [email protected] # www.concinnity-risks.com import time, sys from shodan import Shodan from decimal import * SHODAN_API_KEY = "" # Create a connection to the Shodan API api = Shodan(SHODAN_API_KEY) FACETS = [ ('org', 10), ('asn', 10), # We only care about the top 5 countries, this is how we let Shodan know to return 5 instead of the # default 10 for a facet. If you want to see more than 10, you could do ('country', 1000) for example # to see the top 1,000 countries for a search query. ('country', 10), ] FACET_TITLES = { 'org': 'Top 10 Organizations', 'asn': 'Top 10 Autonomous Systems', 'country': 'Top 10 Countries', }
def __init__(self): self.key = Core.shodan_key() if self.key is None: raise MissingKey(True) self.api = Shodan(self.key) self.hostdatarow = []
def __init__(self, b): super().__init__(b) self.key = self.bot.config.get('apikeys', 'shodan') if not self.key: raise SakariException('Couln\'t find api key for Shodan.') self.shodan = Shodan(self.key)
def host(self, ips): host = Shodan.host(self, ips) if host: return host
print('Usage: {} <IPs filename> <output filename> [with history]'.format(argv[0])) exit(1) input_filename = argv[1] output_filename = argv[2] # Whether or not to look up historical information for the IPs use_history = False if len(argv) == 4: use_history = True # Must have initialized the CLI before running this script key = get_api_key() # Create the API connection api = Shodan(key) # Create the output file fout = open_file(output_filename, 'w') # Open the file containing the list of IPs with open(input_filename, 'r') as fin: # Loop over all the IPs in the file for line in fin: ip = line.strip() # Remove any trailing whitespace/ newlines # Wrap the API calls to nicely skip IPs which don't have data try: print('Processing: {}'.format(ip)) info = api.host(ip, history=use_history)
def run(self, args, lookup, report_directory, api_key_directory): """main function""" self.shodan_query_result = [] self.shodan_api_key = None self.api_key_value = None #first if https://shodan.readthedocs.io/en/latest/tutorial.html#connect-to-the-api #else https://shodan.readthedocs.io/en/latest/tutorial.html#looking-up-a-host #check for a stored api key, if missing ask for it and if it should be saved if not os.path.exists(api_key_directory + 'shodan.key'): print('[!] You are missing {}shodan.key'.format(api_key_directory)) self.api_key_value = getpass.getpass('[i] Please provide an API Key: ') response = raw_input('[i] Would you like to save this key to a plaintext file? (y/n): ') if 'y' in response.lower(): with open(api_key_directory + 'shodan.key', 'w') as api_key_file: api_key_file.writelines(self.api_key_value) else: pass with open(api_key_directory + 'shodan.key') as f: self.api_key_value = f.readlines()[0] #invoke api with api key provided shodanApi = Shodan(self.api_key_value) #roll through the lookup list from -i or -d for i, l in enumerate(lookup): #open output file shodan_text_output=open(report_directory+l+'/'+l+'_shodan.txt','w') #user notification that something is happening print('[+] Querying Shodan via API search for {}'.format(l)) try: #set results to api search of current lookup value #https://shodan.readthedocs.io/en/latest/examples/basic-search.html result = shodanApi.search(query="hostname:"+l) print('[+] Shodan found: {} hosts'.format(str(result['total']))) #for each result for service in result['matches']: if args.verbose is True: print(str(service['ip_str'].encode('utf-8')+\ ' ISP: '+service['isp'].encode('utf-8')+\ ' Last seen: '+service['timestamp'].encode('utf-8'))) if args.verbose is True: #print and encode if there are non-us chars print(service['data'].encode('utf-8')) #append to shodanResult list self.shodan_query_result.append(str(\ service['ip_str'].encode('utf-8')+\ '\nISP:'+service['isp'].encode('utf-8')+\ '\nLast seen:'+service['timestamp'].encode('utf-8'))+\ '\n'+service['data'].encode('utf-8')) #catch exceptions except Exception as e: #print excepted error print('[-] Shodan Error: {} '.format(e)) print('[!] You may need to specify an API key with -s <api key>') return #write contents of shodanResult list. this needs formatted shodan_text_output.writelines('[+] Shodan found: {} hosts\n\n'.format(str(result['total']))) shodan_text_output.writelines(self.shodan_query_result) return self.shodan_query_result
def search(self, query, page=1): results = Shodan.search(self, query, page=page) return results