Skip to content

Commit

Permalink
Merge pull request #512 from LDO-CERT/joesandbox_new
Browse files Browse the repository at this point in the history
updated joesandbox analyzer
  • Loading branch information
3c7 authored Nov 16, 2019
2 parents e84e037 + 730816b commit 40145ac
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 158 deletions.
209 changes: 51 additions & 158 deletions analyzers/JoeSandbox/joesandbox_analyzer.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# encoding: utf-8

from cortexutils.analyzer import Analyzer

import os.path
import io
import requests
import time
import json
from jbxapi import JoeSandbox


class JoeSandboxAnalyzer(Analyzer):

def __init__(self):
Analyzer.__init__(self)
self.service = self.get_param('config.service', None, 'JoeSandbox service is missing')
self.url = self.get_param('config.url', None, 'JoeSandbox url is missing')
if self.get_param('config.key'):
self.apikey = self.get_param('config.key')
self.url = self.get_param("config.url", None, "JoeSandbox url is missing")
if self.get_param("config.key"):
apikey = self.get_param("config.key")
else:
self.apikey = self.get_param('config.apikey', None, 'JoeSandbox API key is missing')
self.analysistimeout = self.get_param('config.analysistimeout', 30*60, None)
self.networktimeout = self.get_param('config.networktimeout', 30, None)
apikey = self.get_param(
"config.apikey", None, "JoeSandbox API key is missing"
)
self.service = self.get_param(
"config.service", None, "JoeSandbox service is missing"
)
self.analysistimeout = self.get_param("config.analysistimeout", 30 * 60, None)
self.networktimeout = self.get_param("config.networktimeout", 30, None)
self.joe = JoeSandbox(apikey, self.url, verify_ssl=False)

def summary(self, raw):
result = {
'service': self.service,
'dataType': self.data_type
}

taxonomies = []
namespace = "JSB"
predicate = "Report"

r = raw['detection']
r = raw["detection"]

value = "{}/{}".format(r["score"], r["maxscore"])

Expand All @@ -46,166 +47,58 @@ def summary(self, raw):
value = "Unknown"

taxonomies.append(self.build_taxonomy(level, namespace, predicate, value))
result.update({"taxonomies": taxonomies})
return {"taxonomies": taxonomies}

return result

def runv1(self):
data = {
'apikey': self.apikey,
'tandc': 1,
'auto': 1,
'comments': 'Submitted by Cortex'
}
files = {}
def run(self):
Analyzer.run(self)

# file analysis with internet access
if self.service == 'file_analysis_inet':
extension = os.path.splitext(self.get_param('filename', ''))[1]
filepath = self.get_param('file', None, 'File is missing')
files['sample'] = (filepath + extension, open(filepath, 'rb'))
data['type'] = 'file'
data['inet'] = 1

# file analysis without internet access
elif self.service == 'file_analysis_noinet':
extension = os.path.splitext(self.get_param('filename', ''))[1]
filepath = self.get_param('file', None, 'File is missing')
files['sample'] = (filepath + extension, open(filepath, 'rb'))
data['type'] = 'file'
data['inet'] = 0

if self.service == "file_analysis_inet":
filename = self.get_param("filename", "")
filepath = self.get_param("file", "")
response = self.joe.submit_sample((filename, open(filepath, "rb")))
elif self.service == "file_analysis_noinet":
filename = self.get_param("filename", "")
filepath = self.get_param("file", "")
response = self.joe.submit_sample(
(filename, open(filepath, "rb")), params={"internet-access": False}
)
# url analysis
elif self.service == 'url_analysis':
data['url'] = self.get_data()
data['type'] = 'url'
data['inet'] = 1
elif self.service == "url_analysis":
response = self.joe.submit_url(self.get_data())

else:
self.error('Unknown JoeSandbox service')
self.error("Unknown JoeSandbox service")

# Submit the file/url for analysis
response = requests.post(self.url + 'api/analysis', files=files, data=data, timeout=self.networktimeout)
webid = response.json()['webid']
submission_id = response["submission_id"]

