diff --git a/REQUIREMENTS b/REQUIREMENTS index 3bbcc88..29387f1 100644 --- a/REQUIREMENTS +++ b/REQUIREMENTS @@ -28,3 +28,4 @@ maclookup vulners psutil blockchain +git+https://github.com/MISP/PyIntel471.git diff --git a/misp_modules/modules/expansion/__init__.py b/misp_modules/modules/expansion/__init__.py index daed1ca..0129224 100644 --- a/misp_modules/modules/expansion/__init__.py +++ b/misp_modules/modules/expansion/__init__.py @@ -1,3 +1,11 @@ from . import _vmray -__all__ = ['vmray_submit', 'asn_history', 'circl_passivedns', 'circl_passivessl', 'countrycode', 'cve', 'dns', 'btc_steroids', 'domaintools', 'eupi', 'farsight_passivedns', 'ipasn', 'passivetotal', 'sourcecache', 'virustotal', 'whois', 'shodan', 'reversedns', 'geoip_country', 'wiki', 'iprep', 'threatminer', 'otx', 'threatcrowd', 'vulndb', 'crowdstrike_falcon', 'yara_syntax_validator', 'hashdd', 'onyphe', 'onyphe_full', 'rbl', 'xforceexchange', 'sigma_syntax_validator', 'stix2_pattern_syntax_validator', 'sigma_queries', 'dbl_spamhaus', 'vulners', 'yara_query', 'macaddress_io'] +__all__ = ['vmray_submit', 'asn_history', 'circl_passivedns', 'circl_passivessl', + 'countrycode', 'cve', 'dns', 'btc_steroids', 'domaintools', 'eupi', + 'farsight_passivedns', 'ipasn', 'passivetotal', 'sourcecache', 'virustotal', + 'whois', 'shodan', 'reversedns', 'geoip_country', 'wiki', 'iprep', + 'threatminer', 'otx', 'threatcrowd', 'vulndb', 'crowdstrike_falcon', + 'yara_syntax_validator', 'hashdd', 'onyphe', 'onyphe_full', 'rbl', + 'xforceexchange', 'sigma_syntax_validator', 'stix2_pattern_syntax_validator', + 'sigma_queries', 'dbl_spamhaus', 'vulners', 'yara_query', 'macaddress_io', + 'intel471'] diff --git a/misp_modules/modules/expansion/intel471.py b/misp_modules/modules/expansion/intel471.py new file mode 100755 index 0000000..bf95b2e --- /dev/null +++ b/misp_modules/modules/expansion/intel471.py @@ -0,0 +1,61 @@ +import json +from pyintel471 import PyIntel471 + +misperrors = {'error': 'Error'} +mispattributes = {'input': ['hostname', 'domain', 'url', 'ip-src', 'ip-dst', 'email-src', + 'email-dst', 'target-email', 'whois-registrant-email', + 'whois-registrant-name', 'md5', 'sha1', 'sha256'], 'output': ['freetext']} +moduleinfo = {'version': '0.1', 'author': 'Raphaƫl Vinot', 'description': 'Module to access Intel 471', + 'module-type': ['hover', 'expansion']} +moduleconfig = ['email', 'authkey'] + + +def cleanup(response): + '''The entries have uids that will be recognised as hashes when they shouldn't''' + j = response.json() + if j['iocTotalCount'] == 0: + return 'Nothing has been found.' + for ioc in j['iocs']: + ioc.pop('uid') + if ioc['links']['actorTotalCount'] > 0: + for actor in ioc['links']['actors']: + actor.pop('uid') + if ioc['links']['reportTotalCount'] > 0: + for report in ioc['links']['reports']: + report.pop('uid') + return json.dumps(j, indent=2) + + +def handler(q=False): + if q is False: + return False + request = json.loads(q) + for input_type in mispattributes['input']: + if input_type in request: + to_query = request[input_type] + break + else: + misperrors['error'] = "Unsupported attributes type" + return misperrors + + if (request.get('config')): + if (request['config'].get('email') is None) or (request['config'].get('authkey') is None): + misperrors['error'] = 'Intel 471 authentication is missing' + return misperrors + + intel471 = PyIntel471(email=request['config'].get('email'), authkey=request['config'].get('authkey')) + ioc_filters = intel471.iocs_filters(ioc=to_query) + res = intel471.iocs(filters=ioc_filters) + to_return = cleanup(res) + + r = {'results': [{'types': mispattributes['output'], 'values': to_return}]} + return r + + +def introspection(): + return mispattributes + + +def version(): + moduleinfo['config'] = moduleconfig + return moduleinfo