2017-03-07 03:36:00 +01:00
|
|
|
import json
|
|
|
|
import requests
|
|
|
|
|
|
|
|
misperrors = {'error': 'Error'}
|
|
|
|
mispattributes = {'input': ['hostname', 'domain', 'ip-src', 'ip-dst', 'md5', 'sha1', 'sha256', 'sha512'],
|
|
|
|
'output': ['domain', 'ip-src', 'ip-dst', 'text', 'md5', 'sha1', 'sha256', 'sha512', 'ssdeep',
|
|
|
|
'authentihash', 'filename', 'whois-registrant-email', 'url', 'link']
|
|
|
|
}
|
|
|
|
|
|
|
|
# possible module-types: 'expansion', 'hover' or both
|
2017-03-08 17:35:03 +01:00
|
|
|
moduleinfo = {'version': '1', 'author': 'KX499',
|
|
|
|
'description': 'Get information from ThreatMiner',
|
2017-03-07 03:36:00 +01:00
|
|
|
'module-type': ['expansion']}
|
|
|
|
|
2017-03-08 17:35:03 +01:00
|
|
|
desc = '{}: Threatminer - {}'
|
2017-03-07 03:36:00 +01:00
|
|
|
|
|
|
|
|
|
|
|
def handler(q=False):
|
|
|
|
if q is False:
|
|
|
|
return False
|
|
|
|
|
|
|
|
q = json.loads(q)
|
|
|
|
|
|
|
|
r = {'results': []}
|
|
|
|
|
|
|
|
if 'ip-src' in q:
|
|
|
|
r['results'] += get_ip(q['ip-src'])
|
|
|
|
if 'ip-dst' in q:
|
|
|
|
r['results'] += get_ip(q['ip-dst'])
|
|
|
|
if 'domain' in q:
|
|
|
|
r['results'] += get_domain(q['domain'])
|
|
|
|
if 'hostname' in q:
|
|
|
|
r['results'] += get_domain(q['hostname'])
|
|
|
|
if 'md5' in q:
|
|
|
|
r['results'] += get_hash(q['md5'])
|
|
|
|
if 'sha1' in q:
|
|
|
|
r['results'] += get_hash(q['sha1'])
|
|
|
|
if 'sha256' in q:
|
|
|
|
r['results'] += get_hash(q['sha256'])
|
|
|
|
if 'sha512' in q:
|
|
|
|
r['results'] += get_hash(q['sha512'])
|
|
|
|
|
|
|
|
uniq = []
|
|
|
|
for res in r['results']:
|
|
|
|
if res not in uniq:
|
|
|
|
uniq.append(res)
|
|
|
|
r['results'] = uniq
|
|
|
|
return r
|
|
|
|
|
|
|
|
|
|
|
|
def get_domain(q):
|
|
|
|
ret = []
|
|
|
|
for flag in [1, 2, 3, 4, 5, 6]:
|
|
|
|
req = requests.get('https://www.threatminer.org/domain.php', params={'q': q, 'api': 'True', 'rt': flag})
|
|
|
|
if not req.status_code == 200:
|
2017-03-08 04:08:23 +01:00
|
|
|
continue
|
2017-03-07 03:36:00 +01:00
|
|
|
results = req.json().get('results')
|
|
|
|
if not results:
|
2017-03-08 04:08:23 +01:00
|
|
|
continue
|
2017-03-07 03:36:00 +01:00
|
|
|
|
|
|
|
for result in results:
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 1: # whois
|
2017-03-07 03:36:00 +01:00
|
|
|
emails = result.get('whois', {}).get('emails')
|
2017-03-08 04:08:23 +01:00
|
|
|
if not emails:
|
|
|
|
continue
|
2017-03-07 03:36:00 +01:00
|
|
|
for em_type, email in emails.items():
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['whois-registrant-email'], 'values': [email], 'comment': desc.format(q, 'whois')})
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 2: # pdns
|
2017-03-07 03:36:00 +01:00
|
|
|
ip = result.get('ip')
|
|
|
|
if ip:
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['ip-src', 'ip-dst'], 'values': [ip], 'comment': desc.format(q, 'pdns')})
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 3: # uri
|
2017-03-07 03:36:00 +01:00
|
|
|
uri = result.get('uri')
|
|
|
|
if uri:
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['url'], 'values': [uri], 'comment': desc.format(q, 'uri')})
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 4: # samples
|
2017-03-07 03:36:00 +01:00
|
|
|
if type(result) is str:
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['sha256'], 'values': [result], 'comment': desc.format(q, 'samples')})
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 5: # subdomains
|
2017-03-07 03:36:00 +01:00
|
|
|
if type(result) is str:
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['domain'], 'values': [result], 'comment': desc.format(q, 'subdomain')})
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 6: # reports
|
2017-03-07 03:36:00 +01:00
|
|
|
link = result.get('URL')
|
|
|
|
if link:
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['url'], 'values': [link], 'comment': desc.format(q, 'report')})
|
2017-03-07 03:36:00 +01:00
|
|
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
|
|
def get_ip(q):
|
|
|
|
ret = []
|
|
|
|
for flag in [1, 2, 3, 4, 5, 6]:
|
|
|
|
req = requests.get('https://www.threatminer.org/host.php', params={'q': q, 'api': 'True', 'rt': flag})
|
|
|
|
if not req.status_code == 200:
|
2017-03-08 04:08:23 +01:00
|
|
|
continue
|
2017-03-07 03:36:00 +01:00
|
|
|
results = req.json().get('results')
|
|
|
|
if not results:
|
2017-03-08 04:08:23 +01:00
|
|
|
continue
|
2017-03-07 03:36:00 +01:00
|
|
|
|
|
|
|
for result in results:
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 1: # whois
|
2017-03-07 03:36:00 +01:00
|
|
|
emails = result.get('whois', {}).get('emails')
|
2017-03-08 04:08:23 +01:00
|
|
|
if not emails:
|
|
|
|
continue
|
2017-03-07 03:36:00 +01:00
|
|
|
for em_type, email in emails.items():
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['whois-registrant-email'], 'values': [email], 'comment': desc.format(q, 'whois')})
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 2: # pdns
|
2017-03-07 03:36:00 +01:00
|
|
|
ip = result.get('ip')
|
|
|
|
if ip:
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['ip-src', 'ip-dst'], 'values': [ip], 'comment': desc.format(q, 'pdns')})
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 3: # uri
|
2017-03-07 03:36:00 +01:00
|
|
|
uri = result.get('uri')
|
|
|
|
if uri:
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['url'], 'values': [uri], 'comment': desc.format(q, 'uri')})
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 4: # samples
|
2017-03-07 03:36:00 +01:00
|
|
|
if type(result) is str:
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['sha256'], 'values': [result], 'comment': desc.format(q, 'samples')})
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 5: # ssl
|
2017-03-07 03:36:00 +01:00
|
|
|
if type(result) is str:
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['x509-fingerprint-sha1'], 'values': [result], 'comment': desc.format(q, 'ssl')})
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 6: # reports
|
2017-03-07 03:36:00 +01:00
|
|
|
link = result.get('URL')
|
|
|
|
if link:
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['url'], 'values': [link], 'comment': desc.format(q, 'report')})
|
2017-03-07 03:36:00 +01:00
|
|
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
|
|
def get_hash(q):
|
|
|
|
ret = []
|
|
|
|
for flag in [1, 3, 6, 7]:
|
|
|
|
req = requests.get('https://www.threatminer.org/sample.php', params={'q': q, 'api': 'True', 'rt': flag})
|
|
|
|
if not req.status_code == 200:
|
2017-03-08 04:08:23 +01:00
|
|
|
continue
|
2017-03-07 03:36:00 +01:00
|
|
|
results = req.json().get('results')
|
|
|
|
if not results:
|
2017-03-08 04:08:23 +01:00
|
|
|
continue
|
2017-03-07 03:36:00 +01:00
|
|
|
|
|
|
|
for result in results:
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 1: # meta (filename)
|
2017-03-07 03:36:00 +01:00
|
|
|
name = result.get('file_name')
|
|
|
|
if name:
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['filename'], 'values': [name], 'comment': desc.format(q, 'file')})
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 3: # network
|
2017-03-07 03:36:00 +01:00
|
|
|
domains = result.get('domains')
|
|
|
|
for dom in domains:
|
|
|
|
if dom.get('domain'):
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['domain'], 'values': [dom['domain']], 'comment': desc.format(q, 'network')})
|
2017-03-07 03:36:00 +01:00
|
|
|
|
|
|
|
hosts = result.get('hosts')
|
|
|
|
for h in hosts:
|
|
|
|
if type(h) is str:
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['ip-src', 'ip-dst'], 'values': [h], 'comment': desc.format(q, 'network')})
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 6: # detections
|
2017-03-07 03:36:00 +01:00
|
|
|
detections = result.get('av_detections')
|
|
|
|
for d in detections:
|
|
|
|
if d.get('detection'):
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['text'], 'values': [d['detection']], 'comment': desc.format(q, 'detection')})
|
2018-12-11 15:29:09 +01:00
|
|
|
if flag == 7: # report
|
2017-03-07 03:36:00 +01:00
|
|
|
if type(result) is str:
|
2017-03-08 17:35:03 +01:00
|
|
|
ret.append({'types': ['sha256'], 'values': [result], 'comment': desc.format(q, 'report')})
|
2017-03-07 03:36:00 +01:00
|
|
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
|
|
def introspection():
|
|
|
|
return mispattributes
|
|
|
|
|
|
|
|
|
|
|
|
def version():
|
|
|
|
return moduleinfo
|