Skip to content

Commit

Permalink
Merge pull request #1153 from remydewa/master
Browse files Browse the repository at this point in the history
Rename 'LastInfoSec' analyzer to 'Gatewatcher CTI' and add feature
  • Loading branch information
jeromeleonard authored Aug 4, 2023
2 parents aec22a9 + 03ab269 commit 27444c4
Show file tree
Hide file tree
Showing 13 changed files with 138 additions and 100 deletions.
57 changes: 57 additions & 0 deletions analyzers/Gatewatcher_CTI/Gatewatcher_CTI.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"name": "Gatewatcher CTI",
"version": "1.0",
"author": "Gatewatcher",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
"license": "AGPL-3.0",
"description": "Get Gatewatcher CTI Report",
"dataTypeList": ["hash", "domain", "fqdn", "url"],
"command": "Gatewatcher_CTI/Gatewatcher_CTI.py",
"baseConfig": "Gatewatcher_CTI",
"config": {
"service": "get_report"
},
"configurationItems": [
{
"name": "apiKey",
"description": "Gatewatcher CTI Api Key.",
"type": "string",
"multi": false,
"required": true
},
{
"name": "extendedReport",
"description": "Show reports for relations.",
"type": "boolean",
"required": true,
"multi": false,
"defaultValue": true
},
{
"name": "maxRelations",
"description": "Max relation reports to display if you have enabled the extendReport option. Set -1 to show all report",
"type": "number",
"multi": false,
"required": false,
"defaultValue": 50
}
],
"registration_required": true,
"subscription_required": true,
"free_subscription": false,
"service_homepage": "https://www.gatewatcher.com/",
"service_logo": {
"path": "assets/Gatewatcher_CTI_logo.png",
"caption": "logo"
},
"screenshots": [
{
"path": "assets/Gatewatcher_CTI_long.png",
"caption": "Gatewatcher CTI long report sample"
},
{
"path": "assets/Gatewatcher_CTI_short.png",
"caption:": "Gatewatcher CTI mini report sample"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,71 +4,75 @@
import requests


class LastInfoSec(Analyzer):
class GatewatcherCTI(Analyzer):
def __init__(self):
Analyzer.__init__(self)
self.api_key = self.get_param(
"config.apiKey", None, "LastInfoSec API KEY is required"
"config.apiKey", None, "Gatewatcher CTI API KEY is required"
)
self.extended_report = self.get_param(
"config.extendedReport", None, "Please set the Extended Report option"
)
self.max_relations= self.get_param(
"config.maxRelations", None
)
self.observable_value = self.get_param("data", None, "Data is missing")

def run(self):
if self.data_type == "hash":
url = "https://api.client.lastinfosec.com/v2/lis/search_hash/{0}?api_key={1}".format(
self.observable_value, self.api_key
)
elif self.data_type == "domain":
url = "https://api.client.lastinfosec.com/v2/lis/search_host/{0}?api_key={1}".format(
self.observable_value, self.api_key
)
else:
self.error("{} not supported".format(self.data_type))
url = f"https://api.client.lastinfosec.com/v2/lis/search?api_key={self.api_key}"
if not self.extended_report:
url = f"{url}&extended_report=false"
data = {"value" : self.observable_value}
useragent = {
"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0"
}
response = requests.get(url, headers=useragent)
response = requests.post(url, headers=useragent, json=data)
info = self.check_response(response)

additional = {}
main = {}
main_hash = {}
urls = []
records = {"IOCs": []}
records = {"IOCs": [], "is_on_gw": True}

if self.data_type == "hash":
for item in info["message"][0]["IOCs"]:
item.update(item.pop("MetaData", None))
if item["Value"] == self.observable_value:
main = item
elif item["Type"] in ["MD5", "SHA1", "SHA256"]:
additional[item["Type"]] = item["Value"]
else:
records["IOCs"].append(item)
main.update(additional)
records["IOCs"].append(main)
elif self.data_type == "domain":
if response.status_code == 422:
records["is_on_gw"] = False
else:
relations = []
for item in info["message"][0]["IOCs"]:
item.update(item.pop("MetaData", None))
if item["Value"] == self.observable_value:
main = item
elif item["Type"] == "URL":
urls.append({"url": item["Value"], "tags": item["Tags"]})
elif item["Type"] in ["MD5", "SHA1", "SHA256"]:
if len(main_hash) == 0:
main_hash = item
else:
additional[item["Type"]] = item["Value"]
relations = item.get("Relations", [])
break

if len(relations) > 0:
has_max = True
if self.max_relations == -1:
has_max = False
total_found_relations = 0
for item in info["message"][0]["IOCs"]:
if total_found_relations == len(relations) or \
(has_max and total_found_relations >= self.max_relations):
break

main["urls"] = urls
records["IOCs"].append(main)
if len(main_hash) > 0:
main_hash.update(additional)
records["IOCs"].append(main_hash)
if item["IocId"] in relations:
total_found_relations += 1

if all(x in ["MD5", "SHA1", "SHA256"] for x in [item["Type"], main["Type"]]):
if item["Type"] not in additional:
additional[item["Type"]] = item["Value"]
else:
additional[item["Type"]] = None
elif item["Type"] in ["URL", "Host", "MD5", "SHA1", "SHA256"]:
records["IOCs"].append(item)

additional = {k : v for k, v in additional.items() if v is not None}
main.update(additional)
records["IOCs"].insert(0, main)

self.report(records)

def check_response(self, response):
if response.status_code != 200:
if response.status_code not in [200,422]:
try:
result = response.json()
if (
Expand Down Expand Up @@ -96,9 +100,9 @@ def check_response(self, response):
def summary(self, raw):
taxonomies = []
level = "info"
namespace = "LastInfoSec"
namespace = "Gatewatcher CTI"
predicate = "GetReport"
value = 0
value = "Not found"
data = next(
(ioc for ioc in raw["IOCs"] if ioc["Value"] == self.observable_value), None
)
Expand All @@ -117,4 +121,4 @@ def summary(self, raw):


if __name__ == "__main__":
LastInfoSec().run()
GatewatcherCTI().run()
5 changes: 5 additions & 0 deletions analyzers/Gatewatcher_CTI/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Requirement : if you want to use LastInfoSec's intelligence, you need an API key. You could contact LastInfoSec's team here https://www.gatewatcher.com/en/contact/
LastInfosec has been acquired by Gatewatcher.
LastInfoSec's Threat Feed is a data feed that makes it easier to detect threats within the information system. It contains enriched compromised evidences in order to reduce the time of threat analysis once detected.
https://www.gatewatcher.com/en/nos-produits/last-info-sec

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.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes.
41 changes: 0 additions & 41 deletions analyzers/LastInfoSec/LastInfoSec.json

This file was deleted.

Binary file removed analyzers/LastInfoSec/assets/LastInfoSec_long.png
Binary file not shown.
Binary file removed analyzers/LastInfoSec/assets/LastInfoSec_short.png
Binary file not shown.
Binary file removed analyzers/LastInfoSec/assets/logolastinfosec.png
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
</div>
</div>

<div ng-if="success">
<div ng-if="success && content.is_on_gw">
<div class="panel panel-info" ng-repeat="ioc in content.IOCs">
<div class="panel-heading">
<strong>LastInfoSec Report for {{ioc.Type}}: {{ioc.Value}}</strong>
<strong>Gatewatcher CTI Report for {{ioc.Type}}: {{ioc.Value}}</strong>
</div>
<div class="panel-body">
<dl class="dl-horizontal" ng-if="ioc.Value == artifact.data && ioc.MD5">
Expand Down Expand Up @@ -68,24 +68,37 @@
<dt>TLP</dt>
<dd class="wrap">{{ioc.TLP}}</dd>
</dl>
<dl class="dl-horizontal" ng-if="ioc.Relations.length>0">
<dt>Relations</dt>
<dd class="wrap">{{ioc.Relations.join(", ")}}</dd>
<dl class="dl-horizontal" ng-if="ioc.TargetedSectors.length>0">
<dt>Targeted Sectors</dt>
<dd class="wrap">{{ioc.TargetedSectors.join(", ")}}</dd>
</dl>
<dl class="dl-horizontal" ng-if="ioc.TargetedCountries.length>0">
<dt>Targeted Countries</dt>
<dd class="wrap">{{ioc.TargetedCountries.join(", ")}}</dd>
</dl>
<dl class="dl-horizontal" ng-if="ioc.TargetedPlatforms.length>0">
<dt>Targeted Platforms</dt>
<dd class="wrap">{{ioc.TargetedPlatforms.join(", ")}}</dd>
</dl>
<dl class="dl-horizontal" ng-if="ioc.Vulnerabilities.length>0">
<dt>Vulnerabilities</dt>
<dd class="wrap">{{ioc.Vulnerabilities.join(", ")}}</dd>
</dl>
<dl class="dl-horizontal" ng-if="ioc.Tags.length>0">
<dt>Tags</dt>
<dd class="wrap">{{ioc.Tags.join(", ")}}</dd>
</dl>
<dl class="dl-horizontal" ng-if="ioc.urls.length>0">
<dt>Urls</dt>
<dd class="wrap">
<ul>
<li ng-repeat="url in ioc.urls">
{{url.url}} [{{url.tags.join(", ")}}]
</li>
</ul>
</dd>
</dl>
</div>
</div>
</div>

<div ng-if="success && !content.is_on_gw">
<div class="panel panel-info">
<div class="panel-heading">
Gatewatcher CTI Report
</div>
<div class="panel-body">
<span>No match.</span>
</div>
</div>
</div>

0 comments on commit 27444c4

Please sign in to comment.