Skip to content

Commit

Permalink
Merge pull request #50 from garanews/master
Browse files Browse the repository at this point in the history
Cuckoo Sandbox Analyzer
  • Loading branch information
jeromeleonard authored Jul 5, 2017
2 parents 0705cd6 + 3a53525 commit 0efec83
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 0 deletions.
15 changes: 15 additions & 0 deletions analyzers/CuckooSandbox/CuckooSandbox_File_Analysis_Inet.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "CuckooSandbox_File_Analysis_Inet",
"version": "1.0",
"author": "Andrea Garavaglia, LDO-CERT",
"url": "https://github.com/garanews/Cortex-Analyzers",
"license": "AGPL-V3",
"baseConfig": "CuckooSandbox",
"config": {
"check_tlp": false,
"service": "file_analysis_inet"
},
"description": "Cuckoo Sandbox file analysis with Internet access",
"dataTypeList": ["file"],
"command": "CuckooSandbox/cuckoosandbox_analyzer.py"
}
15 changes: 15 additions & 0 deletions analyzers/CuckooSandbox/CuckooSandbox_Url_Analysis.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "CuckooSandbox_Url_Analysis",
"version": "1.0",
"author": "Andrea Garavaglia, LDO-CERT",
"url": "https://github.com/garanews/Cortex-Analyzers",
"license": "AGPL-V3",
"baseConfig": "CuckooSandbox",
"config": {
"check_tlp": false,
"service": "url_analysis"
},
"description": "Cuckoo Sandbox url analysis",
"dataTypeList": ["url"],
"command": "CuckooSandbox/cuckoosandbox_analyzer.py"
}
104 changes: 104 additions & 0 deletions analyzers/CuckooSandbox/cuckoosandbox_analyzer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/usr/bin/env python
# encoding: utf-8

from cortexutils.analyzer import Analyzer

import requests
import time
from os.path import basename

class CuckooSandboxAnalyzer(Analyzer):

def __init__(self):
Analyzer.__init__(self)
self.service = self.getParam('config.service', None, 'CuckooSandbox service is missing')
self.url = self.getParam('config.url', None, 'CuckooSandbox url is missing')
#self.analysistimeout = self.getParam('config.analysistimeout', 30*60, None)
#self.networktimeout = self.getParam('config.networktimeout', 30, None)

def summary(self, raw):
result = {
'service': self.service,
'dataType': self.data_type
}
result["malscore"] = raw.get("malscore", None)
result["malfamily"] = raw.get("malfamily", None)
return result

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

try:

# file analysis
if self.service in ['file_analysis_inet', 'file_analysis_noinet']:
filepath = self.getParam('file', None, 'File is missing')
filename = basename(filepath)
with open(filepath, "rb") as sample:
files = {"file": (filename, sample)}
response = requests.post(self.url + 'tasks/create/file', files=files)
task_id = response.json()['task_ids'][0]

# url analysis
elif self.service == 'url_analysis':
data = {"url": self.getData()}
response = requests.post(self.url + 'tasks/create/url', data=data)
task_id = response.json()['task_id']

else:
self.error('Unknown CuckooSandbox service')

finished = False
tries = 0
while not finished and tries <= 15: #wait max 15 mins
time.sleep(60)
response = requests.get(self.url + 'tasks/view/' + str(task_id))
content = response.json()['task']['status']
if content == 'reported':
finished = True
tries += 1
if not finished:
self.error('CuckooSandbox analysis timed out')

# Download the report
response = requests.get(self.url + 'tasks/report/' + str(task_id) + '/json')
resp_json = response.json()
list_description = [x['description'] for x in resp_json['signatures']]
if 'suricata' in resp_json.keys() and 'alerts' in resp_json['suricata'].keys():
suri_alerts = [(x['signature'],x['dstip'],x['dstport'],x['severity']) for x in resp_json['suricata']['alerts']]
else:
suri_alerts = []
hosts = [(x['ip'],x['hostname'],x['country_name']) for x in resp_json['network']['hosts']]
uri = [(x['uri']) for x in resp_json['network']['http']]
if self.service == 'url_analysis':
self.report({
'signatures': list_description,
'suricata_alerts': suri_alerts,
'hosts': hosts,
'uri': uri,
'malscore': resp_json['malscore'],
'malfamily': resp_json['malfamily'],
'file_type': 'url',
'yara': resp_json['target']['url'] if 'target' in resp_json.keys() and 'url' in resp_json['target'].keys() else '-'
})
else:
self.report({
'signatures': list_description,
'suricata_alerts': suri_alerts,
'hosts': hosts,
'uri': uri,
'malscore': resp_json['malscore'],
'malfamily': resp_json['malfamily'],
'file_type': "".join([x for x in resp_json['target']['file']['type']]),
'yara': [ x['name'] + " - " + x['meta']['description'] if 'description' in x['meta'].keys() else x['name'] for x in resp_json['target']['file']['yara'] ]
})

