diff --git a/analyzers/Crtsh/crtshquery.py b/analyzers/Crtsh/crtshquery.py
index c3dd6e3c0..6667b753b 100755
--- a/analyzers/Crtsh/crtshquery.py
+++ b/analyzers/Crtsh/crtshquery.py
@@ -3,6 +3,7 @@
import requests
import json
+import re
from cortexutils.analyzer import Analyzer
@@ -29,22 +30,46 @@ def search(self, domain, wildcard=True):
XML notation would also include the base64 cert:
https://crt.sh/atom?q={}
"""
+ rex = '\
SHA-1\(Certificate\)\ | \s+\([^\<]+)\ | '
base_url = "https://crt.sh/?q={}&output=json"
- if wildcard:
- domain = "%25.{}".format(domain)
url = base_url.format(domain)
- ua = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1'
+ ua = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
req = requests.get(url, headers={'User-Agent': ua})
if req.ok:
try:
content = req.content.decode('utf-8')
data = json.loads(content.replace('}{', '},{'))
- return data
- except Exception:
- self.error("Error retrieving information.")
- return None
+ except Exception as e:
+ self.error("Error retrieving base domain information. {}".format(e))
+ return None
+
+ if wildcard:
+ url2 = base_url.format("%25{}.".format(domain))
+ req2 = requests.get(url2, headers={'User-Agent': ua})
+ if req2.ok:
+ try:
+ content2 = req2.content.decode('utf-8')
+ data2 = json.loads(content2.replace('}{', '},{'))
+ data.extend(data2)
+ except Exception as e:
+ self.error("Error retrieving wildcard information. {}".format(e))
+ return None
+
+ for c in data:
+ det_url = 'https://crt.sh/?q={}&output=json'.format(c['min_cert_id'])
+ try:
+ det_req = requests.get(det_url, headers={'User-Agent': ua})
+ if det_req.status_code == requests.codes.ok:
+ det_con = det_req.content.decode('utf-8')
+ sha1 = re.findall(rex, det_con)[0]
+ c['sha1'] = sha1
+ else:
+ c['sha1'] = ''
+ except:
+ c['sha1'] = ''
+ return data
def __init__(self):
Analyzer.__init__(self)
@@ -68,6 +93,19 @@ def summary(self, raw):
return {"taxonomies": taxonomies}
+ def artifacts(self, raw):
+ artifacts = []
+ results = raw.get('certobj', {}).get('result', [])
+ for cert in results:
+ if 'sha1' in cert:
+ artifacts.append({'type':'certificate_hash', 'value':cert.get('sha1')})
+ if 'name_value' in cert:
+ artifacts.append({'type': 'fqdn', 'value': cert.get('name_value')})
+
+ #dedup
+ artifacts = [dict(t) for t in {tuple(d.items()) for d in artifacts}]
+ return artifacts
+
def run(self):
Analyzer.run(self)
diff --git a/thehive-templates/Crt_sh_Transparency_Logs_1_0/long.html b/thehive-templates/Crt_sh_Transparency_Logs_1_0/long.html
index d2694997f..319a0b3ea 100644
--- a/thehive-templates/Crt_sh_Transparency_Logs_1_0/long.html
+++ b/thehive-templates/Crt_sh_Transparency_Logs_1_0/long.html
@@ -7,28 +7,18 @@
No result found.
-
-
- name |
- not before |
- not after |
- min cert id |
- issuer name |
- issuer ca id |
- min entry timestamp |
-
-
-
- {{r.name_value}} |
- {{r.not_before}} |
- {{r.not_after}} |
- {{r.min_cert_id}} |
- {{r.issuer_name}} |
- {{r.issuer_ca_id}} |
- {{r.min_entry_timestamp}} |
-
-
-
+
+ - Name:
+ - {{r.name_value}}
+ - SHA1:
+ - {{r.sha1}}
+ - Issuer:
+ - {{r.issuer_name}}
+ - Not Before:
+ - {{r.not_before}}
+ - Not After:
+ - {{r.not_after}}
+