diff --git a/Core/Entities/Financials.xml b/Core/Entities/Financials.xml index 2487589..195856a 100644 --- a/Core/Entities/Financials.xml +++ b/Core/Entities/Financials.xml @@ -40,7 +40,7 @@ Currency Name - Default.svg + CryptoWallet.svg \ No newline at end of file diff --git a/Core/Entities/Software.xml b/Core/Entities/Software.xml index 528f911..7a38cb3 100644 --- a/Core/Entities/Software.xml +++ b/Core/Entities/Software.xml @@ -16,4 +16,13 @@ Hash.svg + + + CVE + CVSS Score + + + CVE.svg + + \ No newline at end of file diff --git a/Modules/KYC/KYC.xml b/Modules/KYC/KYC.xml index acf58b6..1090357 100644 --- a/Modules/KYC/KYC.xml +++ b/Modules/KYC/KYC.xml @@ -69,7 +69,7 @@ Currency Name - Default.svg + Sanctioned_CryptoWallet.svg \ No newline at end of file diff --git a/Modules/Nessus/Nessus.xml b/Modules/Nessus/Nessus.xml index 5c91a73..b0c3411 100644 --- a/Modules/Nessus/Nessus.xml +++ b/Modules/Nessus/Nessus.xml @@ -7,9 +7,4 @@ CVSS2 Vector - - - CVE - - \ No newline at end of file diff --git a/Modules/Shodan/ShodanDomainScan.py b/Modules/Shodan/ShodanDomainScan.py index 089ad26..9c2acde 100644 --- a/Modules/Shodan/ShodanDomainScan.py +++ b/Modules/Shodan/ShodanDomainScan.py @@ -6,10 +6,10 @@ class ShodanDomainScan: category = "Network Infrastructure" description = "Find information about a particular domain" originTypes = {'Domain'} - resultTypes = {'Domain'} - parameters = {'Shodan API Key': {'description': 'Enter your Premium API key under your profile after' - 'signing up on https://shodan.io/ for more info on billing ' - 'plans:https://account.shodan.io/billing', + resultTypes = {'Domain', 'IPv6 Address', 'IP Address'} + parameters = {'Shodan API Key': {'description': 'Enter your API key under your profile after ' + 'signing up on https://shodan.io/.\nFor more info on billing ' + 'plans: https://account.shodan.io/billing', 'type': 'String', 'value': '', 'global': True}} diff --git a/Modules/Shodan/ShodanIPScan.py b/Modules/Shodan/ShodanIPScan.py index 22e425f..36bf595 100644 --- a/Modules/Shodan/ShodanIPScan.py +++ b/Modules/Shodan/ShodanIPScan.py @@ -5,10 +5,11 @@ class ShodanIPScan: name = "Shodan IP Scan" category = "Network Infrastructure" description = "Find information about ip addresses and discovered vulnerabilities" - originTypes = {'IP Address'} - resultTypes = {'Shodan Scan'} - parameters = {'Shodan API Key': {'description': 'Enter your API key under your profile after' - ' signing up on https://shodan.io/. ' + originTypes = {'IP Address', 'IPv6 Address'} + resultTypes = {'Operating System', 'Organization', 'Country', 'City', 'Autonomous System', 'GeoCoordinates', + 'Port', 'Domain', 'CVE', 'Phrase'} + parameters = {'Shodan API Key': {'description': 'Enter your API key under your profile after ' + 'signing up on https://shodan.io/.\n' 'On the Free tier you will have a rate limit of one request per ' 'second.', 'type': 'String', @@ -28,21 +29,29 @@ class ShodanIPScan: return_result.append([{'Organization Name': host['org'], 'Entity Type': 'Organization'}, {uid: {'Resolution': 'Shodan IP Organization', 'Notes': ''}}]) + if host.get('isp') is not None: + return_result.append([{'Company Name': host['isp'], + 'Entity Type': 'Company'}, + {uid: {'Resolution': 'Shodan IP ISP', 'Notes': ''}}]) return_result.append([{'Country Name': host['country_name'], 'Entity Type': 'Country'}, {uid: {'Resolution': 'Shodan IP Country', 'Notes': ''}}]) return_result.append([{'City Name': host['city'], 'Entity Type': 'City'}, {uid: {'Resolution': 'Shodan IP City', 'Notes': ''}}]) + longitude = host.get('longitude') + latitude = host.get('latitude') + if latitude is not None and longitude is not None: + return_result.append([{'Label': host['ip_str'] + " Location", + 'Longitude': host['longitude'], + 'Latitude': host['latitude'], + 'Entity Type': 'GeoCoordinates'}, + {uid: {'Resolution': 'Shodan IP GeoCoordinates', 'Notes': ''}}]) if host.get('asn') is not None: return_result.append([{'AS Number': 'AS' + host['asn'], 'Entity Type': 'Autonomous System'}, {uid: {'Resolution': 'Shodan IP AS Number', 'Notes': ''}}]) - return_result.append([{'Label': host['ip_str'] + " Location", - 'Longitude': host['longitude'], - 'Latitude': host['latitude'], - 'Entity Type': 'GeoCoordinates'}, - {uid: {'Resolution': 'Shodan IP GeoCoordinates', 'Notes': ''}}]) + for port in host['ports']: return_result.append([{'Port': host['ip_str'] + ":" + str(port), 'Entity Type': 'Port'}, @@ -57,6 +66,26 @@ class ShodanIPScan: 'Entity Type': 'Domain'}, {uid: {'Resolution': 'Shodan IP Domains', 'Notes': ''}}]) + if host.get('data') is not None: + for dataItem in host['data']: + if dataItem.get('vulns') is not None: + for vuln in dataItem.get('vulns'): + # Cast to strings for safety. + summary = str(dataItem['vulns'][vuln].get('summary')) + cvss = str(dataItem['vulns'][vuln].get('cvss')) + verified = dataItem['vulns'][vuln].get('verified') + return_result.append([{'CVE': vuln, + 'CVSS Score': cvss, + 'Entity Type': 'CVE', + 'Notes': summary}, + {uid: {'Resolution': 'Shodan IP Vulnerabilities', 'Notes': ''}}]) + if verified: + # This never really happens, as far as I can see. + return_result.append([{'Phrase': "Vulnerability Verified", + 'Entity Type': 'Phrase'}, + {len(return_result) - 1: {'Resolution': 'Shodan IP Vulnerabilities', + 'Notes': ''}}]) + def resolution(self, entityJsonList, parameters): import shodan import time diff --git a/Modules/Shodan/ShodanSearch.py b/Modules/Shodan/ShodanSearch.py index e069e37..c37008f 100644 --- a/Modules/Shodan/ShodanSearch.py +++ b/Modules/Shodan/ShodanSearch.py @@ -5,19 +5,19 @@ class ShodanSearch: name = "Shodan Search" category = "Network Infrastructure" description = "Search Shodan's database" - originTypes = {'IP Address', 'Phrase', 'Person'} - resultTypes = {'IP Address'} - parameters = {'Shodan API Key': {'description': 'Enter your Premium API key under your profile after ' + originTypes = {'IP Address', 'IPv6 Address', 'Phrase', 'Person'} + resultTypes = {'IP Address', 'IPv6 Address', 'GeoCoordinates', 'Country', 'City', 'Operating System', 'Domain', + 'Autonomous System'} + parameters = {'Shodan API Key': {'description': 'Enter your API key under your profile after ' 'signing up on https://shodan.io/.\nFor more info on billing ' 'plans: https://account.shodan.io/billing', 'type': 'String', 'value': '', 'globals': True}, - 'Number of results': {'description': 'Creating a lot of nodes could slow down the software. Please ' - 'be mindful of the value you enter.', + 'Number of results': {'description': 'Enter the maximum number of results you want returned.', 'type': 'String', - 'value': 'Enter the number of results you want returned', + 'value': '', 'default': '10'} } @@ -34,13 +34,54 @@ class ShodanSearch: for entity in entityJsonList: uid = entity['uid'] primary_field = entity[list(entity)[1]] + entityType = entity['Entity Type'] try: search = api.search(primary_field) except shodan.exception.APIError: return "The API Key provided is Invalid" for match in search['matches'][:max_results]: - return_result.append([{ - 'IP Address': str(match['ip_str']), - 'Entity Type': 'IP Address'}, - {uid: {'Resolution': 'Shodan Search results', 'Notes': ''}}]) + ipMatch = str(match['ip_str']) + if match.get('location') is not None: + locationDetails = match['location'] + longitude = locationDetails.get('longitude') + latitude = locationDetails.get('latitude') + if latitude is not None and longitude is not None: + return_result.append([{'Label': ipMatch + " Location", + 'Longitude': str(locationDetails['longitude']), + 'Latitude': str(locationDetails['latitude']), + 'Entity Type': 'GeoCoordinates'}, + {uid: {'Resolution': 'Shodan Search GeoCoordinates', 'Notes': ''}}]) + countryName = locationDetails.get('country_name') + if countryName is not None: + return_result.append([{'Country Name': countryName, + 'Entity Type': 'Country'}, + {uid: {'Resolution': 'Shodan Search Country', 'Notes': ''}}]) + cityName = locationDetails.get('city') + if cityName is not None: + return_result.append([{'City Name': cityName, + 'Entity Type': 'City'}, + {uid: {'Resolution': 'Shodan Search City', 'Notes': ''}}]) + if match.get('asn') is not None: + return_result.append([{'AS Number': 'AS' + match['asn'], + 'Entity Type': 'Autonomous System'}, + {uid: {'Resolution': 'Shodan Search AS Number', 'Notes': ''}}]) + if match.get('os') is not None: + return_result.append([{'OS Name': match['os'], + 'Entity Type': 'Operating System'}, + {uid: {'Resolution': 'Shodan Search OS', 'Notes': ''}}]) + for domain in match['domains']: + return_result.append([{'Domain Name': domain, + 'Entity Type': 'Domain'}, + {uid: {'Resolution': 'Shodan Search Domains', 'Notes': ''}}]) + if entityType != 'IP Address' and entityType != 'IPv6 Address': + if match.get('ip') is not None: + return_result.append([{ + 'IP Address': ipMatch, + 'Entity Type': 'IP Address'}, + {uid: {'Resolution': 'Shodan Search IP', 'Notes': ''}}]) + else: + return_result.append([{ + 'IPv6 Address': ipMatch, + 'Entity Type': 'IPv6 Address'}, + {uid: {'Resolution': 'Shodan Search IP', 'Notes': ''}}]) return return_result diff --git a/Resources/Icons/CVE.svg b/Resources/Icons/CVE.svg new file mode 100644 index 0000000..67a8f7b --- /dev/null +++ b/Resources/Icons/CVE.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Resources/Icons/CryptoWallet.svg b/Resources/Icons/CryptoWallet.svg new file mode 100644 index 0000000..4063c1d --- /dev/null +++ b/Resources/Icons/CryptoWallet.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/Icons/Sanctioned_CryptoWallet.svg b/Resources/Icons/Sanctioned_CryptoWallet.svg new file mode 100644 index 0000000..f160399 --- /dev/null +++ b/Resources/Icons/Sanctioned_CryptoWallet.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +