From 5379459444504cc21128587efe1e7d37bd1eac3c Mon Sep 17 00:00:00 2001 From: Manabu Niseki Date: Thu, 18 Apr 2019 17:17:09 +0900 Subject: [PATCH 1/2] Add IPinfo analyzer Implement #462 --- analyzers/IPinfo/IPinfo_Details.json | 21 ++++++ analyzers/IPinfo/IPinfo_Hosted_Domains.json | 21 ++++++ analyzers/IPinfo/ipinfo.py | 39 ++++++++++ analyzers/IPinfo/ipinfo_analyzer.py | 72 +++++++++++++++++++ analyzers/IPinfo/requirements.txt | 2 + .../IPinfo_Details_1.0/long.html | 51 +++++++++++++ .../IPinfo_Details_1.0/short.html | 4 ++ .../IPinfo_Hosted_Domains_1.0/long.html | 42 +++++++++++ .../IPinfo_Hosted_Domains_1.0/short.html | 4 ++ 9 files changed, 256 insertions(+) create mode 100644 analyzers/IPinfo/IPinfo_Details.json create mode 100644 analyzers/IPinfo/IPinfo_Hosted_Domains.json create mode 100644 analyzers/IPinfo/ipinfo.py create mode 100755 analyzers/IPinfo/ipinfo_analyzer.py create mode 100644 analyzers/IPinfo/requirements.txt create mode 100644 thehive-templates/IPinfo_Details_1.0/long.html create mode 100644 thehive-templates/IPinfo_Details_1.0/short.html create mode 100644 thehive-templates/IPinfo_Hosted_Domains_1.0/long.html create mode 100644 thehive-templates/IPinfo_Hosted_Domains_1.0/short.html diff --git a/analyzers/IPinfo/IPinfo_Details.json b/analyzers/IPinfo/IPinfo_Details.json new file mode 100644 index 000000000..eadfcdbeb --- /dev/null +++ b/analyzers/IPinfo/IPinfo_Details.json @@ -0,0 +1,21 @@ +{ + "name": "IPinfo_Details", + "version": "1.0", + "author": "Manabu Niseki", + "url": "https://github.com/ninoseki/ipinfo-analyzers", + "license": "MIT", + "description": "IPinfo details lookup.", + "dataTypeList": ["ip"], + "command": "IPinfo/ipinfo_analyzer.py", + "baseConfig": "IPinfo", + "config": { + "service": "details" + }, + "configurationItems": [{ + "name": "api_key", + "description": "Define the API key to use to connect the service", + "type": "string", + "multi": false, + "required": true + }] +} diff --git a/analyzers/IPinfo/IPinfo_Hosted_Domains.json b/analyzers/IPinfo/IPinfo_Hosted_Domains.json new file mode 100644 index 000000000..b91ee394a --- /dev/null +++ b/analyzers/IPinfo/IPinfo_Hosted_Domains.json @@ -0,0 +1,21 @@ +{ + "name": "IPinfo_Hosted_Domains", + "version": "1.0", + "author": "Manabu Niseki", + "url": "https://github.com/ninoseki/ipinfo-analyzers", + "license": "MIT", + "description": "IPinfo hosted domains lookup.", + "dataTypeList": ["ip"], + "command": "IPinfo/ipinfo_analyzer.py", + "baseConfig": "IPinfo", + "config": { + "service": "hosted_domains" + }, + "configurationItems": [{ + "name": "api_key", + "description": "Define the API key to use to connect the service", + "type": "string", + "multi": false, + "required": true + }] +} diff --git a/analyzers/IPinfo/ipinfo.py b/analyzers/IPinfo/ipinfo.py new file mode 100644 index 000000000..aebc0cac4 --- /dev/null +++ b/analyzers/IPinfo/ipinfo.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 + +import requests + + +class IPinfoException(Exception): + pass + + +class IPinfo(): + def __init__(self, api_key): + self.base_url = "https://ipinfo.io" + self.api_key = api_key + + if self.api_key is None: + raise IPinfoException("No API key is present") + + self.session = requests.Session() + self.session.headers.update( + {"Authorization": "Bearer {}".format(self.api_key)}) + + def details(self, ip_address): + url = "{}/{}".format(self.base_url, ip_address) + return self._request(url) + + def hosted_domains(self, ip_address): + url = "{}/domains/{}".format(self.base_url, ip_address) + return self._request(url) + + def _request(self, url): + res = self.session.request("GET", url) + + if res.status_code != 200: + raise IPinfoException("IPinfo returns {}".format(res.status_code)) + + if res.text == "": + return {} + + return res.json() diff --git a/analyzers/IPinfo/ipinfo_analyzer.py b/analyzers/IPinfo/ipinfo_analyzer.py new file mode 100755 index 000000000..91c287ad0 --- /dev/null +++ b/analyzers/IPinfo/ipinfo_analyzer.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +# encoding: utf-8 + +from cortexutils.analyzer import Analyzer +from ipinfo import IPinfoException, IPinfo + + +class IPinfoAnalyzer(Analyzer): + def __init__(self): + Analyzer.__init__(self) + self.service = self.get_param( + "config.service", None, "IPinfo service is missing") + + self.api_key = self.get_param( + "config.api_key", None, "IPinfo API key is missing") + + def summary(self, raw): + taxonomies = [] + level = "info" + namespace = "IPinfo" + + if self.service == "details": + country = raw.get("country") + if country: + taxonomies.append( + self.build_taxonomy(level, namespace, "Country", country) + ) + + asn = raw.get("asn") + if asn and asn.get("asn"): + taxonomies.append( + self.build_taxonomy( + level, namespace, "ASN", asn.get("asn")) + ) + + elif self.service == "hosted_domains": + total = 0 + if "domains" in raw: + total = len(raw["domains"]) + + if total < 2: + value = "{} record".format(total) + else: + value = "{} records".format(total) + + taxonomies.append( + self.build_taxonomy(level, namespace, "HostedDomains", value) + ) + + return {"taxonomies": taxonomies} + + def run(self): + data = self.get_data() + + try: + ipinfo = IPinfo(api_key=self.api_key) + + if self.service == "details": + result = ipinfo.details(data) + self.report(result) + elif self.service == "hosted_domains": + result = ipinfo.hosted_domains(data) + self.report(result) + else: + self.error("Unknown IPinfo service") + + except IPinfoException as e: + self.error(str(e)) + + +if __name__ == "__main__": + IPinfoAnalyzer().run() diff --git a/analyzers/IPinfo/requirements.txt b/analyzers/IPinfo/requirements.txt new file mode 100644 index 000000000..6aabc3cfa --- /dev/null +++ b/analyzers/IPinfo/requirements.txt @@ -0,0 +1,2 @@ +cortexutils +requests diff --git a/thehive-templates/IPinfo_Details_1.0/long.html b/thehive-templates/IPinfo_Details_1.0/long.html new file mode 100644 index 000000000..c6b960135 --- /dev/null +++ b/thehive-templates/IPinfo_Details_1.0/long.html @@ -0,0 +1,51 @@ +
+
+
IPinfo details ({{ content.ip || "-" }})
+
+
+ No data found +
+
+
+
Hostname:
+
{{ content.hostname || "-" }}
+
+
+
Country:
+
{{ content.country || "-" }}
+
+
+
+
ASN:
+
+ {{ content.asn.asn || "-" }} / {{ content.asn.name || "-" }} +
+
+
+
Route:
+
{{ content.asn.route || "-" }}
+
+
+
Type:
+
{{ content.asn.type || "-" }}
+
+
+
+
+
+
+ + +
+
+ {{ artifact.data | fang }} +
+
+
+
+ +
+
{{ content.errorMessage }}
+
+
+
diff --git a/thehive-templates/IPinfo_Details_1.0/short.html b/thehive-templates/IPinfo_Details_1.0/short.html new file mode 100644 index 000000000..aa10d54b0 --- /dev/null +++ b/thehive-templates/IPinfo_Details_1.0/short.html @@ -0,0 +1,4 @@ + + {{t.namespace}}:{{t.predicate}}="{{t.value}}" + diff --git a/thehive-templates/IPinfo_Hosted_Domains_1.0/long.html b/thehive-templates/IPinfo_Hosted_Domains_1.0/long.html new file mode 100644 index 000000000..76dfe6c42 --- /dev/null +++ b/thehive-templates/IPinfo_Hosted_Domains_1.0/long.html @@ -0,0 +1,42 @@ +
+
+
+ IPinfo hosted domains +
+
+
+ No data found +
+
+
+ No domains found +
+
+ + + + + + + +
Domain
{{ domain }}
+
+
+
+
+
+ + +
+
+ {{ artifact.data | fang }} +
+
+
+
+ +
+
{{ content.errorMessage }}
+
+
+
diff --git a/thehive-templates/IPinfo_Hosted_Domains_1.0/short.html b/thehive-templates/IPinfo_Hosted_Domains_1.0/short.html new file mode 100644 index 000000000..aa10d54b0 --- /dev/null +++ b/thehive-templates/IPinfo_Hosted_Domains_1.0/short.html @@ -0,0 +1,4 @@ + + {{t.namespace}}:{{t.predicate}}="{{t.value}}" + From 6f209090c0419a75905a6321e2108b144f161d08 Mon Sep 17 00:00:00 2001 From: Manabu Niseki Date: Fri, 19 Apr 2019 19:40:04 +0900 Subject: [PATCH 2/2] fix a typo --- thehive-templates/IPinfo_Details_1.0/long.html | 2 +- thehive-templates/IPinfo_Hosted_Domains_1.0/long.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/thehive-templates/IPinfo_Details_1.0/long.html b/thehive-templates/IPinfo_Details_1.0/long.html index c6b960135..40f5636fe 100644 --- a/thehive-templates/IPinfo_Details_1.0/long.html +++ b/thehive-templates/IPinfo_Details_1.0/long.html @@ -1,4 +1,4 @@ -
+
IPinfo details ({{ content.ip || "-" }})
diff --git a/thehive-templates/IPinfo_Hosted_Domains_1.0/long.html b/thehive-templates/IPinfo_Hosted_Domains_1.0/long.html index 76dfe6c42..bee9f40e6 100644 --- a/thehive-templates/IPinfo_Hosted_Domains_1.0/long.html +++ b/thehive-templates/IPinfo_Hosted_Domains_1.0/long.html @@ -1,4 +1,4 @@ -
+
IPinfo hosted domains