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 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 _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_search_not_found(self): crt = Crtsh() res = crt.search('domaindoesnotexist.cco') self.assertEqual(len(res), 0)
def test_search(self): crt = Crtsh() res = crt.search("okta.com") self.assertTrue(len(res) > 0)