# Wait for the analysis to finish
data = {
'apikey': self.apikey,
'webid': webid
}
finished = False
tries = 0
while not finished and tries <= self.analysistimeout/60:
while not finished and tries <= self.analysistimeout / 60:
time.sleep(60)
response = requests.post(self.url + 'api/analysis/check', data=data, timeout=self.networktimeout)
content = response.json()
if content['status'] == 'finished':
response = self.joe.submission_info(submission_id)
webid = response["analyses"][0]["webid"]
if response["status"] == "finished":
finished = True
tries += 1
if not finished:
self.error('JoeSandbox analysis timed out')

self.error("JoeSandbox analysis timed out")
# Download the report
data = {
'apikey': self.apikey,
'webid': webid,
'type': 'irjsonfixed',
'run': 0
}
response = requests.post(self.url + 'api/analysis/download', data=data, timeout=self.networktimeout)
analysis = response.json()['analysis']
analysis['htmlreport'] = self.url + 'analysis/' + str(analysis['id']) + '/0/html'
analysis['pdfreport'] = self.url + 'analysis/' + str(analysis['id']) + '/0/pdf'
self.report(analysis)

def runv2(self):
data = {
'apikey': self.apikey,
'accept-tac': '1',
'systems': None,
'comments': 'Submitted by Cortex'
}
files = {}

# file analysis with internet access
if self.service == 'file_analysis_inet':
extension = os.path.splitext(self.get_param('filename', ''))[1]
filepath = self.get_param('file', None, 'File is missing')
files['sample'] = (filepath + extension, open(filepath, 'rb'))
data['internet-access'] = '1'

# file analysis without internet access
elif self.service == 'file_analysis_noinet':
extension = os.path.splitext(self.get_param('filename', ''))[1]
filepath = self.get_param('file', None, 'File is missing')
files['sample'] = (filepath + extension, open(filepath, 'rb'))
data['internet-access'] = '0'

# url analysis
elif self.service == 'url_analysis':
data['url'] = self.get_data()
data['internet-access'] = '1'

response = self.joe.analysis_download(webid, "irjsonfixed", run=0)
analysis = json.loads(response[1].decode("utf-8")).get("analysis", None)
if analysis:
analysis["htmlreport"] = (
self.url + "analysis/" + str(analysis["id"]) + "/0/html"
)
analysis["pdfreport"] = (
self.url + "analysis/" + str(analysis["id"]) + "/0/pdf"
)
self.report(analysis)
else:
self.error('Unknown JoeSandbox service')

# Submit the file/url for analysis
response = requests.post(self.url + 'api/v2/analysis/submit',
files=files,
data=data,
timeout=self.networktimeout)
webid = response.json()['data']['webids'][0]
self.error("Invalid output")

# Wait for the analysis to finish
data = {
'apikey': self.apikey,
'webid': webid
}
finished = False
tries = 0
while not finished and tries <= self.analysistimeout/60:
time.sleep(60)
response = requests.post(self.url + 'api/v2/analysis/info', data=data, timeout=self.networktimeout)
content = response.json()
if content['data']['status'] == 'finished':
finished = True
tries += 1
if not finished:
self.error('JoeSandbox analysis timed out')

# Download the report
data = {
'apikey': self.apikey,
'webid': webid,
'type': 'irjsonfixed',
'run': 0
}
response = requests.post(self.url + 'api/v2/analysis/download', data=data, timeout=self.networktimeout)
analysis = response.json()['analysis']
analysis['htmlreport'] = self.url + 'analysis/' + str(analysis['id']) + '/0/html'
analysis['pdfreport'] = self.url + 'analysis/' + str(analysis['id']) + '/0/pdf'
self.report(analysis)

def run(self):
Analyzer.run(self)

try:
data = {
'apikey': self.apikey
}
# Check whether API v2 is supported or not
response = requests.post(self.url + 'api/v2/server/online',
data=data,
timeout=self.networktimeout,
allow_redirects=False)
if response.status_code == 200:
self.runv2()
else:
self.runv1()

except Exception as e:
self.unexpectedError(e)


if __name__ == '__main__':
if __name__ == "__main__":
JoeSandboxAnalyzer().run()
1 change: 1 addition & 0 deletions analyzers/JoeSandbox/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
cortexutils
requests
jbxapi==3.2.0

0 comments on commit 40145ac

Please sign in to comment.