-
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.
Merge branch 'feat/sekoia_analyzers' of https://github.com/SEKOIA-IO/…
…Cortex-Analyzers into SEKOIA-IO-feat/sekoia_analyzers
- Loading branch information
Showing
12 changed files
with
345 additions
and
0 deletions.
There are no files selected for viewing
50 changes: 50 additions & 0 deletions
50
analyzers/SEKOIAIntelligenceCenter/IntelligenceCenter_Context.json
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,50 @@ | ||
{ | ||
"name": "SEKOIAIntelligenceCenter_Context", | ||
"version": "1.0", | ||
"author": "SEKOIA", | ||
"url": "https://github.com/TheHive-Project/Cortex-Analyzers", | ||
"license": "AGPL-V3", | ||
"description": "Query the Intelligence Center to retrieve the context of an observable", | ||
"dataTypeList": [ | ||
"domain", | ||
"fqdn", | ||
"url", | ||
"hash", | ||
"ip" | ||
], | ||
"command": "SEKOIAIntelligenceCenter/sekoia_intelligence_center_analyzer.py", | ||
"baseConfig": "SEKOIAIntelligenceCenter", | ||
"config": { | ||
"service": "context" | ||
}, | ||
"configurationItems": [ | ||
{ | ||
"name": "api_key", | ||
"description": "Intelligence center API key", | ||
"type": "string", | ||
"multi": false, | ||
"required": true | ||
}, | ||
{ | ||
"name": "url", | ||
"description": "Intelligence center URL", | ||
"type": "string", | ||
"multi": false, | ||
"required": false | ||
} | ||
], | ||
"registration_required": true, | ||
"subscription_required": true, | ||
"free_subscription": false, | ||
"service_homepage": "https://sekoia.io/", | ||
"service_logo": { | ||
"path": "assets/sekoia_logo.png", | ||
"caption": "logo" | ||
}, | ||
"screenshots": [ | ||
{ | ||
"path": "assets/SEKOIAIntelligenceCenter_Context_long.png", | ||
"caption": "SEKOIAIntelligenceCenter_Context long report sample" | ||
} | ||
] | ||
} |
50 changes: 50 additions & 0 deletions
50
analyzers/SEKOIAIntelligenceCenter/IntelligenceCenter_Indicators.json
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,50 @@ | ||
{ | ||
"name": "SEKOIAIntelligenceCenter_Indicators", | ||
"version": "1.0", | ||
"author": "SEKOIA", | ||
"url": "https://github.com/TheHive-Project/Cortex-Analyzers", | ||
"license": "AGPL-V3", | ||
"description": "Query the Intelligence Center to retrieve indicators", | ||
"dataTypeList": [ | ||
"domain", | ||
"fqdn", | ||
"url", | ||
"hash", | ||
"ip" | ||
], | ||
"command": "SEKOIAIntelligenceCenter/sekoia_intelligence_center_analyzer.py", | ||
"baseConfig": "SEKOIAIntelligenceCenter", | ||
"config": { | ||
"service": "indicators" | ||
}, | ||
"configurationItems": [ | ||
{ | ||
"name": "api_key", | ||
"description": "Intelligence center API key", | ||
"type": "string", | ||
"multi": false, | ||
"required": true | ||
}, | ||
{ | ||
"name": "url", | ||
"description": "Intelligence center URL", | ||
"type": "string", | ||
"multi": false, | ||
"required": false | ||
} | ||
], | ||
"registration_required": true, | ||
"subscription_required": true, | ||
"free_subscription": false, | ||
"service_homepage": "https://sekoia.io/", | ||
"service_logo": { | ||
"path": "assets/sekoia_logo.png", | ||
"caption": "logo" | ||
}, | ||
"screenshots": [ | ||
{ | ||
"path": "assets/SEKOIAIntelligenceCenter_Indicators_long.png", | ||
"caption": "SEKOIAIntelligenceCenter_Indicators long report sample" | ||
} | ||
] | ||
} |
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,14 @@ | ||
Get more context around domain names, IP adresses, urls and file hashes using the | ||
[SEKOIA.IO](https://sekoia.io) Intelligence Database. | ||
|
||
The analyzer comes in 2 flavors: | ||
|
||
- SEKOIAIntelligenceCenter_**Indicators**: Find indicators matching the observable provided. | ||
- SEKOIAIntelligenceCenter_**Context**: Get indicators and their context for the observable provided. | ||
|
||
#### Requirements | ||
You need an active [SEKOIA.IO Intelligence Center](https://sekoia.io/) subscription to use the analyzer: | ||
|
||
- Provide your API key as a value for the `api_key` parameter. | ||
|
||
To get any help don't hesitate to contact [email protected]. |
Binary file added
BIN
+70.3 KB
...yzers/SEKOIAIntelligenceCenter/assets/SEKOIAIntelligenceCenter_Context_long.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+35.7 KB
...rs/SEKOIAIntelligenceCenter/assets/SEKOIAIntelligenceCenter_Indicators_long.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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 |
91 changes: 91 additions & 0 deletions
91
analyzers/SEKOIAIntelligenceCenter/sekoia_intelligence_center_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,91 @@ | ||
#!/usr/bin/env python3 | ||
# encoding: utf-8 | ||
from ipaddress import ip_address | ||
|
||
import requests | ||
from cortexutils.analyzer import Analyzer | ||
from requests import HTTPError | ||
|
||
|
||
class IntelligenceCenterAnalyzer(Analyzer): | ||
|
||
TYPES_MAPPING = { | ||
"url": "url", | ||
"domain": "domain-name", | ||
"fqdn": "domain-name", | ||
"hash": "file", | ||
"ip": ["ipv4-addr", "ipv6-addr"], | ||
} | ||
|
||
DEFAULT_URL = "https://app.sekoia.io" | ||
|
||
@property | ||
def url(self): | ||
path = "" | ||
if self.service == "context": | ||
path = "/context" | ||
return "{}/api/v2/inthreat/indicators{}".format(self.base_url, path) | ||
|
||
def __init__(self): | ||
Analyzer.__init__(self) | ||
self.service = self.get_param("config.service", None, "Service parameter is missing") | ||
self.api_key = self.get_param("config.api_key", None, "Missing Api Key") | ||
self.base_url = self.get_param("config.url", self.DEFAULT_URL) | ||
if not self.base_url: | ||
# Case of empty string | ||
self.base_url = self.DEFAULT_URL | ||
|
||
def run(self): | ||
ic_type = self.get_ic_type() | ||
value = self.get_data() | ||
results = self.perform_request({"type": ic_type, "value": value}) | ||
self.report({"results": results}) | ||
|
||
def summary(self, raw): | ||
count = len(raw.get("results", [])) | ||
value = "{} result{}".format(count, "s" if count > 1 else "") | ||
if count == 0: | ||
level = "safe" | ||
else: | ||
level = "malicious" | ||
|
||
return {"taxonomies": [self.build_taxonomy(level, "SEKOIA", self.service, value)]} | ||
|
||
def get_ic_type(self): | ||
if self.data_type not in self.TYPES_MAPPING.keys(): | ||
self.error("Invalid data type") | ||
if self.data_type != "ip": | ||
return self.TYPES_MAPPING[self.data_type] | ||
|
||
# Check what kind of IP it is. | ||
try: | ||
address = ip_address(self.get_data()) | ||
return "ipv4-addr" if address.version == 4 else "ipv6-addr" | ||
except ValueError: | ||
self.error("Invalid IP address") | ||
|
||
def perform_request(self, payload): | ||
""" | ||
Send the request to the API. | ||
The main error codes are handled here | ||
""" | ||
headers = {"Authorization": "Bearer {}".format(self.api_key)} | ||
try: | ||
response = requests.get(self.url, params=payload, headers=headers) | ||
response.raise_for_status() | ||
return response.json()["items"] | ||
except HTTPError as ex: | ||
if ex.response.status_code == 401: | ||
self.error("Unauthorized to query the API. Is the API key valid ?") | ||
if ex.response.status_code == 403: | ||
self.error( | ||
"Forbidden to query the API. Does the API key has the right permissions ?" | ||
) | ||
if ex.response.status_code == 429: | ||
self.error("Quota exhausted.") | ||
self.error("API returned with the error code {}".format(str(ex.response.status_code))) | ||
|
||
|
||
if __name__ == "__main__": | ||
IntelligenceCenterAnalyzer().run() |
75 changes: 75 additions & 0 deletions
75
thehive-templates/SEKOIAIntelligenceCenter_Context_1_0/long.html
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,75 @@ | ||
<div class="sekoia-report" ng-if="success"> | ||
<div ng-if="content.results.length === 0"> | ||
No results found | ||
</div> | ||
<h2 ng-if="content.results.length > 0">{{content.results.length}} Context(s)</h2> | ||
<div ng-repeat="bundle in content.results track by 'id'"> | ||
<h4>{{bundle.id}}</h4> | ||
<div ng-if="bundle.objects.length > 0" ng-repeat="item in bundle.objects"> | ||
<div class="panel panel-info" ng-if="item.type !== 'relationship' && item.type !== 'marking-definition'"> | ||
<div class="panel-heading"> | ||
<strong>{{item.name | fang}}</strong> | ||
</div> | ||
<div class="panel-body"> | ||
<div> | ||
<dl class="dl-horizontal"> | ||
<dt>Type</dt> | ||
<dd class="wrap">{{item.type}}</dd> | ||
</dl> | ||
<dl class="dl-horizontal" ng-if="item.aliases"> | ||
<dt>Aliases</dt> | ||
<dd> | ||
<div ng-if="item.aliases.length === 0">No aliases defined</div> | ||
<div ng-if="item.aliases.length > 0"> | ||
<span class="label label-info" style="margin: 2px;" ng-repeat="alias in item.aliases">{{alias}}</span> | ||
</div> | ||
</dd> | ||
</dl> | ||
<dl class="dl-horizontal"> | ||
<dt>Description</dt> | ||
<dd class="wrap">{{item.description || 'No description' }}</dd> | ||
</dl> | ||
<dl class="dl-horizontal" ng-if="item.type === 'indicator'"> | ||
<dt>Pattern</dt> | ||
<dd class="wrap">{{item.pattern }}</dd> | ||
</dl> | ||
<dl class="dl-horizontal" ng-if="item.type === 'indicator'"> | ||
<dt>Pattern type</dt> | ||
<dd class="wrap">{{item.pattern_type || 'stix' }}</dd> | ||
</dl> | ||
<dl class="dl-horizontal" ng-if="item.type === 'indicator'"> | ||
<dt>Valid from</dt> | ||
<dd class="wrap">{{item.valid_from.split("T")[0] || 'no set' }}</dd> | ||
</dl> | ||
<dl class="dl-horizontal" ng-if="item.type === 'indicator'"> | ||
<dt>Valid until</dt> | ||
<dd class="wrap">{{item.valid_until.split("T")[0] || 'no set' }}</dd> | ||
</dl> | ||
<dl class="dl-horizontal" ng-if="item.kill_chain_phases"> | ||
<dt>Kill chain phases</dt> | ||
<dd> | ||
<div ng-if="item.kill_chain_phases.length === 0">No kill chain defined</div> | ||
<div ng-if="item.kill_chain_phases.length > 0"> | ||
<span class="label label-info" style="margin: 2px;" ng-repeat="chain in item.kill_chain_phases">{{chain.phase_name}}</span> | ||
</div> | ||
</dd> | ||
</dl> | ||
</div> | ||
</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"> | ||
<dl class="dl-horizontal" ng-if="content.errorMessage"> | ||
<dt><i class="fa fa-warning"></i> SEKOIA: </dt> | ||
<dd class="wrap">{{content.errorMessage}}</dd> | ||
</dl> | ||
</div> | ||
</div> |
3 changes: 3 additions & 0 deletions
3
thehive-templates/SEKOIAIntelligenceCenter_Context_1_0/short.html
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,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> |
57 changes: 57 additions & 0 deletions
57
thehive-templates/SEKOIAIntelligenceCenter_Indicators_1_0/long.html
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,57 @@ | ||
<div class="sekoia-report" ng-if="success"> | ||
<div ng-if="content.results.length === 0"> | ||
No results found | ||
</div> | ||
<h2 ng-if="content.results.length > 0">{{content.results.length}} Indicator(s)</h2> | ||
<div class="panel panel-info" ng-if="content.results.length > 0" ng-repeat="indicator in content.results track by 'id'"> | ||
<div class="panel-heading"> | ||
<strong>{{indicator.name | fang}}</strong> | ||
</div> | ||
<div class="panel-body"> | ||
<div> | ||
<dl class="dl-horizontal"> | ||
<dt>Description</dt> | ||
<dd class="wrap">{{indicator.description || 'No description' }}</dd> | ||
</dl> | ||
<dl class="dl-horizontal"> | ||
<dt>Pattern</dt> | ||
<dd class="wrap">{{indicator.pattern }}</dd> | ||
</dl> | ||
<dl class="dl-horizontal"> | ||
<dt>Pattern type</dt> | ||
<dd class="wrap">{{indicator.pattern_type || 'stix' }}</dd> | ||
</dl> | ||
<dl class="dl-horizontal"> | ||
<dt>Valid from</dt> | ||
<dd class="wrap">{{indicator.valid_from.split("T")[0] || 'no set' }}</dd> | ||
</dl> | ||
<dl class="dl-horizontal"> | ||
<dt>Valid until</dt> | ||
<dd class="wrap">{{indicator.valid_until.split("T")[0] || 'no set' }}</dd> | ||
</dl> | ||
<dl class="dl-horizontal" ng-if="indicator.kill_chain_phases"> | ||
<dt>Kill chain phases</dt> | ||
<dd> | ||
<div ng-if="indicator.kill_chain_phases.length === 0">No kill chain defined</div> | ||
<div ng-if="indicator.kill_chain_phases.length > 0"> | ||
<span class="label label-info" style="margin: 2px;" ng-repeat="chain in indicator.kill_chain_phases">{{chain.phase_name}}</span> | ||
</div> | ||
</dd> | ||
</dl> | ||
</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"> | ||
<dl class="dl-horizontal" ng-if="content.errorMessage"> | ||
<dt><i class="fa fa-warning"></i> SEKOIA: </dt> | ||
<dd class="wrap">{{content.errorMessage}}</dd> | ||
</dl> | ||
</div> | ||
</div> |
3 changes: 3 additions & 0 deletions
3
thehive-templates/SEKOIAIntelligenceCenter_Indicators_1_0/short.html
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,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> |