def crtshSearch(self, domain, parentDomain): result = [] discardDomains = [] c = Crtsh() # Get certs try: certs = c.search(domain) # Get data of every cert available for cert in certs: data = c.get(cert["id"], type="id") for alternative_name in data["extensions"][ "alternative_names"]: # Discard wildcard names if alternative_name not in discardDomains and "*" not in alternative_name: try: ip = socket.gethostbyname(alternative_name) except socket.gaierror as e: # Subdomains does not resolve ip = None discardDomains.append(alternative_name) result.append( Domain(None, alternative_name, parentDomain, ip)) except Exception as e: self.callback.exception(e) self.callback.update(result)
def test_get_unknown_id(self): crt = Crtsh() try: cert = crt.get('81863923950', type='id') self.assertTrue(False) except CrtshCertificateNotFound: pass
def test_get_id(self): crt = Crtsh() cert = crt.get('8186392', type='id') self.assertEqual(cert['id'], '8186392') self.assertEqual(cert['sha1'], 'B387B1F38800844F5E8FBA0F4442BFB3892BE2A9') self.assertEqual( cert['sha256'], 'E9AB36315DC9DEBC718086BA341E3F9332A1AE98C5554B71A14E6E39F755BCC4') self.assertEqual(cert['serial'], '00d3fc2747513084672c3739cce9a212c0')
def get_subdomains(self, domain): crt = Crtsh() subdomains = set() index = crt.search(unbracket(domain)) for c in index: data = crt.get(c["id"], type="id") subdomains.add(data["subject"]["commonName"]) if "alternative_names" in data["extensions"]: for d in data["extensions"]["alternative_names"]: subdomains.add(d) return list(subdomains)
def _get_details(crt_id): """ Returns details for given certificate """ c = Crtsh() try: return c.get(crt_id) except (IndexError, CrtshCertificateNotFound) as err: log.error(err) return {'subject': dict(), 'issuer': dict()}
def _search_domain(domain): """ Check if domain exists in db of crt.sh and return it's certs """ domain = url_to_domain(domain) c = Crtsh() certs = c.search(domain) if not certs: return None else: return certs
def crtsh(domain): c = Crtsh() certs = c.search(domain) subdomains = [] for cert in certs: if '\n' in cert['name']: splitted_names = cert['name'].split("\n") for i in splitted_names: subdomains.append(i) else: subdomains.append(cert['name'].rstrip()) return subdomains
def _search_domain(domain): """ Check if domain exists in db of crt.sh and return it's certs """ domain = url_to_domain(domain) c = Crtsh() try: certs = c.search(domain) except json.JSONDecodeError as err: log.error(err) return None if not certs: return None else: return certs
import argparse import operator from pycrtsh import Crtsh from collections import Counter if __name__ == "__main__": parser = argparse.ArgumentParser(description='List certificates for a domain') parser.add_argument('DOMAIN', help='an integer for the accumulator') args = parser.parse_args() crt = Crtsh() index = crt.search(args.DOMAIN) domains = [] print("Certificates") for c in index: data = crt.get(c["id"], type="id") print("%s\t%s\t%s\t%s" % ( data["subject"]["commonName"], data["not_before"].isoformat(), data["not_after"].isoformat(), data["sha1"] ) ) if "alternative_names" in data["extensions"]: domains += list(set([a[2:] if a.startswith("*.") else a for a in data["extensions"]["alternative_names"]])) print("\nDomains") count = Counter(domains) for d in sorted(count.items(), key=operator.itemgetter(1), reverse=True): print("-%s: %i occurences" % (d[0], d[1]))
def run(self, conf, args, plugins): crt = Crtsh() if args.domain: index = crt.search(args.domain) if args.format == "txt": domains = [] print("Certificates") for c in index: data = crt.get(c["id"], type="id") print("%s\t%s\t%s\t%s" % (data["subject"]["commonName"], data["not_before"].isoformat(), data["not_after"].isoformat(), data["sha1"])) if "alternative_names" in data["extensions"]: domains += list( set([ a[2:] if a.startswith("*.") else a for a in data["extensions"]["alternative_names"] ])) print("\nDomains") count = Counter(domains) for d in sorted(count.items(), key=operator.itemgetter(1), reverse=True): print("-%s: %i occurences" % (d[0], d[1])) elif args.format == "json": certs = {} for c in index: certs[c["id"]] = crt.get(c["id"], type="id") print( json.dumps(certs, sort_keys=True, indent=4, separators=(',', ': '), default=json_serial)) elif args.format == "csv": print( "id|serial|sha1|Common Name|Issuer|Not Before|Not After|Basic Constraints|Alt Names" ) for c in index: data = crt.get(c["id"], type="id") print( "%s|%s|%s|%s|%s|%s|%s|%s|%s" % (c["id"], data["serial"], data["sha1"], data["subject"]["commonName"], data["issuer"]["commonName"], data["not_before"], data["not_after"], data["extensions"] ["basic_constraints"] if "basic_constraints" in data["extensions"] else "False", ", ".join(data["extensions"]["alternative_names"]) if "alternative_names" in data["extensions"] else "")) elif args.list: sha1_list = [] with open(args.list, 'r') as f: domains = [a.strip() for a in f.read().split()] if args.format == "txt": for d in domains: index = crt.search(d) print("Certificates for %s" % d) for c in index: data = crt.get(c["id"], type="id") print("%s\t%s\t%s\t%s" % (data["subject"]["commonName"], data["not_before"].isoformat(), data["not_after"].isoformat(), data["sha1"])) print("") elif args.format == "json": data = {} for d in domains: data[d] = {} index = crt.search(d) for c in index: if data["sha1"] not in sha1_list: sha1_list.append(data["sha1"]) data[d][c["id"]] = crt.get(c["id"], type="id") print( json.dumps(data, sort_keys=True, indent=4, separators=(',', ': '), default=json_serial)) elif args.format == "csv": print( "id|serial|sha1|Common Name|Issuer|Not Before|Not After|Basic Constraints|Alt Names" ) for d in domains: index = crt.search(d) for c in index: data = crt.get(c["id"], type="id") if data["sha1"] not in sha1_list: sha1_list.append(data["sha1"]) print("%s|%s|%s|%s|%s|%s|%s|%s|%s" % (c["id"], data["serial"], data["sha1"], data["subject"]["commonName"], data["issuer"]["commonName"], data["not_before"], data["not_after"], data["extensions"]["basic_constraints"] if "basic_constraints" in data["extensions"] else "False", ", ".join( data["extensions"]["alternative_names"]) if "alternative_names" in data["extensions"] else "")) else: self.parser.print_help() else: self.parser.print_help()
def test_get_serial_bug(self): crt = Crtsh() cert = crt.get('146290136') self.assertEqual(cert['serial'], '24d427be1877104b4eef1a85')
def test_search_not_found(self): crt = Crtsh() res = crt.search('domaindoesnotexist.cco') self.assertEqual(len(res), 0)
def test_get_parsing(self): crt = Crtsh() cert = crt.get('253073880', type='id') self.assertEqual(cert['subject']['commonName'], 'citizenlab.ca') self.assertTrue('alternative_names' in cert['extensions']) self.assertEqual(len(cert['extensions']['alternative_names']), 2)
def test_search(self): crt = Crtsh() res = crt.search("okta.com") self.assertTrue(len(res) > 0)