diff --git a/analyzers/SecurityTrails/SecurityTrails_Passive_DNS.json b/analyzers/SecurityTrails/SecurityTrails_Passive_DNS.json new file mode 100644 index 000000000..c9542586c --- /dev/null +++ b/analyzers/SecurityTrails/SecurityTrails_Passive_DNS.json @@ -0,0 +1,21 @@ +{ + "name": "SecurityTrails_Passive_DNS", + "version": "1.0", + "author": "ninoseki", + "url": "https://github.com/ninoseki/cortex-securitytrails", + "license": "MIT", + "description": "SecurityTrails Passive DNS Lookup.", + "dataTypeList": ["ip"], + "command": "SecurityTrails/securitytrails_analyzer.py", + "baseConfig": "SecurityTrails", + "config": { + "service": "passive_dns" + }, + "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/SecurityTrails/SecurityTrails_Whois.json b/analyzers/SecurityTrails/SecurityTrails_Whois.json new file mode 100644 index 000000000..5dd5d31a5 --- /dev/null +++ b/analyzers/SecurityTrails/SecurityTrails_Whois.json @@ -0,0 +1,21 @@ +{ + "name": "SecurityTrails_Whois_DNS", + "version": "1.0", + "author": "ninoseki", + "url": "https://github.com/ninoseki/cortex-securitytrails", + "license": "MIT", + "description": "SecurityTrails Whois Lookup.", + "dataTypeList": ["domain"], + "command": "SecurityTrails/securitytrails_analyzer.py", + "baseConfig": "SecurityTrails", + "config": { + "service": "whois" + }, + "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/SecurityTrails/requirements.txt b/analyzers/SecurityTrails/requirements.txt new file mode 100644 index 000000000..6aabc3cfa --- /dev/null +++ b/analyzers/SecurityTrails/requirements.txt @@ -0,0 +1,2 @@ +cortexutils +requests diff --git a/analyzers/SecurityTrails/securitytrails.py b/analyzers/SecurityTrails/securitytrails.py new file mode 100644 index 000000000..65a7d0bf0 --- /dev/null +++ b/analyzers/SecurityTrails/securitytrails.py @@ -0,0 +1,38 @@ +import json +import requests + + +class SecurityTrailsException(Exception): + pass + + +class SecurityTrails(): + def __init__(self, api_key): + self.base_url = "https://api.securitytrails.com/v1" + self.api_key = api_key + + if self.api_key is None: + raise SecurityTrailsException("No API key is present") + + def passive_dns(self, ipaddress): + url = "{}/domains/list".format(self.base_url) + payload = json.dumps({"filter": {"ipv4": ipaddress}}) + response = requests.request( + "POST", url, data=payload, headers={"apikey": self.api_key}) + + if response.status_code == 200: + return response.json() + else: + raise SecurityTrailsException( + "SecurityTrails returns {}".format(response.status_code)) + + def whois(self, domain): + url = "{}/domain/{}/whois".format(self.base_url, domain) + response = requests.request( + "GET", url, headers={"apikey": self.api_key}) + + if response.status_code == 200: + return response.json() + else: + raise SecurityTrailsException( + "SecurityTrails returns {}".format(response.status_code)) diff --git a/analyzers/SecurityTrails/securitytrails_analyzer.py b/analyzers/SecurityTrails/securitytrails_analyzer.py new file mode 100755 index 000000000..59912a42d --- /dev/null +++ b/analyzers/SecurityTrails/securitytrails_analyzer.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +# encoding: utf-8 + +from cortexutils.analyzer import Analyzer +from securitytrails import SecurityTrailsException, SecurityTrails + + +class SecurityTrailsAnalyzer(Analyzer): + def __init__(self): + Analyzer.__init__(self) + self.service = self.get_param( + "config.service", None, "SecurityTrails service is missing") + + self.api_key = self.get_param( + "config.api_key", None, "SecurityTrails API key is missing") + + def summary(self, raw): + taxonomies = [] + level = "info" + namespace = "ST" + + if self.service == "passive_dns": + predicate = "PassiveDNS" + total = 0 + if "record_count" in raw and raw["record_count"]: + total = raw["record_count"] + + if total < 2: + value = "{} record".format(total) + else: + value = "{} records".format(total) + elif self.service == "whois": + predicate = "Whois" + name = "N/A" + email = "N/A" + + if "registrarName" in raw and raw["registrarName"]: + name = raw["registrarName"] + + if "contactEmail" in raw and raw["contactEmail"]: + email = raw["contactEmail"] + + value = "Registrar name: {} / Contact email: {}".format( + name, email) + + taxonomies.append( + self.build_taxonomy(level, namespace, predicate, value) + ) + + return {"taxonomies": taxonomies} + + def run(self): + data = self.get_data() + + try: + st = SecurityTrails(api_key=self.api_key) + # passive dns service + if self.service == "passive_dns": + result = st.passive_dns(data) + self.report(result) + elif self.service == "whois": + result = st.whois(data) + self.report(result) + else: + self.error("Unknown SecurityTrails service") + + except SecurityTrailsException as e: + self.error(str(e)) + + +if __name__ == "__main__": + SecurityTrailsAnalyzer().run() diff --git a/thehive-templates/SecurityTrails_Passive_DNS_1.0/long.html b/thehive-templates/SecurityTrails_Passive_DNS_1.0/long.html new file mode 100644 index 000000000..bd5fc5b9f --- /dev/null +++ b/thehive-templates/SecurityTrails_Passive_DNS_1.0/long.html @@ -0,0 +1,65 @@ +
hostname | +whois expires date | +whois created date | +whois registrar | +host provider | +mail provider | +
---|---|---|---|---|---|
{{r.hostname}} | ++ + {{r.whois.expiresDate | date:'yyyy-MM-dd'}} + + - + | ++ + {{r.whois.createdDate | date:'yyyy-MM-dd'}} + + - + | +{{r.whois.registrar || "-"}} | ++ {{host_provider}} + | ++ {{mail_provider}} + | +