mirror of
https://github.com/valitydev/Cortex-Analyzers.git
synced 2024-11-06 09:05:19 +00:00
Merge branch 'feature/122' into develop
This commit is contained in:
commit
6f36eb4575
16
analyzers/PayloadSecurity/PayloadSecurity_File_Analysis.json
Normal file
16
analyzers/PayloadSecurity/PayloadSecurity_File_Analysis.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "PayloadSecurity_File_Analysis",
|
||||
"version": "1.0",
|
||||
"author": "Emmanuel Torquato",
|
||||
"url": "https://github.com/notset/Cortex-Analyzers",
|
||||
"license": "AGPL-V3",
|
||||
"baseConfig": "PayloadSecurity",
|
||||
"config": {
|
||||
"check_tlp": true,
|
||||
"max_tlp": 3,
|
||||
"service": "file_analysis"
|
||||
},
|
||||
"description": "PayloadSecurity Sandbox File Analysis",
|
||||
"dataTypeList": ["file"],
|
||||
"command": "PayloadSecurity/payloadsecurity_analyzer.py"
|
||||
}
|
16
analyzers/PayloadSecurity/PayloadSecurity_Url_Analysis.json
Normal file
16
analyzers/PayloadSecurity/PayloadSecurity_Url_Analysis.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "PayloadSecurity_Url_Analysis",
|
||||
"version": "1.0",
|
||||
"author": "Emmanuel Torquato",
|
||||
"url": "https://github.com/notset/Cortex-Analyzers",
|
||||
"license": "AGPL-V3",
|
||||
"baseConfig": "PayloadSecurity",
|
||||
"config": {
|
||||
"check_tlp": true,
|
||||
"max_tlp": 3,
|
||||
"service": "url_analysis"
|
||||
},
|
||||
"description": "PayloadSecurity Sandbox Url Analysis",
|
||||
"dataTypeList": ["url"],
|
||||
"command": "PayloadSecurity/payloadsecurity_analyzer.py"
|
||||
}
|
181
analyzers/PayloadSecurity/payloadsecurity_analyzer.py
Executable file
181
analyzers/PayloadSecurity/payloadsecurity_analyzer.py
Executable file
@ -0,0 +1,181 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
from cortexutils.analyzer import Analyzer
|
||||
import requests
|
||||
from requests.auth import HTTPBasicAuth
|
||||
import time
|
||||
|
||||
|
||||
class PayloadSecurityAnalyzer(Analyzer):
|
||||
def __init__(self):
|
||||
Analyzer.__init__(self)
|
||||
self.service = self.getParam('config.service', None, 'PayloadSecurity service is missing')
|
||||
self.url = self.getParam('config.url', None, 'PayloadSecurity url is missing')
|
||||
self.apikey = self.getParam('config.key', None, 'PayloadSecurity apikey is missing')
|
||||
self.secret = self.getParam('config.secret', None, 'PayloadSecurity secret is missing')
|
||||
self.environmentid = self.getParam('config.environmentid', None, 'PayloadSecurity environmentid is missing')
|
||||
self.timeout = self.getParam('config.timeout', 15, None)
|
||||
self.verify = self.getParam('config.verifyssl', True, None)
|
||||
if not self.verify:
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
|
||||
def summary(self, raw):
|
||||
taxonomies = []
|
||||
level = "safe"
|
||||
namespace = "PayloadSecurity"
|
||||
predicate = "ThreatScore"
|
||||
value = "\"0/100\""
|
||||
|
||||
result = {
|
||||
'service': self.service,
|
||||
'dataType': self.data_type
|
||||
}
|
||||
result["verdict"] = raw.get("verdict", None)
|
||||
result["vxfamily"] = raw.get("vxfamily", None)
|
||||
result["threatscore"] = raw.get("threatscore", None)
|
||||
|
||||
if result["verdict"] == "malicious":
|
||||
level = "malicious"
|
||||
elif result["verdict"] == "suspicious":
|
||||
level = "suspicious"
|
||||
else:
|
||||
level = "safe"
|
||||
|
||||
if result.get("threatscore"):
|
||||
value = "\"{}/100\"".format(result["threatscore"])
|
||||
|
||||
taxonomies.append(self.build_taxonomy(level, namespace, predicate, value))
|
||||
|
||||
return {"taxonomies": taxonomies}
|
||||
|
||||
def run(self):
|
||||
Analyzer.run(self)
|
||||
|
||||
try:
|
||||
|
||||
user_agent = {'User-agent': 'Cortex Analyzer'}
|
||||
|
||||
# Submit Analysis
|
||||
# File
|
||||
if self.service in ['file_analysis']:
|
||||
data = {'environmentId': self.environmentid, 'comment': 'Submitted by Cortex'}
|
||||
filepath = self.getParam('file', None, 'File is missing')
|
||||
f = open(filepath, "rb")
|
||||
files = {"file": f}
|
||||
response = requests.post(self.url.strip('/') + '/api/submit', data=data, headers=user_agent,
|
||||
files=files, auth=HTTPBasicAuth(self.apikey, self.secret), verify=self.verify)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data['response_code'] == 0:
|
||||
if data.get('response'):
|
||||
if data['response'].get('sha256'):
|
||||
sha256 = data['response']['sha256']
|
||||
elif data['response_code'] != 0:
|
||||
if data.get('response'):
|
||||
if data['response'].get('error'):
|
||||
self.error(data['response']['error'])
|
||||
else:
|
||||
self.error('unknown error return by server')
|
||||
else:
|
||||
self.error('unknown error return by server')
|
||||
elif response.status_code == 400:
|
||||
self.error('File upload failed or unknown submission related error')
|
||||
elif response.status_code == 429:
|
||||
self.error('Your API key quota has been reached')
|
||||
else:
|
||||
self.error('Unknown Server Error')
|
||||
|
||||
# URL
|
||||
elif self.service == 'url_analysis':
|
||||
data = {'environmentId': self.environmentid, 'analyzeurl': self.getData(),
|
||||
'comment': 'Submitted by Cortex'}
|
||||
response = requests.post(self.url.strip('/') + '/api/submiturl', data=data, headers=user_agent,
|
||||
verify=self.verify, auth=HTTPBasicAuth(self.apikey, self.secret))
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data['response_code'] == 0:
|
||||
if data.get('response'):
|
||||
if data['response'].get('sha256'):
|
||||
sha256 = data['response']['sha256']
|
||||
elif data['response_code'] != 0:
|
||||
if data.get('response'):
|
||||
if data['response'].get('error'):
|
||||
self.error(data['response']['error'])
|
||||
else:
|
||||
self.error('unknown error return by server')
|
||||
else:
|
||||
self.error('Not expected answer received from server')
|
||||
elif response.status_code == 400:
|
||||
self.error('File upload failed or unknown submission related error')
|
||||
elif response.status_code == 429:
|
||||
self.error('Your API key quota has been reached')
|
||||
else:
|
||||
self.error('Unknown Server Error')
|
||||
|
||||
else:
|
||||
self.error('Unknown PayloadSecurity service error')
|
||||
|
||||
# Check analysis status
|
||||
stateUrl = self.url.strip('/') + '/api/state/' + sha256
|
||||
params = {'environmentId': self.environmentid}
|
||||
finished = False
|
||||
tries = 0
|
||||
while not finished and tries <= self.timeout:
|
||||
time.sleep(60)
|
||||
response = requests.get(stateUrl, headers=user_agent, params=params, verify=self.verify,
|
||||
auth=HTTPBasicAuth(self.apikey, self.secret))
|
||||
data = response.json()
|
||||
if data["response_code"] == 0 and data["response"]["state"] == 'SUCCESS':
|
||||
finished = True
|
||||
tries += 1
|
||||
if not finished:
|
||||
self.error('PayloadSecurity analysis timed out')
|
||||
|
||||
# Retrieve report summary
|
||||
report = {}
|
||||
summaryUrl = self.url.strip('/') + '/api/summary/' + sha256
|
||||
params = {'environmentId': self.environmentid, 'type': 'json'}
|
||||
response = requests.get(summaryUrl, headers=user_agent, params=params, verify=self.verify,
|
||||
auth=HTTPBasicAuth(self.apikey, self.secret))
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data['response_code'] == 0 and data.get('response'):
|
||||
report = data['response']
|
||||
report['reporturl'] = self.url.strip('/') + '/sample/' + sha256 + '?environmentId=' + str(
|
||||
self.environmentid)
|
||||
else:
|
||||
self.error('unknown error return by server')
|
||||
else:
|
||||
self.error('Unknown Server Error')
|
||||
|
||||
# Retrieve associated screenshots
|
||||
# Associated Sha256 can be different if submitted file is an archive
|
||||
if 'sha256' in report:
|
||||
sha256 = report['sha256']
|
||||
screenshotsUrl = self.url.strip('/') + '/api/sample-screenshots/' + sha256
|
||||
params = {'environmentId': self.environmentid, 'type': 'json'}
|
||||
response = requests.get(screenshotsUrl, headers=user_agent, params=params, verify=self.verify,
|
||||
auth=HTTPBasicAuth(self.apikey, self.secret))
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data['response_code'] == 0 and data.get('response') and data['response'].get('screenshots'):
|
||||
report['screenshots'] = data['response']['screenshots']
|
||||
else:
|
||||
self.error('unknown error return by server')
|
||||
else:
|
||||
self.error('Unknown Server Error')
|
||||
|
||||
if 'reporturl' in report:
|
||||
self.report(report)
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
self.error(e)
|
||||
|
||||
except Exception as e:
|
||||
self.unexpectedError(e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
PayloadSecurityAnalyzer().run()
|
111
thehive-templates/PayloadSecurity_File_Analysis_1_0/long.html
Normal file
111
thehive-templates/PayloadSecurity_File_Analysis_1_0/long.html
Normal file
@ -0,0 +1,111 @@
|
||||
<!-- General error -->
|
||||
<div class="panel panel-danger" ng-if="!success">
|
||||
<div class="panel-heading">
|
||||
<strong>{{(artifact.data || artifact.attachment.name) | fang}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{content.errorMessage}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-PayloadSecuritySandbox" ng-if="success">
|
||||
<style>
|
||||
.report-PayloadSecuritySandbox dl {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.smaller {
|
||||
width: 25%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<strong>PayloadSecurity File Report</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<h4>File information</h4>
|
||||
<br>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Analysis Date</dt>
|
||||
<dd>{{content.analysis_start_time}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Submit Name</dt>
|
||||
<dd><a ng-href={{content.reporturl}}>{{content.submitname}}</a></dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>File Hash</dt>
|
||||
<dd>{{content.sha256}}</dd>
|
||||
</dl>
|
||||
<div ng-if="content.classification_tags && content.classification_tags.length > 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Tagged as</dt>
|
||||
<dd><li ng-repeat="tag in ::content.classification_tags">{{tag}}</li></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>File Type</dt>
|
||||
<dd>{{content.type}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Threat Score</dt>
|
||||
<dd>
|
||||
<span ng-class="{'label-info': content.threatscore<=50, 'label-warning': content.threatscore>50 && content.threatscore<=70, 'label-danger': content.threatscore >70}">
|
||||
{{content.threatscore}}
|
||||
</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Verdict</dt>
|
||||
<dd>{{content.verdict}}</dd>
|
||||
</dl>
|
||||
<div ng-if="content.vxfamily && content.vxfamily != null">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Malware Family</dt>
|
||||
<dd>{{content.vxfamily}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Total Signatures</dt>
|
||||
<dd>{{content.total_signatures}}</dd>
|
||||
</dl>
|
||||
<div ng-if="content.avdetect && content.avdetect != null">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>AV Detect</dt>
|
||||
<dd>{{content.avdetect}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div ng-if="content.targeturl && content.targeturl != null">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Target Url</dt>
|
||||
<dd>{{content.targeturl}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div ng-if="content.hosts && content.hosts.length > 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Contacted Host</dt>
|
||||
<dd><li ng-repeat="host in ::content.hosts">{{host}}</li></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div ng-if="content.domains && content.domains.length > 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Dns Requests</dt>
|
||||
<dd><li ng-repeat="domain in ::content.domains">{{domain}}</li></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="content.screenshots && content.screenshots.length > 0">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<strong>Screenshots</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal" ng-repeat="screenshot in content.screenshots track by $index">
|
||||
<dt>{{screenshot.name}}</dt>
|
||||
<dd><img class="img-responsive smaller" ng-src="data:image/JPEG;base64,{{screenshot.image}}"></dd>
|
||||
<br>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
107
thehive-templates/PayloadSecurity_Url_Analysis_1_0/long.html
Normal file
107
thehive-templates/PayloadSecurity_Url_Analysis_1_0/long.html
Normal file
@ -0,0 +1,107 @@
|
||||
<!-- General error -->
|
||||
<div class="panel panel-danger" ng-if="!success">
|
||||
<div class="panel-heading">
|
||||
<strong>{{(artifact.data || artifact.attachment.name) | fang}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{content.errorMessage}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-PayloadSecuritySandbox" ng-if="success">
|
||||
<style>
|
||||
.report-PayloadSecuritySandbox dl {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.smaller {
|
||||
width: 25%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<strong>PayloadSecurity Url Report</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<h4>Url information</h4>
|
||||
<br>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Analysis Date</dt>
|
||||
<dd>{{content.analysis_start_time}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Submit Name</dt>
|
||||
<dd><a ng-href={{content.reporturl}}>{{content.submitname}}</a></dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Url Hash</dt>
|
||||
<dd>{{content.sha256}}</dd>
|
||||
</dl>
|
||||
<div ng-if="content.classification_tags && content.classification_tags.length > 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Tagged as</dt>
|
||||
<dd><li ng-repeat="tag in ::content.classification_tags">{{tag}}</li></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Threat Score</dt>
|
||||
<dd>
|
||||
<span ng-class="{'label-info': content.threatscore<=50, 'label-warning': content.threatscore>50 && content.threatscore<=70, 'label-danger': content.threatscore >70}">
|
||||
{{content.threatscore}}
|
||||
</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Verdict</dt>
|
||||
<dd>{{content.verdict}}</dd>
|
||||
</dl>
|
||||
<div ng-if="content.vxfamily && content.vxfamily != null">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Malware Family</dt>
|
||||
<dd>{{content.vxfamily}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Total Signatures</dt>
|
||||
<dd>{{content.total_signatures}}</dd>
|
||||
</dl>
|
||||
<div ng-if="content.avdetect && content.avdetect != null">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>AV Detect</dt>
|
||||
<dd>{{content.avdetect}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div ng-if="content.targeturl && content.targeturl != null">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Target Url</dt>
|
||||
<dd>{{content.targeturl}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div ng-if="content.hosts && content.hosts.length > 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Contacted Host</dt>
|
||||
<dd><li ng-repeat="host in ::content.hosts">{{host}}</li></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div ng-if="content.domains && content.domains.length > 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Dns Requests</dt>
|
||||
<dd><li ng-repeat="domain in ::content.domains">{{domain}}</li></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="content.screenshots && content.screenshots.length > 0">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<strong>Screenshots</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal" ng-repeat="screenshot in content.screenshots track by $index">
|
||||
<dt>{{screenshot.name}}</dt>
|
||||
<dd><img class="img-responsive smaller" ng-src="data:image/JPEG;base64,{{screenshot.image}}"></dd>
|
||||
<br>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user