2017-12-05 16:41:41 +01:00
|
|
|
import json
|
2018-03-09 00:26:39 +01:00
|
|
|
from ._dnsdb_query.dnsdb_query import DnsdbClient, QueryError
|
2017-12-05 16:41:41 +01:00
|
|
|
|
|
|
|
|
|
|
|
misperrors = {'error': 'Error'}
|
|
|
|
mispattributes = {'input': ['hostname', 'domain', 'ip-src', 'ip-dst'], 'output': ['freetext']}
|
|
|
|
moduleinfo = {'version': '0.1', 'author': 'Christophe Vandeplas', 'description': 'Module to access Farsight DNSDB Passive DNS', 'module-type': ['expansion', 'hover']}
|
|
|
|
moduleconfig = ['apikey']
|
|
|
|
|
|
|
|
server = 'https://api.dnsdb.info'
|
|
|
|
|
|
|
|
# TODO return a MISP object with the different attributes
|
|
|
|
|
|
|
|
|
|
|
|
def handler(q=False):
|
|
|
|
if q is False:
|
|
|
|
return False
|
|
|
|
request = json.loads(q)
|
|
|
|
if (request.get('config')):
|
|
|
|
if (request['config'].get('apikey') is None):
|
|
|
|
misperrors['error'] = 'Farsight DNSDB apikey is missing'
|
|
|
|
return misperrors
|
|
|
|
client = DnsdbClient(server, request['config']['apikey'])
|
|
|
|
if request.get('hostname'):
|
|
|
|
res = lookup_name(client, request['hostname'])
|
|
|
|
elif request.get('domain'):
|
|
|
|
res = lookup_name(client, request['domain'])
|
|
|
|
elif request.get('ip-src'):
|
|
|
|
res = lookup_ip(client, request['ip-src'])
|
|
|
|
elif request.get('ip-dst'):
|
|
|
|
res = lookup_ip(client, request['ip-dst'])
|
|
|
|
else:
|
|
|
|
misperrors['error'] = "Unsupported attributes type"
|
|
|
|
return misperrors
|
|
|
|
|
|
|
|
out = ''
|
|
|
|
for v in set(res): # uniquify entries
|
|
|
|
out = out + "{} ".format(v)
|
|
|
|
r = {'results': [{'types': mispattributes['output'], 'values': out}]}
|
|
|
|
return r
|
|
|
|
|
|
|
|
|
|
|
|
def lookup_name(client, name):
|
2018-03-09 00:26:39 +01:00
|
|
|
try:
|
|
|
|
res = client.query_rrset(name) # RRSET = entries in the left-hand side of the domain name related labels
|
|
|
|
for item in res:
|
|
|
|
if item.get('rrtype') in ['A', 'AAAA', 'CNAME']:
|
|
|
|
for i in item.get('rdata'):
|
|
|
|
yield(i.rstrip('.'))
|
|
|
|
if item.get('rrtype') in ['SOA']:
|
|
|
|
for i in item.get('rdata'):
|
|
|
|
# grab email field and replace first dot by @ to convert to an email address
|
|
|
|
yield(i.split(' ')[1].rstrip('.').replace('.', '@', 1))
|
2018-12-11 15:29:09 +01:00
|
|
|
except QueryError:
|
2018-03-09 00:26:39 +01:00
|
|
|
pass
|
|
|
|
|
|
|
|
try:
|
|
|
|
res = client.query_rdata_name(name) # RDATA = entries on the right-hand side of the domain name related labels
|
|
|
|
for item in res:
|
|
|
|
if item.get('rrtype') in ['A', 'AAAA', 'CNAME']:
|
|
|
|
yield(item.get('rrname').rstrip('.'))
|
2018-12-11 15:29:09 +01:00
|
|
|
except QueryError:
|
2018-03-09 00:26:39 +01:00
|
|
|
pass
|
2017-12-05 16:41:41 +01:00
|
|
|
|
|
|
|
|
|
|
|
def lookup_ip(client, ip):
|
2018-03-09 00:26:39 +01:00
|
|
|
try:
|
|
|
|
res = client.query_rdata_ip(ip)
|
|
|
|
for item in res:
|
|
|
|
yield(item['rrname'].rstrip('.'))
|
2018-12-11 15:29:09 +01:00
|
|
|
except QueryError:
|
2018-03-09 00:26:39 +01:00
|
|
|
pass
|
2017-12-05 16:41:41 +01:00
|
|
|
|
|
|
|
|
|
|
|
def introspection():
|
|
|
|
return mispattributes
|
|
|
|
|
|
|
|
|
|
|
|
def version():
|
|
|
|
moduleinfo['config'] = moduleconfig
|
|
|
|
return moduleinfo
|