|
|
|
@ -9,21 +9,7 @@ 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)) |
|
|
|
|
moduleconfig = ['apiurl', 'apikey'] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def handler(q=False): |
|
|
|
@ -34,21 +20,32 @@ def handler(q=False): |
|
|
|
|
apikey = request['config'].get('apikey') |
|
|
|
|
if not apikey: |
|
|
|
|
return {'error': 'No API key provided'} |
|
|
|
|
|
|
|
|
|
url = request['attribute']['value'] |
|
|
|
|
if "/submissions/" not in url: |
|
|
|
|
return {'error': "The URL does not point to a Joe Sandbox analysis."} |
|
|
|
|
|
|
|
|
|
submission_id = url.split('/')[-1] # The URL has the format https://example.net/submissions/12345 |
|
|
|
|
joe = jbxapi.JoeSandbox(apiurl=apiurl, apikey=apikey, user_agent='MISP joesandbox_query') |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
accept_tac = _parse_bool(request['config'].get('accept-tac'), 'accept-tac') |
|
|
|
|
except _ParseError as e: |
|
|
|
|
joe_info = joe.submission_info(submission_id) |
|
|
|
|
except jbxapi.ApiError 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]) |
|
|
|
|
|
|
|
|
|
if joe_info["status"] != "finished": |
|
|
|
|
return {'error': "The analysis has not finished yet."} |
|
|
|
|
|
|
|
|
|
if joe_info['most_relevant_analysis'] is None: |
|
|
|
|
return {'error': "No analysis belongs to this submission."} |
|
|
|
|
|
|
|
|
|
analysis_webid = joe_info['most_relevant_analysis']['webid'] |
|
|
|
|
|
|
|
|
|
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_data = json.loads(joe.analysis_download(analysis_webid, 'jsonfixed')[1]) |
|
|
|
|
joe_parser.parse_data(joe_data['analysis']) |
|
|
|
|
joe_parser.finalize_results() |
|
|
|
|
|
|
|
|
|
return {'results': joe_parser.results} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|