2019-06-04 01:48:50 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import jbxapi
|
|
|
|
import json
|
|
|
|
from joe_parser import JoeParser
|
|
|
|
|
|
|
|
misperrors = {'error': 'Error'}
|
|
|
|
|
2020-01-24 14:51:10 +01:00
|
|
|
inputSource = ['link']
|
|
|
|
|
|
|
|
moduleinfo = {'version': '0.2', 'author': 'Christian Studer',
|
2019-06-04 01:48:50 +02:00
|
|
|
'description': 'Query Joe Sandbox API with a report URL to get the parsed data.',
|
|
|
|
'module-type': ['expansion']}
|
2020-01-24 14:51:10 +01:00
|
|
|
moduleconfig = ['apiurl', 'apikey', 'import_pe', 'import_mitre_attack']
|
2019-06-04 01:48:50 +02:00
|
|
|
|
|
|
|
|
|
|
|
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')
|
2020-01-24 14:51:10 +01:00
|
|
|
parser_config = {
|
|
|
|
"import_pe": request["config"].get('import_pe', "false") == "true",
|
|
|
|
"mitre_attack": request["config"].get('import_mitre_attack', "false") == "true",
|
|
|
|
}
|
|
|
|
|
2019-06-04 01:48:50 +02:00
|
|
|
if not apikey:
|
|
|
|
return {'error': 'No API key provided'}
|
2019-06-04 11:29:40 +02:00
|
|
|
|
|
|
|
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')
|
|
|
|
|
2019-06-04 01:48:50 +02:00
|
|
|
try:
|
2019-06-04 11:29:40 +02:00
|
|
|
joe_info = joe.submission_info(submission_id)
|
|
|
|
except jbxapi.ApiError as e:
|
2019-06-04 01:48:50 +02:00
|
|
|
return {'error': str(e)}
|
2019-06-04 11:29:40 +02:00
|
|
|
|
|
|
|
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']
|
|
|
|
|
2020-01-24 14:51:10 +01:00
|
|
|
joe_parser = JoeParser(parser_config)
|
2019-06-04 11:29:40 +02:00
|
|
|
joe_data = json.loads(joe.analysis_download(analysis_webid, 'jsonfixed')[1])
|
|
|
|
joe_parser.parse_data(joe_data['analysis'])
|
2019-06-04 01:48:50 +02:00
|
|
|
joe_parser.finalize_results()
|
2019-06-04 11:29:40 +02:00
|
|
|
|
2019-06-04 01:48:50 +02:00
|
|
|
return {'results': joe_parser.results}
|
|
|
|
|
|
|
|
|
|
|
|
def introspection():
|
2020-01-24 14:51:10 +01:00
|
|
|
modulesetup = {}
|
|
|
|
try:
|
|
|
|
userConfig
|
|
|
|
modulesetup['userConfig'] = userConfig
|
|
|
|
except NameError:
|
|
|
|
pass
|
|
|
|
try:
|
|
|
|
inputSource
|
|
|
|
modulesetup['input'] = inputSource
|
|
|
|
except NameError:
|
|
|
|
pass
|
|
|
|
modulesetup['format'] = 'misp_standard'
|
|
|
|
return modulesetup
|
2019-06-04 01:48:50 +02:00
|
|
|
|
2019-06-04 03:33:42 +02:00
|
|
|
|
2019-06-04 01:48:50 +02:00
|
|
|
def version():
|
|
|
|
moduleinfo['config'] = moduleconfig
|
|
|
|
return moduleinfo
|