diff --git a/README.md b/README.md index a9184b5..653695b 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ For more information: [Extending MISP with Python modules](https://www.misp-proj * [TruSTAR Enrich](misp_modules/modules/expansion/trustar_enrich.py) - an expansion module to enrich MISP data with [TruSTAR](https://www.trustar.co/). * [urlhaus](misp_modules/modules/expansion/urlhaus.py) - Query urlhaus to get additional data about a domain, hash, hostname, ip or url. * [urlscan](misp_modules/modules/expansion/urlscan.py) - an expansion module to query [urlscan.io](https://urlscan.io). +* [variotdbs](misp_modules/modules/expansion/variotdbs.py) - an expansion module to query the [VARIoT db](https://www.variotdbs.pl) API to get more information about a Vulnerability * [virustotal](misp_modules/modules/expansion/virustotal.py) - an expansion module to query the [VirusTotal](https://www.virustotal.com/gui/home) API with a high request rate limit required. (More details about the API: [here](https://developers.virustotal.com/reference)) * [virustotal_public](misp_modules/modules/expansion/virustotal_public.py) - an expansion module to query the [VirusTotal](https://www.virustotal.com/gui/home) API with a public key and a low request rate limit. (More details about the API: [here](https://developers.virustotal.com/reference)) * [VMray](misp_modules/modules/expansion/vmray_submit.py) - a module to submit a sample to VMray. diff --git a/documentation/README.md b/documentation/README.md index a455c79..524e1a2 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -685,6 +685,28 @@ Expansion module to fetch the html content from an url and convert it into markd ----- +#### [hyasinsight](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hyasinsight.py) + + + +HYAS Insight integration to MISP provides direct, high volume access to HYAS Insight data. It enables investigators and analysts to understand and defend against cyber adversaries and their infrastructure. +- **features**: +>This Module takes the IP Address, Domain, URL, Email, Phone Number, MD5, SHA1, Sha256, SHA512 MISP Attributes as input to query the HYAS Insight API. +> The results of the HYAS Insight API are than are then returned and parsed into Hyas Insight Objects. +> +>An API key is required to submit queries to the HYAS Insight API. +> +- **input**: +>A MISP attribute of type IP Address(ip-src, ip-dst), Domain(hostname, domain), Email Address(email, email-src, email-dst, target-email, whois-registrant-email), Phone Number(phone-number, whois-registrant-phone), MDS(md5, x509-fingerprint-md5, ja3-fingerprint-md5, hassh-md5, hasshserver-md5), SHA1(sha1, x509-fingerprint-sha1), SHA256(sha256, x509-fingerprint-sha256), SHA512(sha512) +- **output**: +>Hyas Insight objects, resulting from the query on the HYAS Insight API. +- **references**: +>https://www.hyas.com/hyas-insight/ +- **requirements**: +>A HYAS Insight API Key. + +----- + #### [intel471](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/intel471.py) @@ -1606,6 +1628,28 @@ An expansion module to query urlscan.io. ----- +#### [variotdbs](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/variotdbs.py) + + + +An expansion module to query the VARIoT db API for more information about a vulnerability. +- **features**: +>The module takes a vulnerability attribute as input and queries que VARIoT db API to gather additional information. +> +>The `vuln` endpoint is queried first to look for additional information about the vulnerability itself. +> +>The `exploits` endpoint is also queried then to look for the information of the potential related exploits, which are parsed and added to the results using the `exploit` object template. +- **input**: +>Vulnerability attribute. +- **output**: +>Additional information about the vulnerability, as it is stored on the VARIoT db, about the vulnerability itself, and the potential related exploits. +- **references**: +>https://www.variotdbs.pl/ +- **requirements**: +>A VARIoT db API key (if you do not want to be limited to 100 queries / day) + +----- + #### [virustotal](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/virustotal.py) diff --git a/documentation/logos/variot.png b/documentation/logos/variot.png new file mode 100644 index 0000000..717b7e7 Binary files /dev/null and b/documentation/logos/variot.png differ diff --git a/documentation/website/expansion/variotdbs.json b/documentation/website/expansion/variotdbs.json new file mode 100644 index 0000000..f561866 --- /dev/null +++ b/documentation/website/expansion/variotdbs.json @@ -0,0 +1,13 @@ +{ + "description": "An expansion module to query the VARIoT db API for more information about a vulnerability.", + "logo": "variot.png", + "requirements": [ + "A VARIoT db API key (if you do not want to be limited to 100 queries / day)" + ], + "input": "Vulnerability attribute.", + "output": "Additional information about the vulnerability, as it is stored on the VARIoT db, about the vulnerability itself, and the potential related exploits.", + "references": [ + "https://www.variotdbs.pl/" + ], + "features": "The module takes a vulnerability attribute as input and queries que VARIoT db API to gather additional information.\n\nThe `vuln` endpoint is queried first to look for additional information about the vulnerability itself.\n\nThe `exploits` endpoint is also queried then to look for the information of the potential related exploits, which are parsed and added to the results using the `exploit` object template." +} diff --git a/misp_modules/modules/expansion/__init__.py b/misp_modules/modules/expansion/__init__.py index 2506265..4388cb0 100644 --- a/misp_modules/modules/expansion/__init__.py +++ b/misp_modules/modules/expansion/__init__.py @@ -18,7 +18,8 @@ __all__ = ['cuckoo_submit', 'vmray_submit', 'bgpranking', 'circl_passivedns', 'c 'assemblyline_submit', 'assemblyline_query', 'ransomcoindb', 'malwarebazaar', 'lastline_query', 'lastline_submit', 'sophoslabs_intelix', 'cytomic_orion', 'censys_enrich', 'trustar_enrich', 'recordedfuture', 'html_to_markdown', 'socialscan', 'passive-ssh', - 'qintel_qsentry', 'mwdb', 'hashlookup', 'mmdb_lookup', 'ipqs_fraud_and_risk_scoring', 'clamav', 'jinja_template_rendering','hyasinsight'] + 'qintel_qsentry', 'mwdb', 'hashlookup', 'mmdb_lookup', 'ipqs_fraud_and_risk_scoring', + 'clamav', 'jinja_template_rendering','hyasinsight', 'variotdbs'] minimum_required_fields = ('type', 'uuid', 'value') diff --git a/misp_modules/modules/expansion/variotdbs.py b/misp_modules/modules/expansion/variotdbs.py index 6d4bf81..eaa5ea3 100644 --- a/misp_modules/modules/expansion/variotdbs.py +++ b/misp_modules/modules/expansion/variotdbs.py @@ -1,7 +1,7 @@ import json import requests from . import check_input_attribute, standard_error_message -from pymisp import MISPEvent, MISPObject +from pymisp import MISPAttribute, MISPEvent, MISPObject misperrors = {'error': 'Error'} mispattributes = {'input': ['vulnerability'], 'format': 'misp_standard'} @@ -20,6 +20,20 @@ class VariotdbsParser: misp_event.add_attribute(**misp_attribute) self.__misp_attribute = misp_attribute self.__misp_event = misp_event + self.__exploit_mapping = { + 'credits': 'credit', + 'exploit': 'exploit' + } + self.__exploit_multiple_mapping = { + 'cve': { + 'feature': 'cve_id', + 'relation': 'cve-id' + }, + 'references': { + 'feature': 'url', + 'relation': 'reference' + } + } self.__vulnerability_data_mapping = { 'credits': 'credit', 'description': 'description', @@ -29,9 +43,17 @@ class VariotdbsParser: 'cve': 'id', 'id': 'id' } + @property + def exploit_mapping(self) -> dict: + return self.__exploit_mapping + + @property + def exploit_multiple_mapping(self) -> dict: + return self.__exploit_multiple_mapping + @property def misp_attribute(self) -> MISPAttribute: - return self.__attribute + return self.__misp_attribute @property def misp_event(self) -> MISPEvent: @@ -50,6 +72,26 @@ class VariotdbsParser: results = {key: event[key] for key in ('Attribute', 'Object') if event.get(key)} return {'results': results} + def parse_exploit_information(self, query_results): + for exploit in query_results['results']: + exploit_object = MISPObject('exploit') + exploit_object.add_attribute('exploitdb-id', exploit['edb_id']) + for feature, relation in self.exploit_mapping.items(): + if exploit.get(feature): + exploit_object.add_attribute( + relation, + exploit[feature]['data'] + ) + for feature, relation in self.exploit_multiple_mapping.items(): + if exploit.get(feature): + for value in exploit[feature]['data']: + exploit_object.add_attribute( + relation['relation'], + value[relation['feature']] + ) + exploit_object.add_reference(self.misp_attribute.uuid, 'related-to') + self.misp_event.add_object(exploit_object) + def parse_vulnerability_information(self, query_results): vulnerability_object = MISPObject('vulnerability') for feature, relation in self.vulnerability_flat_mapping.items(): @@ -65,13 +107,14 @@ class VariotdbsParser: query_results[feature]['data'] ) if query_results.get('configurations', {}).get('data'): - for node in query_results['configurations']['data']['nodes']: - for cpe_match in node['cpe_match']: - if cpe_match['vulnerable']: - vulnerability_object.add_attribute( - 'vulnerable-configuration', - cpe_match['cpe23Uri'] - ) + for configuration in query_results['configurations']['data']: + for node in configuration['nodes']: + for cpe_match in node['cpe_match']: + if cpe_match['vulnerable']: + vulnerability_object.add_attribute( + 'vulnerable-configuration', + cpe_match['cpe23Uri'] + ) if query_results.get('cvss', {}).get('data'): cvss = {} for cvss_data in query_results['cvss']['data']: @@ -129,15 +172,27 @@ def handler(q=False): headers = {'Content-Type': 'application/json'} if request.get('config', {}).get('API_key'): headers['Authorization'] = f"Token {request['config']['API_key']}" + empty = True + parser = VariotdbsParser(attribute) r = requests.get(f"{variotdbs_url}/vuln/{attribute['value']}/", headers=headers) if r.status_code == 200: - query_results = r.json() - if not query_results: - return {'error': 'Empty results'} + vulnerability_results = r.json() + if vulnerability_results: + parser.parse_vulnerability_information(vulnerability_results) + empty = False + else: + if r.reason != 'Not found': + return {'error': 'Error while querying the variotdbs API.'} + r = requests.get(f"{variotdbs_url}/exploits/?cve={attribute['value']}", headers=headers) + if r.status_code == 200: + exploit_results = r.json() + if exploit_results: + parser.parse_exploit_information(exploit_results) + empty = False else: return {'error': 'Error while querying the variotdbs API.'} - parser = VariotdbsParser(attribute, query_results) - parser.parse_vulnerability_information() + if empty: + return {'error': 'Empty results'} return parser.get_results() @@ -147,4 +202,4 @@ def introspection(): def version(): moduleinfo['config'] = moduleconfig - return moduleconfig + return moduleinfo