ifxlookup/plugins/shodan.py

68 lines
2.0 KiB
Python

from servicebase import ServiceBase
import socket
import ipaddress
import dns.resolver
import shodan
class ServiceDelegate(ServiceBase) :
_api_sessions = None
def get_arguments(cls) :
"""Returns an array of information used to construct an argumentparser argument."""
return [ '-s', '--shodan', 'store_true', 'Return Shodan information about the subject (dns)' ]
def startup(self) :
for requirement in ['keys'] :
if requirement not in self._config or (requirement in self._config and self._config[requirement] == ''):
self._error.append('Missing required config option ' + requirement)
return
keys = self._config['keys']
self._api_sessions = [shodan.Shodan(x) for x in keys]
self.debug('Searching Shodan for hosts...',1)
def lookup(self,subject) :
if self._api_sessions :
session = next(self.get_api())
try :
host = session.host(subject)
clean = self._clean_newlines(host)
return host
except shodan.exception.APIError as e:
self.debug('Unable to search for ' + subject + ' on shodan: ' + str(e),1)
pass
def _clean_newlines(self,structure) :
if type(structure) == dict :
newstructure = {}
for key in structure :
if key :
if structure[key] and type(structure[key]) == dict or type(structure[key]) == list :
newkey = key.replace('\n','')
newstructure.update({newkey:self._clean_newlines(structure[key])})
else :
newkey = key.replace('\n','')
if structure[key] and type(structure[key]) == str :
newvalue = structure[key].replace('\n','')
newstructure.update({newkey:newvalue})
else :
newstructure.update({newkey:None})
return newstructure
if type(structure) == list :
newstructure = []
for item in structure :
if type(item) == dict or type(item) == list :
newstructure.append(self._clean_newlines(item))
if type(item) == str :
newstructure.append(item.replace('\n',''))
else :
newstructure.append(item)
return newstructure
def get_api(self) :
while True :
for x in self._api_sessions :
yield x