Skip to content

Commit

Permalink
feat: add SecurityTrails analyzers (#371)
Browse files Browse the repository at this point in the history
add SecurityTrails Passive DNS & Whois analyzers
  • Loading branch information
ninoseki authored and nadouani committed Nov 30, 2018
1 parent a1fad09 commit da51b61
Show file tree
Hide file tree
Showing 9 changed files with 298 additions and 0 deletions.
21 changes: 21 additions & 0 deletions analyzers/SecurityTrails/SecurityTrails_Passive_DNS.json
Original file line number Diff line number Diff line change
@@ -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
}]
}
21 changes: 21 additions & 0 deletions analyzers/SecurityTrails/SecurityTrails_Whois.json
Original file line number Diff line number Diff line change
@@ -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
}]
}
2 changes: 2 additions & 0 deletions analyzers/SecurityTrails/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cortexutils
requests
38 changes: 38 additions & 0 deletions analyzers/SecurityTrails/securitytrails.py
Original file line number Diff line number Diff line change
@@ -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))
72 changes: 72 additions & 0 deletions analyzers/SecurityTrails/securitytrails_analyzer.py
Original file line number Diff line number Diff line change
@@ -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()
65 changes: 65 additions & 0 deletions thehive-templates/SecurityTrails_Passive_DNS_1.0/long.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<div class="panel panel-danger" ng-if="success">
<div class="panel panel-info" ng-if="content.records" ng-init="results_limit = 20">
<div class="panel-heading">
SecurityTrails PassiveDNS report ({{content.meta.query}})
<span class="pull-right" ng-show="content.indicator.results.length > 20">
<a href ng-show="results_limit===20" ng-click="results_limit = undefined">Show All
({{content.records.length}})</a>
<a href ng-show="!results_limit" ng-click="results_limit = 20">Show less</a>
</span>
</div>
<div class="panel-body">
<div ng-if="content.records.length === 0">
No records found
</div>
<div ng-if="content.records.length !== 0">
<table class="table table-hover">
<tr>
<th>hostname</th>
<th>whois expires date</th>
<th>whois created date</th>
<th>whois registrar</th>
<th>host provider</th>
<th>mail provider</th>
</tr>
<tr ng-repeat="r in content.records | limitTo:results_limit | orderBy:'-task.time'">
<td>{{r.hostname}}</td>
<td>
<span ng-if="r.whois.expiresDate">
{{r.whois.expiresDate | date:'yyyy-MM-dd'}}
</span>
<span ng-if="!r.whois.expiresDate">-</span>
</td>
<td>
<span ng-if="r.whois.expiresDate">
{{r.whois.createdDate | date:'yyyy-MM-dd'}}
</span>
<span ng-if="!r.whois.expiresDate">-</span>
</td>
<td>{{r.whois.registrar || "-"}}</td>
<td>
<span ng-repeat="host_provider in r.host_provider"> <span class="label label-info">{{host_provider}}</span></span>
</td>
<td>
<span ng-repeat="mail_provider in r.mail_provider"> <span class="label label-info">{{mail_provider}}</span></span>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>

<!-- General error -->
<div class="panel panel-danger" ng-if="!success">
<div class="panel-heading">
<strong>{{artifact.data | fang}}</strong>
</div>
<div class="panel-body">
<dl class="dl-horizontal" ng-if="content.errorMessage">
<dt>
<i class="fa fa-warning"></i></dt>
<dd class="wrap">{{content.errorMessage}}</dd>
</dl>
</div>
</div>
3 changes: 3 additions & 0 deletions thehive-templates/SecurityTrails_Passive_DNS_1.0/short.html
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>
73 changes: 73 additions & 0 deletions thehive-templates/SecurityTrails_Whois_1.0/long.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<div class="report-FILEInfo" ng-if="success">
<div class="panel panel-info">
<div class="panel-heading">
SecurityTrails Whois report ({{content.domain}})
</div>
<div class="panel-body">
<div ng-if="content.contacts.length === 0">
No records found
</div>
<div ng-if="content.contacts.length !== 0">
<dl class=" dl-horizontal">
<dt>Domain: </dt>
<dd class="wrap">{{content.domain|| "-"}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Contact email: </dt>
<dd class="wrap">{{content.contactEmail || "-"}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Nameservers: </dt>
<dd class="wrap" ng-repeat="ns in content.nameServers">{{ns}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Created date: </dt>
<dd class="wrap">{{content.createdDate | date:'yyyy-MM-dd'}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Updated date: </dt>
<dd class="wrap">{{content.updatedDate | date:'yyyy-MM-dd'}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Expires date: </dt>
<dd class="wrap">{{content.expiresDate | date:'yyyy-MM-dd'}}</dd>
</dl>
<dl class="dl-horizontal">
<dt>Registrar name: </dt>
<dd class="wrap">{{content.registrarName}}</dd>
</dl>
</div>
</div>
</div>
<div class="panel panel-info" ng-if="success">
<div class="panel-heading">
<strong>Contacts info</strong>
</div>
<div class="panel-body">
<div ng-if="content.contacts.length === 0">
No records found
</div>
<div ng-repeat="contact in content.contacts">
<dl class="dl-horizontal" ng-repeat="(key, value) in contact">
<dt>{{key}}</dt>
<dd>{{value}}</dd>
</dl>
<hr>
</div>
</div>
</div>
</div>

<!-- General error -->
<div class="panel panel-danger" ng-if="!success">
<div class="panel-heading">
<strong>{{artifact.data | fang}}</strong>
</div>
<div class="panel-body">
<dl class="dl-horizontal" ng-if="content.errorMessage">
<dt>
<i class="fa fa-warning"></i></dt>
<dd class="wrap">{{content.errorMessage}}</dd>
</dl>
</div>
</div>
3 changes: 3 additions & 0 deletions thehive-templates/SecurityTrails_Whois_1.0/short.html
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>

0 comments on commit da51b61

Please sign in to comment.