Upgrade OpenCTI analyzer to v4 + add fuzzy search flavor

This commit is contained in:
Nicolas Grorod 2021-01-20 21:24:29 +01:00
parent 06e06b37a3
commit d55a85043a
7 changed files with 376 additions and 43 deletions

View File

@ -1,10 +1,10 @@
{
"name": "OpenCTI_SearchObservable",
"name": "OpenCTI_SearchExactObservable",
"author": "ANSSI",
"license": "AGPL-V3",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers/",
"version": "1.0",
"description": "Query multiple OpenCTI instances for an observable.",
"version": "2.0",
"description": "Query multiple OpenCTI instances for a specific observable.",
"dataTypeList": [
"domain",
"ip",
@ -20,6 +20,9 @@
"other",
"filename"
],
"config": {
"service": "search_exact"
},
"baseConfig": "OpenCTI",
"command": "OpenCTI/opencti.py",
"configurationItems": [

View File

@ -0,0 +1,59 @@
{
"name": "OpenCTI_SearchObservables",
"author": "ANSSI",
"license": "AGPL-V3",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers/",
"version": "2.0",
"description": "Query multiple OpenCTI instances for a list of observables matching a pattern.",
"dataTypeList": [
"domain",
"ip",
"url",
"fqdn",
"uri_path",
"user-agent",
"hash",
"mail",
"mail_subject",
"registry",
"regexp",
"other",
"filename"
],
"config": {
"service": "search_observables"
},
"baseConfig": "OpenCTI",
"command": "OpenCTI/opencti.py",
"configurationItems": [
{
"name": "name",
"description": "Name of OpenCTI servers",
"multi": true,
"required": false,
"type": "string"
},
{
"name": "url",
"description": "URL of OpenCTI servers",
"type": "string",
"multi": true,
"required": true
},
{
"name": "key",
"description": "API key for each server",
"type": "string",
"multi": true,
"required": true
},
{
"name": "cert_check",
"description": "Verify server certificate",
"type": "boolean",
"multi": false,
"required": true,
"defaultValue": true
}
]
}

View File

@ -9,7 +9,7 @@ class OpenCTIAnalyzer(Analyzer):
Analyzer.__init__(self)
self.service = self.get_param(
'config.service', "search_observable", None)
'config.service', "search_exact", None)
ssl = self.get_param('config.cert_check', True)
names = self.get_param('config.name', None, 'No OpenCTI instance name given.')
@ -42,23 +42,12 @@ class OpenCTIAnalyzer(Analyzer):
namespace = "OpenCTI"
predicate = "Search Observable"
data = []
found = False
found = 0
for r in raw['results']:
if r['observable']:
found = True
for res in r['reports']:
if 'id' in res:
data.append(res['id'])
if r['observables']:
found += len(r['observables'])
# return number of reports
value = "Found - " if found else "Not found - "
if not data:
value += "0 reports"
taxonomies.append(self.build_taxonomy(level, namespace, predicate, value))
else:
value += "{} report(s)".format(len(list(set(data))))
level = "suspicious"
value = ("Found " + str(found) + " observables") if found > 0 else "Not found"
taxonomies.append(self.build_taxonomy(level, namespace, predicate, value))
return {"taxonomies": taxonomies}
@ -70,46 +59,47 @@ class OpenCTIAnalyzer(Analyzer):
response = []
for opencti in self.openctis:
# Lookup observable
observable = opencti["api_client"].stix_observable.read(
filters=[{"key": "observable_value", "values": [data]}]
)
reports = []
if observable:
# Strip observable data for lighter output.
del(observable["markingDefinitionsIds"])
del(observable["tagsIds"])
# Lookup observables
observables = opencti["api_client"].stix_cyber_observable.list(search=data)
if self.service == "search_exact":
# Filter results to only keep exact matches
observables = [observable for observable in observables if observable["observable_value"] == data]
for observable in observables:
# Strip observable data for lighter output
del(observable["objectMarkingIds"])
del(observable["objectLabelIds"])
del(observable["externalReferencesIds"])
del(observable["indicatorsIds"])
del(observable["parent_types"])
# Get a list of reports containing this observable
reports = opencti["api_client"].report.list(
filters=[
{
"key": "observablesContains",
"key": "objectContains",
"values": [observable["id"]],
}
]
)
# Strip reports data for lighter output.
for r in reports:
del(r["graph_data"])
del(r["objectRefs"])
del(r["observableRefs"])
del(r["relationRefs"])
del(r["markingDefinitionsIds"])
del(r["tagsIds"])
del(r["externalReferencesIds"])
del(r["objectRefsIds"])
del(r["observableRefsIds"])
del(r["relationRefsIds"])
for report in reports:
del(report["objects"])
del(report["objectMarkingIds"])
del(report["externalReferencesIds"])
del(report["objectLabelIds"])
del(report["parent_types"])
del(report["objectsIds"])
del(report["x_opencti_graph_data"])
observable["reports"] = reports
response.append({
"name": opencti["name"],
"url": opencti["url"],
"observable": observable,
"reports": reports
"observables": observables
})
self.report({'results': response})

View File

@ -0,0 +1,137 @@
<div class="panel panel-info" ng-repeat="res in content.results">
<div class="panel-heading">
<b>OpenCTI {{res.name}}</b> - Report from {{res.url}}
</div>
<div class="panel-body">
<div ng-if="res.observables.length == 0">
<dl class="dl-horizontal">
<dt><i class="fa fa-warning"></i> No results</dt>
<dd>No results from OpenCTI {{res.name}}</dd>
</dl>
</div>
<div ng-if="res.observables.length > 0">
<dl class="dl-horizontal">
<dt>Observable Id:</dt>
<dd><a target="_blank" href="{{res.url}}/dashboard/observations/observables/{{res.observables[0].id}}">{{res.observables[0].id}}</a></dd>
</dl>
<dl class="dl-horizontal">
<dt>Entity Type:</dt>
<dd>{{res.observables[0].entity_type}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Created on:</dt>
<dd>{{res.observables[0].created_at}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Created by:</dt>
<dd><a target="_blank" href="{{res.url}}/dashboard/entities/organizations/{{res.observables[0].createdBy.id}}">{{res.observables[0].createdBy.name}}</a></dd>
</dl>
<dl class="dl-horizontal" ng-if="res.observables[0].objectMarking.length > 0" >
<dt>Marking Definitions:</dt>
<dd ng-repeat="md in res.observables[0].objectMarking">
<span ng-if="md.x_opencti_color==='#ffffff'" class="label"
ng-style="{'border':'1px solid','color': '#000000', 'background-color': md.x_opencti_color}">{{md.definition}}
</span>
<span ng-if="md.x_opencti_color!=='#ffffff'" class="label"
ng-style="{'background-color': md.x_opencti_color}">{{md.definition}}
</span>
</dd>
</dl>
<dl class="dl-horizontal" ng-if="res.observables[0].objectLabel.length > 0" >
<dt>Tags:</dt>
<dd ng-repeat="label in res.observables[0].objectLabel">
<span ng-if="label.color==='#ffffff'" class="label"
ng-style="{'border':'1px solid','color': '#000000', 'background-color': label.color}">{{label.value}}
</span>
<span ng-if="label.color!=='#ffffff'" class="label"
ng-style="{'background-color': label.color}">{{label.value}}
</span>
</dd>
</dl>
<dl class="dl-horizontal" ng-if="res.observables[0].externalReferences.length > 0" >
<dt>External refs:</dt>
<dd ng-repeat="extref in res.observables[0].externalReferences">
<a target="_blank" href="{{extref.url}}">{{extref.source_name}}</a>
</dd>
</dl>
<dl class="dl-horizontal" ng-if="res.observables[0].indicators.length > 0" >
<dt>Indicators:</dt>
<dd ng-repeat="ind in res.observables[0].indicators">
<a target="_blank" href="{{res.url}}/dashboard/observations/indicators/{{ind.id}}">{{ind.pattern_type}}:{{ind.pattern}}</a>
</dd>
</dl>
<div ng-repeat="report in res.observables[0].reports">
<dl class="dl-horizontal">
<dt>Report Id:</dt>
<dd><a target="_blank" href="{{res.url}}/dashboard/analysis/reports/{{report.id}}">{{report.id}}</a></dd>
</dl>
<dl class="dl-horizontal">
<dt>Report types:</dt>
<dd>{{report.report_types}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Name:</dt>
<dd>{{report.name}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Description:</dt>
<dd>{{report.description}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Published on:</dt>
<dd>{{report.published}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Confidence:</dt>
<dd>{{report.confidence}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Created by:</dt>
<dd><a target="_blank" href="{{res.url}}/dashboard/entities/organizations/{{report.createdBy.id}}">{{report.createdBy.name}}</a></dd>
</dl>
<dl class="dl-horizontal" ng-if="report.objectMarking.length > 0" >
<dt>Marking Definitions:</dt>
<dd ng-repeat="md in report.objectMarking">
<span ng-if="md.x_opencti_color==='#ffffff'" class="label"
ng-style="{'border':'1px solid','color': '#000000', 'background-color': md.x_opencti_color}">{{md.definition}}
</span>
<span ng-if="md.x_opencti_color!=='#ffffff'" class="label"
ng-style="{'background-color': md.x_opencti_color}">{{md.definition}}
</span>
</dd>
</dl>
<dl class="dl-horizontal" ng-if="report.objectLabel.length > 0" >
<dt>Labels:</dt>
<dd ng-repeat="label in report.objectLabel">
<span ng-if="label.color==='#ffffff'" class="label"
ng-style="{'border':'1px solid','color': '#000000', 'background-color': label.color}">{{label.value}}
</span>
<span ng-if="label.color!=='#ffffff'" class="label"
ng-style="{'background-color': label.color}">{{label.value}}
</span>
</dd>
</dl>
<dl class="dl-horizontal" ng-if="report.externalReferences.length > 0" >
<dt>External refs:</dt>
<dd ng-repeat="extref in report.externalReferences">
<a target="_blank" href="{{extref.url}}">{{extref.source_name}}</a>
</dd>
</dl>
<hr>
<br>
</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>

View 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>

View File

@ -0,0 +1,138 @@
<div class="panel panel-info" ng-repeat="res in content.results">
<div class="panel-heading">
<b>OpenCTI {{res.name}}</b> - Report from {{res.url}}
</div>
<div class="panel-body">
<div ng-if="res.observables.length == 0">
<dl class="dl-horizontal">
<dt><i class="fa fa-warning"></i> No results</dt>
<dd>No results from OpenCTI {{res.name}}</dd>
</dl>
</div>
<div ng-if="res.observables.length > 0">
<div ng-repeat="observable in res.observables">
<dl class="dl-horizontal">
<dt>Observable Id:</dt>
<dd><a target="_blank" href="{{res.url}}/dashboard/observations/observables/{{observable.id}}">{{observable.id}}</a></dd>
</dl>
<dl class="dl-horizontal">
<dt>Entity Type:</dt>
<dd>{{observable.entity_type}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Created on:</dt>
<dd>{{observable.created_at}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Created by:</dt>
<dd><a target="_blank" href="{{res.url}}/dashboard/entities/organizations/{{observable.createdBy.id}}">{{observable.createdBy.name}}</a></dd>
</dl>
<dl class="dl-horizontal" ng-if="observable.objectMarking.length > 0" >
<dt>Marking Definitions:</dt>
<dd ng-repeat="md in observable.objectMarking">
<span ng-if="md.x_opencti_color==='#ffffff'" class="label"
ng-style="{'border':'1px solid','color': '#000000', 'background-color': md.x_opencti_color}">{{md.definition}}
</span>
<span ng-if="md.x_opencti_color!=='#ffffff'" class="label"
ng-style="{'background-color': md.x_opencti_color}">{{md.definition}}
</span>
</dd>
</dl>
<dl class="dl-horizontal" ng-if="observable.objectLabel.length > 0" >
<dt>Tags:</dt>
<dd ng-repeat="label in observable.objectLabel">
<span ng-if="label.color==='#ffffff'" class="label"
ng-style="{'border':'1px solid','color': '#000000', 'background-color': label.color}">{{label.value}}
</span>
<span ng-if="label.color!=='#ffffff'" class="label"
ng-style="{'background-color': label.color}">{{label.value}}
</span>
</dd>
</dl>
<dl class="dl-horizontal" ng-if="observable.externalReferences.length > 0" >
<dt>External refs:</dt>
<dd ng-repeat="extref in observable.externalReferences">
<a target="_blank" href="{{extref.url}}">{{extref.source_name}}</a>
</dd>
</dl>
<dl class="dl-horizontal" ng-if="observable.indicators.length > 0" >
<dt>Indicators:</dt>
<dd ng-repeat="ind in observable.indicators">
<a target="_blank" href="{{res.url}}/dashboard/observations/indicators/{{ind.id}}">{{ind.pattern_type}}:{{ind.pattern}}</a>
</dd>
</dl>
<div ng-repeat="report in observable.reports">
<dl class="dl-horizontal">
<dt>Report Id:</dt>
<dd><a target="_blank" href="{{res.url}}/dashboard/analysis/reports/{{report.id}}">{{report.id}}</a></dd>
</dl>
<dl class="dl-horizontal">
<dt>Report types:</dt>
<dd>{{report.report_types}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Name:</dt>
<dd>{{report.name}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Description:</dt>
<dd>{{report.description}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Published on:</dt>
<dd>{{report.published}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Confidence:</dt>
<dd>{{report.confidence}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Created by:</dt>
<dd><a target="_blank" href="{{res.url}}/dashboard/entities/organizations/{{report.createdBy.id}}">{{report.createdBy.name}}</a></dd>
</dl>
<dl class="dl-horizontal" ng-if="report.objectMarking.length > 0" >
<dt>Marking Definitions:</dt>
<dd ng-repeat="md in report.objectMarking">
<span ng-if="md.x_opencti_color==='#ffffff'" class="label"
ng-style="{'border':'1px solid','color': '#000000', 'background-color': md.x_opencti_color}">{{md.definition}}
</span>
<span ng-if="md.x_opencti_color!=='#ffffff'" class="label"
ng-style="{'background-color': md.x_opencti_color}">{{md.definition}}
</span>
</dd>
</dl>
<dl class="dl-horizontal" ng-if="report.objectLabel.length > 0" >
<dt>Labels:</dt>
<dd ng-repeat="label in report.objectLabel">
<span ng-if="label.color==='#ffffff'" class="label"
ng-style="{'border':'1px solid','color': '#000000', 'background-color': label.color}">{{label.value}}
</span>
<span ng-if="label.color!=='#ffffff'" class="label"
ng-style="{'background-color': label.color}">{{label.value}}
</span>
</dd>
</dl>
<dl class="dl-horizontal" ng-if="report.externalReferences.length > 0" >
<dt>External refs:</dt>
<dd ng-repeat="extref in report.externalReferences">
<a target="_blank" href="{{extref.url}}">{{extref.source_name}}</a>
</dd>
</dl>
<hr>
<br>
</div>
</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>

View 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>