-
Notifications
You must be signed in to change notification settings - Fork 385
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
796 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,5 @@ thehive-templates/*.sh | |
|
||
.idea | ||
.DS_Store | ||
|
||
Cortex-analyzers.iml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"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": true, | ||
"max_tlp":1, | ||
"service": "file_analysis" | ||
}, | ||
"description": "Cuckoo Sandbox file analysis with Internet access", | ||
"dataTypeList": ["file"], | ||
"command": "CuckooSandbox/cuckoosandbox_analyzer.py" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"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": true, | ||
"max_tlp":1, | ||
"service": "url_analysis" | ||
}, | ||
"description": "Cuckoo Sandbox URL analysis", | ||
"dataTypeList": ["url"], | ||
"command": "CuckooSandbox/cuckoosandbox_analyzer.py" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
#!/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): | ||
taxonomies = [] | ||
level = "safe" | ||
namespace = "Cuckoo" | ||
predicate = "Malscore" | ||
value = "\"0\"" | ||
|
||
result = { | ||
'service': self.service, | ||
'dataType': self.data_type | ||
} | ||
result["malscore"] = raw.get("malscore", None) | ||
result["malfamily"] = raw.get("malfamily", None) | ||
|
||
if result["malscore"] > 6.5: | ||
level = "malicious" | ||
elif result["malscore"] > 2: | ||
level = "suspicious" | ||
elif result["malscore"] > 0: | ||
level = "safe" | ||
|
||
taxonomies.append(self.build_taxonomy(level, namespace, predicate, "\"{}\"".format(result["malscore"]))) | ||
taxonomies.append(self.build_taxonomy(level, namespace, "Malfamily", "\"{}\"".format(result["malfamily"]))) | ||
|
||
return {"taxonomies": taxonomies} | ||
|
||
def run(self): | ||
Analyzer.run(self) | ||
|
||
try: | ||
|
||
# file analysis | ||
if self.service in ['file_analysis']: | ||
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() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
cortexutils | ||
requests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"name": "WOT_Lookup", | ||
"version": "1.0", | ||
"author": "Andrea Garavaglia - LDO-CERT", | ||
"url": "https://github.com/garanews/Cortex-Analyzers", | ||
"license": "AGPL-V3", | ||
"description": "Check a Domain against Web of Trust (WOT) a website reputation service", | ||
"dataTypeList": ["domain", "fqdn"], | ||
"baseConfig": "WOT", | ||
"config": { | ||
"check_tlp": true, | ||
"max_tlp": 1, | ||
"service": "query" | ||
}, | ||
"command": "WOT/WOT_lookup.py" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
#!/usr/bin/env python | ||
# encoding: utf-8 | ||
|
||
import json | ||
import requests | ||
import datetime | ||
from cortexutils.analyzer import Analyzer | ||
|
||
class WOTAnalyzer(Analyzer): | ||
|
||
def __init__(self): | ||
Analyzer.__init__(self) | ||
self.service = self.getParam( | ||
'config.service', None, 'Service parameter is missing') | ||
self.WOT_key = self.getParam('config.key', None, | ||
'Missing WOT API key') | ||
self.categories = { | ||
"101": "Malware or viruses", | ||
"102": "Poor customer experience", | ||
"103": "Phishing", | ||
"104": "Scam", | ||
"105": "Potentially illegal", | ||
"201": "Misleading claims or unethical", | ||
"202": "Privacy risks", | ||
"203": "Suspicious", | ||
"204": "Hate, discrimination", | ||
"205": "Spam", | ||
"206": "Potentially unwanted programs", | ||
"207": "Ads / pop-ups", | ||
"301": "Online tracking", | ||
"302": "Alternative or controversial medicine", | ||
"303": "Opinions, religion, politics", | ||
"304": "Other", | ||
"401": "Adult content", | ||
"402": "Incidental nudity", | ||
"403": "Gruesome or shocking", | ||
"404": "Site for kids", | ||
"501": "Good site" | ||
} | ||
|
||
def points_to_verbose(self, points): | ||
if points >= 80: | ||
return "Excellent" | ||
elif points >= 60: | ||
return "Good" | ||
elif points >= 40: | ||
return "Unsatisfactory" | ||
elif points >= 20: | ||
return "Poor" | ||
else: | ||
return "Very poor" | ||
|
||
def WOT_checkurl(self, data): | ||
url = 'http://api.mywot.com/0.4/public_link_json2?hosts=' + data + '/&callback=process&key=' + self.WOT_key | ||
r = requests.get(url) | ||
return json.loads(r.text.replace("process(","").replace(")","")) | ||
|
||
def summary(self, raw): | ||
taxonomies = [] | ||
level = "safe" | ||
value = "-" | ||
|
||
categories = raw.get("Categories", None) | ||
blacklists = raw.get("Blacklists", None) | ||
num_categories = raw.get("Categories Identifier", None) | ||
|
||
if categories: | ||
value = "|".join(categories) | ||
if blacklists: | ||
value = "|".join([x[0] for x in blacklists]) | ||
level = "malicious" | ||
else: | ||
if num_categories: | ||
min_cat = min([int(x) for x in num_categories]) | ||
else: | ||
min_cat = 501 | ||
if min_cat > 300: | ||
level = "safe" | ||
elif min_cat > 200: | ||
level = "suspicious" | ||
else: | ||
level = "malicious" | ||
|
||
taxonomies.append(self.build_taxonomy(level, "WOT", "Category", "\"{}\"".format(value))) | ||
return {"taxonomies": taxonomies} | ||
|
||
def run(self): | ||
if self.service == 'query': | ||
if self.data_type in ['domain', 'fqdn']: | ||
data = self.getParam('data', None, 'Data is missing') | ||
r = self.WOT_checkurl(data) | ||
if data in r.keys(): | ||
info = r[data] | ||
r_dict = {} | ||
if '0' in info.keys(): | ||
r_dict['Trustworthiness'] = {} | ||
r_dict['Trustworthiness']['Reputation'] = self.points_to_verbose(info['0'][0]) | ||
r_dict['Trustworthiness']['Confidence'] = self.points_to_verbose(info['0'][1]) | ||
if '4' in info.keys(): | ||
r_dict['Child_Safety'] = {} | ||
r_dict['Child_Safety']['Reputation'] = self.points_to_verbose(info['4'][0]) | ||
r_dict['Child_Safety']['Confidence'] = self.points_to_verbose(info['4'][1]) | ||
if 'blacklists' in info.keys(): | ||
r_dict['Blacklists'] = [(k, datetime.datetime.fromtimestamp(v).strftime('%Y-%m-%d %H:%M:%S') ) for k,v in info['blacklists'].items()] | ||
if 'categories' in info.keys(): | ||
r_dict['Categories'] = [self.categories[x] for x in list(info['categories'].keys())] | ||
r_dict['Categories Identifier'] = list(info['categories'].keys()) | ||
self.report(r_dict) | ||
else: | ||
self.error('Invalid data type') | ||
else: | ||
self.error('Invalid service') | ||
|
||
if __name__ == '__main__': | ||
WOTAnalyzer().run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
cortexutils |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"name": "Yeti", | ||
"author": "CERT-BDF", | ||
"license": "AGPL-V3", | ||
"url": "https://github.com/CERT/cortex-analyzers", | ||
"version": "1.0", | ||
"baseConfig": "Yeti", | ||
"config": { | ||
"check_tlp": false, | ||
"max_tlp": 3 | ||
}, | ||
"description": "Fetch observable details from a Yeti", | ||
"dataTypeList": ["domain", "fqdn", "ip", "url", "hash"], | ||
"command": "Yeti/yeti.py" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
cortexutils | ||
git+https://github.com/yeti-platform/pyeti |
Oops, something went wrong.