diff --git a/misp_modules/modules/expansion/__init__.py b/misp_modules/modules/expansion/__init__.py index ba10b32..f64600a 100644 --- a/misp_modules/modules/expansion/__init__.py +++ b/misp_modules/modules/expansion/__init__.py @@ -10,4 +10,4 @@ __all__ = ['cuckoo_submit', 'vmray_submit', 'bgpranking', 'circl_passivedns', 'c 'sigma_queries', 'dbl_spamhaus', 'vulners', 'yara_query', 'macaddress_io', 'intel471', 'backscatter_io', 'btc_scam_check', 'hibp', 'greynoise', 'macvendors', 'qrcode', 'ocr-enrich', 'pdf-enrich', 'docx-enrich', 'xlsx-enrich', 'pptx-enrich', - 'ods-enrich', 'odt-enrich', 'joesandbox_submit', 'urlhaus'] + 'ods-enrich', 'odt-enrich', 'joesandbox_submit', 'joesandbox_query', 'urlhaus'] diff --git a/misp_modules/modules/expansion/joesandbox_query.py b/misp_modules/modules/expansion/joesandbox_query.py new file mode 100644 index 0000000..ea58cb6 --- /dev/null +++ b/misp_modules/modules/expansion/joesandbox_query.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +import jbxapi +import json +import os +import sys +sys.path.append('{}/lib'.format('/'.join((os.path.realpath(__file__)).split('/')[:-3]))) +from joe_parser import JoeParser + +misperrors = {'error': 'Error'} +mispattributes = {'input': ['link'], 'format': 'misp_standard'} + +moduleinfo = {'version': '0.1', 'author': 'Christian Studer', + 'description': 'Query Joe Sandbox API with a report URL to get the parsed data.', + 'module-type': ['expansion']} +moduleconfig = ['apiurl', 'apikey', 'accept-tac'] + + +class _ParseError(Exception): + pass + + +def _parse_bool(value, name="bool"): + if value is None or value == "": + return None + if value in ("true", "True"): + return True + if value in ("false", "False"): + return False + raise _ParseError("Cannot parse {}. Must be 'true' or 'false'".format(name)) + + +def handler(q=False): + if q is False: + return False + request = json.loads(q) + apiurl = request['config'].get('apiurl') or 'https://jbxcloud.joesecurity.org/api' + apikey = request['config'].get('apikey') + if not apikey: + return {'error': 'No API key provided'} + try: + accept_tac = _parse_bool(request['config'].get('accept-tac'), 'accept-tac') + except _parseError as e: + return {'error': str(e)} + attribute = request['attribute'] + joe = jbxapi.JoeSandbox(apiurl=apiurl, apikey=apikey, user_agent='MISP joesandbox_analysis', accept_tac=accept_tac) + joe_info = joe.submission_info(attribute['value'].split('/')[-1]) + joe_parser = JoeParser() + most_relevant = joe_info['most_relevant_analysis']['webid'] + for analyse in joe_info['analyses']: + if analyse['webid'] == most_relevant: + joe_data = json.loads(joe.analysis_download(most_relevant, 'jsonfixed')[1]) + joe_parser.parse_data(joe_data['analysis']) + break + joe_parser.finalize_results() + return {'results': joe_parser.results} + + +def introspection(): + return mispattributes + +def version(): + moduleinfo['config'] = moduleconfig + return moduleinfo