except requests.exceptions.RequestException as e:
self.error(e)

except Exception as e:
self.unexpectedError(e)

if __name__ == '__main__':
CuckooSandboxAnalyzer().run()

2 changes: 2 additions & 0 deletions analyzers/CuckooSandbox/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cortexutils
requests
148 changes: 148 additions & 0 deletions thehive-templates/CuckooSandbox_File_Analysis_Inet_1_0/long.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<div class="report-CuckooSandbox" ng-if="success">
<style>
.report-CuckooSandbox dl {
margin-bottom: 2px;
}
</style>

<div class="panel panel-info">
<div class="panel-heading">
<strong>General Information</strong>
</div>
<div class="panel-body">

<h4>File information</h4>
<br>
<dl class="dl-horizontal">
<dt>FileType</dt>
<dd>{{content.file_type}}</dd>
</dl>

<dl class="dl-horizontal">
<dt>Malfamily</dt>
<dd>{{content.malfamily}}</dd>
</dl>

<dl class="dl-horizontal">
<dt>Malscore</dt>
<dd>
<span ng-class="{'label-info': content.malscore<=2, 'label-warning': content.malscore>2 && content.malscore<=6.5, 'label-danger': content.malscore >6.5}">
{{content.malscore}}
</span>
</dd>
</dl>
</div>
</div>

<div class="panel panel-info">
<div class="panel-heading">
<strong>Analysis</strong>
</div>
<div class="panel-body">

<div ng-if="content.signatures">
<h4>Signatures</h4>
<br>
<dl class="dl-horizontal" ng-repeat="signature in content.signatures track by $index">
<dd>{{ signature }}<dd>
</dl>
</div>
<div ng-if="!content.signatures">
No suspicious signature reported
</div>
</div>
</div>

<div class="panel panel-info">
<div class="panel-heading">
<strong>Analysis</strong>
</div>
<div class="panel-body">

<div ng-if="content.hosts">
<h4>Remote connections</h4>
<br>
<div>
<table class="table table-hover">
<tr>
<th>Domain</th>
<th>IP</th>
<th>Location</th>
</tr>
<tr ng-repeat="host in content.hosts track by $index">
<td>{{host[1]}}</td>
<td>{{host[0]}}</td>
<td>{{host[2]}}</td>
</tr>
</table>
</div>
</div>

<br/>
<hr>
<br/>

<div ng-if="content.uri">
<h4>URI</h4>
<br>
<dl class="dl-horizontal" ng-repeat="uri in content.uri track by $index">
<dd>{{ uri }}<dd>
</dl>
</div>
<div ng-if="!content.uri">
No suspicious uri reported
</div>

</div>
</div>

<div class="panel panel-info">
<div class="panel-heading">
<strong>Yara</strong>
</div>
<div class="panel-body">

<div ng-if="content.yara">
<h4>Yara</h4>
<br>
<dl class="dl-horizontal" ng-repeat="yara in content.yara track by $index">
<dd>{{ yara }}<dd>
</dl>
</div>
<div ng-if="!content.yara">
No suspicious activity reported
</div>

</div>
</div>

<div class="panel panel-info">
<div class="panel-heading">
<strong>Suricata</strong>
</div>
<div class="panel-body">

<div ng-if="content.suricata_alerts">
<h4>Suricata Alerts</h4>
<br>
<dl class="dl-horizontal" ng-repeat="suri in content.suri track by $index">
<dd>{{ suri }}<dd>
</dl>
</div>
<div ng-if="!content.suri">
No suspicious suricata alerts reported
</div>
</div>
</div>
</div>


<!-- 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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<span class="label" ng-class="{'label-info': content.malscore<=2, 'label-warning': content.malscore>2 && content.malscore<=6.5, 'label-danger': content.malscore >6.5}">
Cuckoo Sandbox=
<span ng-if="content.malscore">CSB:Malscore={{content.malscore}}</span>
<span ng-if="content.malfamily">CSB:Malfamily=[{{ content.malfamily}}]</span>
</span>

0 comments on commit 0efec83

Please sign in to comment.