mirror of
https://github.com/valitydev/Cortex-Analyzers.git
synced 2024-11-07 09:28:58 +00:00
Merge branch 'develop' into feature/manalyze
This commit is contained in:
commit
3a8ea1ca37
14
analyzers/DShield/DShield_lookup.json
Normal file
14
analyzers/DShield/DShield_lookup.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "DShield_lookup",
|
||||
"version": "1.0",
|
||||
"author": "Xavier Xavier, SANS ISC",
|
||||
"url": "https://github.com/xme/thehive/Cortex-Analyzers",
|
||||
"license": "AGPL-V3",
|
||||
"description": "Query the SANS ISC DShield API to check for an IP address reputation.",
|
||||
"dataTypeList": ["ip"],
|
||||
"command": "DShield/DShield_lookup.py",
|
||||
"baseConfig": "DShield",
|
||||
"config": {
|
||||
"service": "query"
|
||||
}
|
||||
}
|
104
analyzers/DShield/DShield_lookup.py
Executable file
104
analyzers/DShield/DShield_lookup.py
Executable file
@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python3
|
||||
# encoding: utf-8
|
||||
import json
|
||||
import requests
|
||||
import datetime
|
||||
import math
|
||||
from cortexutils.analyzer import Analyzer
|
||||
|
||||
class DShieldAnalyzer(Analyzer):
|
||||
def __init__(self):
|
||||
Analyzer.__init__(self)
|
||||
|
||||
def dshield_checkip(self, data):
|
||||
url = 'https://isc.sans.edu/api/ip/%s?json' % data
|
||||
r = requests.get(url)
|
||||
return json.loads(r.text)
|
||||
|
||||
def artifacts(self, raw):
|
||||
artifacts = []
|
||||
if 'as' in raw:
|
||||
artifacts.append({'type':'autonomous-system','value':str(raw['as'])})
|
||||
|
||||
if 'asabusecontact' in raw:
|
||||
artifacts.append({'type': 'email', 'value':str(raw['asabusecontact'])})
|
||||
return artifacts
|
||||
|
||||
def summary(self, raw):
|
||||
taxonomies = []
|
||||
value = "-"
|
||||
level = 'safe'
|
||||
|
||||
categories = raw.get("Categories", None)
|
||||
blacklists = raw.get("Blacklists", None)
|
||||
num_categories = raw.get("Categories Identifier", None)
|
||||
|
||||
if 'maxrisk' in raw:
|
||||
if 'threatfeedscount' in raw:
|
||||
r = int(raw['maxrisk']) + raw['threatfeedscount']
|
||||
else:
|
||||
r = int(raw['maxrisk'])
|
||||
if r <= 1:
|
||||
level = 'safe'
|
||||
elif r <= 6:
|
||||
level = 'suspicious'
|
||||
else:
|
||||
level = 'malicious'
|
||||
|
||||
value = "{} count(s) / {} attack(s) / {} threatfeed(s)".format(raw['count'], raw['attacks'], raw['threatfeedscount'])
|
||||
|
||||
taxonomies.append(self.build_taxonomy(level, "DShield", "Score", value))
|
||||
return {"taxonomies": taxonomies}
|
||||
|
||||
def get_reputation(self, risk):
|
||||
if risk <= 1:
|
||||
return("Safe")
|
||||
elif risk <= 6:
|
||||
return("Suspicious")
|
||||
else:
|
||||
return("Malicious")
|
||||
|
||||
def run(self):
|
||||
if self.data_type == 'ip':
|
||||
data = self.get_param('data', None, 'Data is missing')
|
||||
r = self.dshield_checkip(data)
|
||||
# Do we get valid results
|
||||
if self.data_type in r.keys():
|
||||
info = r[self.data_type]
|
||||
results = {}
|
||||
results['ip'] = info['number']
|
||||
results['count'] = info['count'] if isinstance(info['count'], int) else 0
|
||||
results['attacks'] = info['attacks'] if isinstance(info['attacks'], int) else 0
|
||||
results['lastseen'] = info['maxdate'] if isinstance(info['maxdate'], str) else 'None'
|
||||
results['firstseen'] = info['mindate'] if isinstance(info['mindate'], str) else 'None'
|
||||
results['updated'] = info['updated'] if isinstance(info['updated'], str) else 'None'
|
||||
results['comment'] = info['comment'] if isinstance(info['comment'], str) else 'None'
|
||||
results['asabusecontact'] = info['asabusecontact'] if isinstance(info['asabusecontact'], str) else 'Unknown'
|
||||
results['as'] = info['as']
|
||||
results['asname'] = info['asname']
|
||||
results['ascountry'] = info['ascountry']
|
||||
results['assize'] = info['assize']
|
||||
results['network'] = info['network']
|
||||
results['threatfeedscount'] = 0
|
||||
if 'threatfeeds' not in info:
|
||||
results['threatfeeds'] = ''
|
||||
else:
|
||||
results['threatfeedscount'] = len(json.loads(json.dumps(info['threatfeeds'])))
|
||||
results['threatfeeds'] = info['threatfeeds']
|
||||
# Compute a risk level based on collected information
|
||||
results['maxrisk'] = 0
|
||||
maxrisk = 10
|
||||
if results['attacks'] > 0:
|
||||
results['maxrisk'] = round(min(math.log10(results['attacks']) * 2, maxrisk))
|
||||
|
||||
# We add the number of threat feeds to the maxrisk to increase the detection rate
|
||||
results['reputation'] = self.get_reputation(int(results['maxrisk']) + results['threatfeedscount'])
|
||||
self.report(results)
|
||||
else:
|
||||
self.error('No data found')
|
||||
else:
|
||||
self.error('Invalid data type')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
DShieldAnalyzer().run()
|
2
analyzers/DShield/requirements.txt
Normal file
2
analyzers/DShield/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
cortexutils
|
||||
urllib2
|
@ -78,6 +78,9 @@ class DomainToolsAnalyzer(Analyzer):
|
||||
"domain_count": sum(d["domain_count"] for d in raw["ip_addresses"])
|
||||
}
|
||||
|
||||
if "record_count" in raw:
|
||||
r["record_count"] = raw.get('record_count')
|
||||
|
||||
if "domain_count" in raw:
|
||||
r["domain_count"] = {
|
||||
"current": raw["domain_count"]["current"],
|
||||
@ -122,7 +125,7 @@ class DomainToolsAnalyzer(Analyzer):
|
||||
|
||||
if r["service"] == "whois/history":
|
||||
taxonomies.append(self.build_taxonomy("info", "DT", "Whois_History",
|
||||
"{}, {} domains ".format(r["name_server"], r["domain_count"])))
|
||||
"{} {}".format(r["record_count"], "records" if r["record_count"] > 1 else "record")))
|
||||
|
||||
if r["service"] == "whois/parsed" or r['service'] == "whois":
|
||||
if r["registrar"]:
|
||||
@ -170,9 +173,6 @@ class DomainToolsAnalyzer(Analyzer):
|
||||
except Exception as e:
|
||||
self.unexpectedError(e)
|
||||
|
||||
else:
|
||||
self.error('Unknown DomainTools service or invalid data type')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
DomainToolsAnalyzer().run()
|
||||
|
@ -1,11 +1,29 @@
|
||||
{
|
||||
"name": "Fortiguard_URLCategory",
|
||||
"version": "2.0",
|
||||
"version": "2.1",
|
||||
"author": "Eric Capuano",
|
||||
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
|
||||
"license": "AGPL-V3",
|
||||
"dataTypeList": ["domain", "url"],
|
||||
"description": "Check the Fortiguard category of a URL or a domain.",
|
||||
"description": "Check the Fortiguard category of a URL or a domain. Check the full available list at https://fortiguard.com/webfilter/categories",
|
||||
"baseConfig": "Fortiguard",
|
||||
"command": "Fortiguard/urlcategory.py"
|
||||
"command": "Fortiguard/urlcategory.py",
|
||||
"configurationItems": [
|
||||
{
|
||||
"name": "malicious_categories",
|
||||
"description": "List of FortiGuard categories to be considered as malicious",
|
||||
"type": "string",
|
||||
"multi": true,
|
||||
"required": true,
|
||||
"defaultValue": ["Malicious Websites", "Phishing", "Spam URLs"]
|
||||
},
|
||||
{
|
||||
"name": "suspicious_categories",
|
||||
"description": "List of FortiGuard categories to be considered as suspicious",
|
||||
"type": "string",
|
||||
"multi": true,
|
||||
"required": true,
|
||||
"defaultValue": ["Newly Observed Domain", "Newly Registered Domain", "Dynamic DNS", "Proxy Avoidance", "Hacking"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -16,14 +16,14 @@ class URLCategoryAnalyzer(Analyzer):
|
||||
if 'category' in raw:
|
||||
r = raw.get('category')
|
||||
value = "{}".format(r)
|
||||
if r == "Malicious Websites":
|
||||
if r in self.get_param('config.malicious_categories', []):
|
||||
level = "malicious"
|
||||
elif r == "Suspicious Websites":
|
||||
elif r in self.get_param('config.suspicious_categories', []):
|
||||
level = "suspicious"
|
||||
elif r == "Not Rated":
|
||||
level = "info"
|
||||
else:
|
||||
level = "safe"
|
||||
else:
|
||||
level = "info"
|
||||
|
||||
taxonomies.append(self.build_taxonomy(level, "Fortiguard", "URLCat", value))
|
||||
|
||||
|
22
analyzers/Hunterio/Hunterio_domainsearch.json
Normal file
22
analyzers/Hunterio/Hunterio_domainsearch.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "Hunterio_DomainSearch",
|
||||
"author": "Rémi Allain, Cyberprotect",
|
||||
"license": "AGPL-V3",
|
||||
"url": "https://github.com/Cyberprotect/Cortex-Analyzers",
|
||||
"version": "1.0",
|
||||
"description": "hunter.io is a service to find email addresses from a domain.",
|
||||
"dataTypeList": ["domain", "fqdn"],
|
||||
"command": "Hunterio/hunterio_analyzer.py",
|
||||
"baseConfig": "Hunterio",
|
||||
"config": {
|
||||
"service": "domainsearch",
|
||||
"check_tlp": false
|
||||
},
|
||||
"configurationItems": [{
|
||||
"name": "key",
|
||||
"description": "api key of hunter.io",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
}]
|
||||
}
|
65
analyzers/Hunterio/hunterio_analyzer.py
Executable file
65
analyzers/Hunterio/hunterio_analyzer.py
Executable file
@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
import requests
|
||||
from cortexutils.analyzer import Analyzer
|
||||
|
||||
|
||||
class Hunterio(Analyzer):
|
||||
URI = "https://api.hunter.io/v2/"
|
||||
|
||||
|
||||
def __init__(self):
|
||||
Analyzer.__init__(self)
|
||||
self.service = self.get_param('config.service', None, 'Service parameter is missing')
|
||||
self.key = self.get_param('config.key', None, 'Missing hunter.io API key')
|
||||
|
||||
def summary(self, raw):
|
||||
|
||||
taxonomies = []
|
||||
namespace = "Hunter.io"
|
||||
if self.service == 'domainsearch':
|
||||
found = 0
|
||||
if(raw.get('meta') and raw['meta'].get('results')):
|
||||
found = raw['meta'].get('results')
|
||||
taxonomies.append(self.build_taxonomy('info', namespace, "Emails found", str(found)))
|
||||
|
||||
return {"taxonomies": taxonomies}
|
||||
|
||||
def artifacts(self, raw):
|
||||
artifacts = []
|
||||
if(raw.get('meta') and raw['meta'].get('results') > 0 ):
|
||||
for email in raw.get('data').get('emails'):
|
||||
artifacts.append({'type':'email', 'value':email.get('value')})
|
||||
return artifacts
|
||||
|
||||
|
||||
def run(self):
|
||||
Analyzer.run(self)
|
||||
|
||||
if self.service == 'domainsearch' and (self.data_type == 'domain' or self.data_type == 'fqdn'):
|
||||
try:
|
||||
offset = 0
|
||||
firstResponse = requests.get("{}domain-search?domain={}&api_key={}&limit=100&offset={}".format(self.URI, self.get_data(), self.key, offset))
|
||||
firstResponse = firstResponse.json()
|
||||
|
||||
if firstResponse.get('meta'):
|
||||
meta = firstResponse.get('meta')
|
||||
|
||||
while meta.get('results') > offset:
|
||||
offset = meta.get('limit') + meta.get('offset')
|
||||
additionalResponse = requests.get("{}domain-search?domain={}&api_key={}&limit=100&offset={}".format(
|
||||
self.URI, self.get_data(), self.key, offset))
|
||||
additionalResponse = additionalResponse.json()
|
||||
meta = additionalResponse.get('meta')
|
||||
firstResponse['data']['emails'] += additionalResponse['data']['emails']
|
||||
|
||||
self.report(firstResponse)
|
||||
except Exception as e:
|
||||
self.unexpectedError(e)
|
||||
else:
|
||||
self.notSupported()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
Hunterio().run()
|
2
analyzers/Hunterio/requirements.txt
Normal file
2
analyzers/Hunterio/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
cortexutils
|
||||
requests
|
@ -10,7 +10,9 @@ class MISPAnalyzer(Analyzer):
|
||||
Analyzer.__init__(self)
|
||||
|
||||
# Fixes #94. Instead of None, the string Unnamed should be passed to MISPClient constructor
|
||||
name = self.get_param('config.name', 'Unnamed')
|
||||
name = self.get_param('config.name', None)
|
||||
if not name or len(name) == 0:
|
||||
name = 'Unnamed'
|
||||
if self.get_param('config.cert_check', True):
|
||||
ssl_path = self.get_param('config.cert_path', None)
|
||||
if not ssl_path or ssl_path == '':
|
||||
|
20
analyzers/Pulsedive/Pulsedive_GetIndicator.json
Normal file
20
analyzers/Pulsedive/Pulsedive_GetIndicator.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "Pulsedive_GetIndicator",
|
||||
"version": "1.0",
|
||||
"author": "Nils Kuhnert",
|
||||
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
|
||||
"license": "AGPL-V3",
|
||||
"description": "Search Pulsedive for a given indicator",
|
||||
"dataTypeList": ["url", "domain", "ip", "hash"],
|
||||
"baseConfig": "Pulsedive",
|
||||
"command": "Pulsedive/pulsedive.py",
|
||||
"configurationItems": [
|
||||
{
|
||||
"name": "key",
|
||||
"description": "Define the API Key",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
}
|
||||
]
|
||||
}
|
55
analyzers/Pulsedive/pulsedive.py
Executable file
55
analyzers/Pulsedive/pulsedive.py
Executable file
@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python
|
||||
import requests
|
||||
|
||||
from cortexutils.analyzer import Analyzer
|
||||
|
||||
|
||||
class PulsediveAnalyzer(Analyzer):
|
||||
def __init__(self):
|
||||
Analyzer.__init__(self)
|
||||
|
||||
self.url = 'https://pulsedive.com/api/'
|
||||
self.key = self.get_param('config.key', None, 'API-Key not given.')
|
||||
self.mapping = {
|
||||
'high': 'malicious',
|
||||
'medium': 'suspicious',
|
||||
'low': 'info'
|
||||
}
|
||||
|
||||
def _query(self, observable):
|
||||
request = self.url + 'info.php'
|
||||
result = requests.get(request, {
|
||||
'indicator': observable,
|
||||
'key': self.key
|
||||
}).json()
|
||||
|
||||
if result.get('error', None) and result.get('error') != 'Indicator not found.':
|
||||
self.error(result.get('error'))
|
||||
return result
|
||||
|
||||
def run(self):
|
||||
self.report(self._query(self.get_data()))
|
||||
|
||||
def summary(self, raw):
|
||||
taxonomies = []
|
||||
for threat in raw.get('threats', []):
|
||||
taxonomies.append(self.build_taxonomy(
|
||||
'malicious' if threat.get('risk', '') == 'high' else 'suspicious',
|
||||
'Pulsedive',
|
||||
'Threat',
|
||||
threat.get('name')
|
||||
))
|
||||
|
||||
if raw.get('risk', None):
|
||||
taxonomies.append(self.build_taxonomy(
|
||||
self.mapping[raw['risk']],
|
||||
'Pulsedive',
|
||||
'Risk',
|
||||
raw['risk']
|
||||
))
|
||||
|
||||
return {'taxonomies': taxonomies}
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
PulsediveAnalyzer().run()
|
2
analyzers/Pulsedive/requirements.txt
Normal file
2
analyzers/Pulsedive/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
cortexutils
|
||||
requests
|
@ -1 +1,3 @@
|
||||
<span class="label label-info">Basic: {{content.count || 0}} record(s)</span>`
|
||||
<span class="label" ng-repeat="t in content.taxonomies" ng-class="{'info': 'label-info', 'safe': 'label-success', 'suspicious': 'label-warning', 'malicious':'label-danger'}[t.level]">
|
||||
{{t.namespace}}:{{t.predicate}}="{{t.value}}"
|
||||
</span>
|
||||
|
104
thehive-templates/DShield_lookup_1_0/long.html
Normal file
104
thehive-templates/DShield_lookup_1_0/long.html
Normal file
@ -0,0 +1,104 @@
|
||||
<div class="report-FILEInfo" ng-if="success">
|
||||
<style>
|
||||
.report-FILEInfo dl {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<strong>DShield IP Reputation Summary</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div ng-if="content[artifact.data].length === 0">
|
||||
No records found
|
||||
</div>
|
||||
<div>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>IP: </dt>
|
||||
<dd class="wrap">{{content.ip|| "-"}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Reputation: </dt>
|
||||
<dd class="wrap">{{content.reputation || "-"}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Network: </dt>
|
||||
<dd class="wrap">{{content.network || "-"}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>AS: </dt>
|
||||
<dd class="wrap">{{content.as || "-"}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>AS Name: </dt>
|
||||
<dd class="wrap">{{content.asname || "-"}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>AS Country: </dt>
|
||||
<dd class="wrap">{{content.ascountry || "-"}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>AS Abuse Contact: </dt>
|
||||
<dd class="wrap">{{content.asabusecontact || "-"}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Number of Attacks: </dt>
|
||||
<dd class="wrap">{{content.count || "-"}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Unique Attacked Hosts: </dt>
|
||||
<dd class="wrap">{{content.attacks || "-"}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>First Reported Attack: </dt>
|
||||
<dd class="wrap">{{content.firstseen || "-"}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Last Reported Attacks: </dt>
|
||||
<dd class="wrap">{{content.lastseen || "-"}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Risk Level: </dt>
|
||||
<dd class="wrap">{{content.maxrisk || "-"}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Comment: </dt>
|
||||
<dd class="wrap">{{content.comment || "-"}}</dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Threat Feeds: </dt>
|
||||
<dd class="wrap">{{content.threatfeedscount || "-"}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-info" ng-if="success">
|
||||
<div class="panel-heading">
|
||||
<strong>Threat Feeds</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div ng-if="content[artifact.threatfeeds].length === 0">
|
||||
No threat feed found
|
||||
</div>
|
||||
<div>
|
||||
<dl class="dl-horizontal" ng-repeat="(key, value) in content.threatfeeds">
|
||||
<dt>{{key}}</dt>
|
||||
<dd class="wrap">First Seen: {{value.firstseen || "-"}}</dd>
|
||||
<dd class="wrap">Last Seen: {{value.lastseen || "-"}}</dd>
|
||||
</dl>
|
||||
</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>
|
3
thehive-templates/DShield_lookup_1_0/short.html
Normal file
3
thehive-templates/DShield_lookup_1_0/short.html
Normal file
@ -0,0 +1,3 @@
|
||||
<span class="label" ng-repeat="t in content.taxonomies" ng-class="{'info': 'label-info', 'safe': 'label-success', 'suspicious': 'label-warning', 'malicious':'label-danger'}[t.level]">
|
||||
{{t.namespace}}:{{t.predicate}}="{{t.value}}"
|
||||
</span>
|
66
thehive-templates/Hunterio_DomainSearch_1_0/long.html
Normal file
66
thehive-templates/Hunterio_DomainSearch_1_0/long.html
Normal file
@ -0,0 +1,66 @@
|
||||
<div class="panel panel-info" ng-if="success">
|
||||
<div class="panel-heading">
|
||||
<a href="https://hunter.io" target="_blank">hunter.io</a> domain search to find email addresses
|
||||
<br/> Report for
|
||||
<strong>{{artifact.data}}</strong>
|
||||
</div>
|
||||
<div class="panel-body" ng-if="content.meta">
|
||||
|
||||
<h4 class="dl-horizontal">{{content.meta.results}} addresses found.</h4>
|
||||
|
||||
|
||||
<div ng-if="content.data && content.data.emails.length > 0">
|
||||
|
||||
<h5>
|
||||
Pattern : {{content.data.pattern}}
|
||||
</h5>
|
||||
|
||||
<h5>
|
||||
Organization: {{content.data.organization}}
|
||||
</h5>
|
||||
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<th>Name</th>
|
||||
<th>Position</th>
|
||||
<th>Type</th>
|
||||
<th>Twitter</th>
|
||||
<th>LinkedIn</th>
|
||||
<th>Phone</th>
|
||||
<th>Confidence</th>
|
||||
<th>Sources</th>
|
||||
</tr>
|
||||
<tr ng-repeat="email in ::content.data.emails">
|
||||
<td class="text-info">{{email.value}}</td>
|
||||
<td>{{email.fisrtname}} {{email.lastname}}</td>
|
||||
<td>{{email.position}}</td>
|
||||
<td>{{email.type}}</td>
|
||||
<td><a ng-if="email.twitter" href="https://twitter.com/{{email.twitter}}" target="_blank">{{email.twitter}}</a></td>
|
||||
<td><a ng-if="email.linkedin" href="{{email.linkedin}}" target="_blank">{{email.linkedin}}</a></td>
|
||||
<td>{{email.phone_number}}</td>
|
||||
<td>
|
||||
<span class="label label-default">{{email.confidence}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li ng-repeat="src in ::email.sources">{{src.domain}}</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="panel-body" ng-if="!content.meta">
|
||||
No results found
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
3
thehive-templates/Hunterio_DomainSearch_1_0/short.html
Normal file
3
thehive-templates/Hunterio_DomainSearch_1_0/short.html
Normal file
@ -0,0 +1,3 @@
|
||||
<span class="label" ng-repeat="t in content.taxonomies" ng-class="{'info': 'label-info', 'safe': 'label-success', 'suspicious': 'label-warning', 'malicious':'label-danger'}[t.level]">
|
||||
{{t.namespace}}:{{t.predicate}}={{t.value}}
|
||||
</span>
|
141
thehive-templates/Pulsedive_GetIndicator_1_0/long.html
Normal file
141
thehive-templates/Pulsedive_GetIndicator_1_0/long.html
Normal file
@ -0,0 +1,141 @@
|
||||
<div class="panel panel-info" ng-if="success && !content.error">
|
||||
<div class="panel-heading">
|
||||
Pulsedive Report for <strong>{{artifact.data}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<!-- THREATS -->
|
||||
<div class="panel" ng-repeat="threat in content.threats" ng-class="{'panel-warning': threat.risk !== 'high', 'panel-danger': threat.risk === 'high'}">
|
||||
<div class="panel-heading">
|
||||
Threat
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Name</dt>
|
||||
<dd>{{threat.name}}</dd>
|
||||
<dt>Risk</dt>
|
||||
<dd><span class="label"
|
||||
ng-class="{'label-warning': threat.risk !== 'high', 'label-danger': threat.risk === 'high'}">
|
||||
{{threat.risk}}
|
||||
</span>
|
||||
</dd>
|
||||
<dt>Category</dt>
|
||||
<dd>{{threat.category}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<!-- //THREATS -->
|
||||
<!-- RISKFACTORS -->
|
||||
<div class="panel panel-warning" ng-if="content.riskfactors">
|
||||
<div class="panel-heading">Risk factors</div>
|
||||
<div class="panel-body">
|
||||
<ul style="list-style: none" ng-repeat="(k, v) in content.riskfactors">
|
||||
<li>
|
||||
<span class="label"
|
||||
ng-class="{'label-success': v.risk === 'none', 'label-primary': v.risk === 'low', 'label-warning': v.risk === 'medium', 'label-danger': v.risk === 'high'}">
|
||||
{{v.risk}}
|
||||
</span>
|
||||
{{v.description}}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- //RISKFACTORS -->
|
||||
<!-- GENERAL -->
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">General information</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Indicator</dt>
|
||||
<dd>{{content.indicator}}</dd>
|
||||
<dt>Risk</dt>
|
||||
<dd>
|
||||
<span class="label"
|
||||
ng-class="{'label-warning': content.risk !== 'high', 'label-danger': content.risk === 'high'}">
|
||||
{{content.risk}}
|
||||
</span>
|
||||
</dd>
|
||||
<dt>Added</dt>
|
||||
<dd>{{content.stamp_added | date}}</dd>
|
||||
<dt>Seen</dt>
|
||||
<dd>{{content.stamp_seen | date}}</dd>
|
||||
<dt>Probed</dt>
|
||||
<dd>{{content.stamp_probed | date}}</dd>
|
||||
<dt>Updated</dt>
|
||||
<dd>{{content.stamp_updated | date}}</dd>
|
||||
<dt>Retired</dt>
|
||||
<dd><span class="label label-secondary" ng-if="content.retired">Retired on {{content.stamp_retired | date}}</span></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<uib-accordion>
|
||||
<div uib-accordion-group class="panel panel-info" heading="Attributes" ng-if="content.attributes" is-open="true">
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal" ng-repeat="(a, c) in content.attributes">
|
||||
<dt>{{a}}</dt>
|
||||
<dd><ul style="list-style: none"><li ng-repeat="item in c">{{item}}</li></ul></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div uib-accordion-group class="panel panel-info" heading="Feeds" ng-if="content.feeds">
|
||||
<div class="panel-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Feed name</td>
|
||||
<td>Feed organization</td>
|
||||
<td>Feed category</td>
|
||||
<td>Feed linked</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="(key, feed) in content.feeds">
|
||||
<td>{{feed.name}}</td>
|
||||
<td>{{feed.organization}}</td>
|
||||
<td>{{feed.category}}</td>
|
||||
<td>{{feed.stamp_linked | date}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div uib-accordion-group class="panel panel-info" heading="Properties">
|
||||
<div class="panel-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Property</td>
|
||||
<td>Property content</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr ng-repeat="(property, value) in content.properties">
|
||||
<td><b>{{property}}</b></td>
|
||||
<td>
|
||||
<dl class="dl-horizontal" ng-repeat="(k, v) in value">
|
||||
<dt>{{k}}</dt>
|
||||
<dd>{{v}}</dd>
|
||||
</dl>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div uib-accordion-group class="panel panel-info" heading="Raw">
|
||||
<div class="panel-body"><pre><code>{{content | json}}</code></pre></div>
|
||||
</div>
|
||||
</uib-accordion>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-warning" ng-if="success && content.error">
|
||||
<div class="panel-heading"><strong>{{artifact.data | fang}}</strong></div>
|
||||
<div class="panel-body">{{content.error}}</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-danger" ng-if="!success">
|
||||
<div class="panel-heading">
|
||||
<strong>{{artifact.data | fang}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{content.errorMessage}}
|
||||
</div>
|
||||
</div>
|
3
thehive-templates/Pulsedive_GetIndicator_1_0/short.html
Normal file
3
thehive-templates/Pulsedive_GetIndicator_1_0/short.html
Normal file
@ -0,0 +1,3 @@
|
||||
<span class="label" ng-repeat="t in content.taxonomies" ng-class="{'info': 'label-info', 'safe': 'label-success', 'suspicious': 'label-warning', 'malicious':'label-danger'}[t.level]">
|
||||
{{t.namespace}}:{{t.predicate}}="{{t.value}}"
|
||||
</span>
|
Loading…
Reference in New Issue
Block a user