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 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 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 search(db_file, keyword, api_key): api = Shodan(api_key) #query = 'product:elastic port:9200' query = 'product:elastic' if keyword is not None: query += ' ' + keyword count_results = api.count(query) print(f'Total results for keyword "{keyword}": {count_results["total"]}') with sqlite3.connect(str(db_file)) as conn: cur = conn.cursor() try: existing_r = cur.execute('SELECT COUNT(*) FROM IP_SEARCH_RESULT').fetchone() existing = existing_r[0] if len(existing_r) > 0 else 0 results = [] for result in api.search_cursor(query): ip = result['ip_str'] port = result['port'] org = result['org'] cntry = result['location']['country_code3'] loc = f"{result['location']['country_name']} ({result['location']['country_code']})" lat = result['location']['latitude'] lon = result['location']['longitude'] date = datetime.now().strftime('%Y-%m-%d %H:%M:%S') results.append((ip, port, org, cntry, loc, lat, lon, query, date)) cur.executemany( 'INSERT OR REPLACE INTO IP_SEARCH_RESULT ' '(IP_ADDRESS, PORT, ORGANIZATION, COUNTRY_CODE, LOCATION, ' 'LATITUDE, LONGITUDE, ORIGINAL_SEARCH_QUERY, UPDATED_DATE) ' 'VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', results) conn.commit() now_r = cur.execute('SELECT COUNT(*) FROM IP_SEARCH_RESULT').fetchone() now = now_r[0] if len(now_r) > 0 else 0 print(f'New IP addresses added: {now - existing}') finally: conn.commit() cur.close()
def shodan_search(query: str, api: Shodan, output: str): """ Search Shodan for query """ for matches in api.search_cursor(query): ip_addr = matches['ip_str'] fw = Filewriter(basefolder=output, filename=ip_addr) if fw.existed: continue ftp = ftplogin(ip_addr) if ftp != None: fw.writeshodan(matches) try: ftp.retrlines('LIST', callback=fw.writeintel) except Exception as e: logging.debug('Ftp LIST failed -> {0}'.format(e)) continue if ftpupload(ftp): fw.writeupload()
def main(): try: api = Shodan(api_key) showInfo('Querying from Shodan API') showInfo('Using query: {}'.format(search_query)) search = api.search_cursor(search_query) showInfo('Retrieved result from Shodan') showInfo('Starting scanning') for result in search: ip = result['ip_str'].strip() port = result['port'] th = Thread(target=check, args=(ip, port,)) th.daemon = True th.start() while activeCount() > 5: sleep(0.001) while activeCount() > 1: sleep(0.001) exit('Scan ended') except Exception as e: exit(e)
from shodan import Shodan from shodan.cli.helpers import get_api_key import json import os import subprocess api = Shodan("api_key") limit = 500 counter = 0 os.system("touch ips") for banner in api.search_cursor('html:/dana/'): # Perform some custom manipulations or stream the results to a database # print(banner) # with open('data.txt', 'w') as outfile: # json.dump(banner, outfile) # f = open('ips','w+') # print(banner['http']['host']) # os.system("curl -I 'https://" + banner['http']['host'] + "/dana-na///css/ds.js?/dana/html5acc/guacamole/'") command = "curl -I -k 'https://" + str( banner['http'] ['host']) + "/dana-na///css/ds.js?/dana/html5acc/guacamole/'" proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) results = proc.stdout.read().decode("utf-8") if '200' in results: f = open('ips', 'a') f.write(str(banner['http']['host']) + "\n") print(str(banner['http']['host'])) counter += 1 if counter >= limit:
from shodan import Shodan import os path = '/output/' #download path api_key = "aWAsQyIds3Z1DLuJvA4ePfM4RoWmWSxs" #(dummy key), replace with yours api = Shodan(api_key) limit = 500 counter = 0 search_ = """master_host port:"6379" OR port:"6379" "Connected Clients" """ for result in api.search_cursor(search_): """ #uncomment to limit results counter += 1 if counter >= limit: break """ ip_str = result['ip_str'] print(ip_str) filepath = path + ip_str + '.txt'
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 def _remove_unused_fields_in_vulns( self, max_references: int = DefaultValues. SHODAN_MAX_VULNERABILITIES_REFERENCES ) -> None: """ Remove fields that not useful from vulnerabilities. :param max_references: decrease quantity of reference to this number :return: None """ for host in self.results: if not host.get("vulns"): continue for cve, cve_information in host.get("vulns", {}).items(): if cve_information.get("references"): cve_information["references"] = cve_information[ "references"][:max_references] if "verified" in cve_information.keys(): cve_information.pop("verified") @exception_handler(expected_exception=ShodanConnectorSearchError) def search( self, query: str, max_records=DefaultValues.SHODAN_DEFAULT_RESULTS_QUANTITY) -> None: """ Search for defined query in Shodan database :param query: query to search for :param max_records: quantity of max records to search :return: None """ try: self.results = list(self.api.search_cursor(query))[:max_records] self._remove_unused_fields_in_vulns() 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 Shodan results :return: list of results """ return self.results def get_shodan_count(self) -> int: """ Return quantity of results from Shodan database :return: quantity of results """ return self.shodan_results_count def get_real_count(self) -> int: """ Return real quantity of results that was successfully gained from Shodan :return: quantity of real results that we get """ return self.real_results_count def get_vulnerabilities(self) -> dict: """ Return dictionary with vulnerabilities, {host: vulnerabilities} :return: dictionary with vulnerabilities """ return { host["ip_str"]: host["vulns"] for host in self.results if host.get("vulns") }
from shodan import Shodan API_KEY = "" api = Shodan(API_KEY) # Search for websites that have been "hacked" for banner in api.search_cursor('http.title:"hacked by"'): print(banner) # Get the total number of industrial control systems services on the Internet ics_services = api.count('tag:ics') print('Industrial Control Systems: {}'.format(ics_services['total'])) # Get the total number of scada services on the Internet scada_services = api.count('tag:scada') print('Supervisory Control and Data Acquisition: {}'.format( scada_services['total'])) # Get the total number of plc services on the Internet plc_services = api.count('tag:plc') print('Programmable Logic Controller: {}'.format(plc_services['total'])) # Get the total number of dcs services on the Internet dcs_services = api.count('tag:dcs') print('Distributed Control System: {}'.format(dcs_services['total']))
print("<\033[96m{ \033[92mAPI Scanner \033[96m}\033[0m>\n") print("\033[91m1 \033[92m) \033[0mHost scan") print("\033[91m2 \033[92m) \033[0mDork scan") print("\033[91m3 \033[92m) \033[0mScan selected target \n") choose=int(input("\033[96m[\033[91m+\033[96m] \033[0mChoose: ")) if choose==1: target=raw_input("\033[96m[\033[91m+\033[96m] \033[0mEnter target: ") print("\033[96m========== \033[92mScanning\033[0m %s \033[92mwith Shodan \033[96m==========\033[0m \n"%(target)) os.system("shodan host "+target) elif choose==2: dork=raw_input("\033[96m[\033[91m+\033[96m] \033[0mEnter dork: ") print("\033[96m========== \033[92mScanning\033[0m %s \033[92mdork with Shodan \033[96m==========\033[0m \n"%(dork)) with open('apikeys/shodan.txt', 'r') as file: api_key = file.read().replace('\n', '') api = Shodan(api_key) for targets in api.search_cursor(dork): print(targets['ip_str']) print("\033[96m========== \033[92mScanning\033[0m %s \033[92mdork with ZoomEye \033[96m==========\033[0m \n"%(dork)) zoom = zoomeye.ZoomEye() with open('apikeys/zoomuser.txt') as zfile: zoomuser = zfile.read().replace('\n', '') zoom.username = zoomuser with open('apikeys/zoompass.txt') as pfile: zoompass = pfile.read().replace('\n', '') zoom.password = zoompass logs = zoom.login() data = zoom.dork_search(dork) zoomeye.show_site_ip(data) elif choose==3: with open('temp.txt', 'r') as file: specified=file.read().replace('\n', '')
def main(api_key, search): api = Shodan(api_key) for result in api.search_cursor(search): print(result['hostnames'])
load_dotenv() parser = argparse.ArgumentParser() parser.add_argument("-s", "--service", help="Specify what service to look for", choices=['googleMaps']) args = parser.parse_args() api = Shodan(os.getenv('SHODAN_API')) if (args.service == "googleMaps"): def checkGoogleMapsApiKey(key): if key not in validMapsApiKeys: r = requests.head( 'https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places&signed_in=true&key=' + format(key)) if (r.status_code == 200): validMapsApiKeys.add(key) with open("maps_keys.txt", "a") as txtfile: txtfile.write(key + "\n") try: # Search Shodan validMapsApiKeys = set() for result in api.search_cursor('https://maps.googleapis.com/maps/api/js'): if 'http' in result: if 'html' in result['http']: soup = BeautifulSoup(format(result['http']), features="html.parser") sources = soup.findAll('script', {"src": True}) for source in sources: if re.search(r"^https:\/\/maps.googleapis.com\/maps\/api(.*)$", source['src']): checkGoogleMapsApiKey(urlparse.parse_qs(urlparse.urlparse(source['src']).query)['key'][0]) except Exception as e: print('Error: {}'.format(e))
from shodan import Shodan from shodan.cli.helpers import get_api_key import csv import time import json api = Shodan(get_api_key()) limit = 1050 counter = 0 i = 0 data = [] for banner in api.search_cursor('city:Santiago country:cl port:445'): # Perform some custom manipulations or stream the results to a database # For this example, I'll just print out the "data" property data.append(banner) # Keep track of how many results have been downloaded so we don't use up all our query credits counter += 1 if counter >= limit: break print(len(data)) hosts = [] i = 1 for ip in data: print(ip['ip_str'], " ", i) try: hosts.append(api.host(ip['ip_str'])) time.sleep(1) except: