Certificate Transparency logs record every SSL/TLS certificate ever issued. crt.sh gives you free access to search them all — and discover subdomains that even the domain owner forgot about.
No API key. No rate limits. Just add ?output=json\ to any query.
Why This Matters
A bug bounty hunter was testing a company's web application. The main site was hardened. But when they searched crt.sh for the company's certificates, they found 47 subdomains — including staging.company.com\, dev-api.company.com\, and old-admin.company.com\. The staging server had default credentials.
Certificate Transparency reveals your entire attack surface.
The Simplest API You'll Ever Use
\`python
import requests
def find_subdomains(domain):
"""Find all subdomains via Certificate Transparency logs."""
response = requests.get(
f"https://crt.sh/?q=%25.{domain}&output=json",
timeout=30
)
if response.status_code == 200:
certs = response.json()
# Extract unique subdomains
subdomains = set()
for cert in certs:
name = cert.get("name_value", "")
for line in name.split("\n"):
line = line.strip().lower()
if line and "*" not in line:
subdomains.add(line)
subdomains = sorted(subdomains)
print(f"Domain: {domain}")
print(f"Certificates found: {len(certs)}")
print(f"Unique subdomains: {len(subdomains)}")
for sub in subdomains[:20]:
print(f" {sub}")
if len(subdomains) > 20:
print(f" ... and {len(subdomains) - 20} more")
return subdomains
Find all subdomains for a domain
find_subdomains("github.com")
`\
Certificate History
See every certificate ever issued for a domain:
\`python
def cert_history(domain):
"""Get certificate issuance history."""
response = requests.get(
f"https://crt.sh/?q={domain}&output=json",
timeout=30
)
if response.status_code == 200:
certs = response.json()
print(f"Total certificates for {domain}: {len(certs)}")
# Sort by most recent
certs.sort(key=lambda c: c.get("not_before", ""), reverse=True)
for cert in certs[:10]:
issuer = cert.get("issuer_name", "Unknown")
not_before = cert.get("not_before", "?")
not_after = cert.get("not_after", "?")
# Extract issuer organization
issuer_org = "Unknown"
if "O=" in issuer:
issuer_org = issuer.split("O=")[1].split(",")[0]
print(f"\n Issued: {not_before}")
print(f" Expires: {not_after}")
print(f" Issuer: {issuer_org}")
print(f" ID: {cert.get('id', '?')}")
cert_history("example.com")
`\
Monitor New Certificates
\`python
from datetime import datetime, timedelta
def monitor_new_certs(domain, days=7):
"""Find certificates issued in the last N days."""
response = requests.get(
f"https://crt.sh/?q=%25.{domain}&output=json",
timeout=30
)
if response.status_code == 200:
certs = response.json()
cutoff = (datetime.now() - timedelta(days=days)).strftime("%Y-%m-%d")
recent = [c for c in certs if c.get("not_before", "") >= cutoff]
print(f"New certificates for *.{domain} in last {days} days: {len(recent)}")
for cert in recent[:10]:
name = cert.get("name_value", "?").split("\n")[0]
issued = cert.get("not_before", "?")
issuer = cert.get("issuer_name", "")
issuer_short = "Unknown"
if "O=" in issuer:
issuer_short = issuer.split("O=")[1].split(",")[0]
print(f" {issued} | {name} | {issuer_short}")
monitor_new_certs("google.com", days=3)
`\
Detect Phishing Domains
\`python
def find_lookalikes(brand):
"""Find certificates for domains that look like a brand (phishing detection)."""
response = requests.get(
f"https://crt.sh/?q=%25{brand}%25&output=json",
timeout=30
)
if response.status_code == 200:
certs = response.json()
# Extract unique domains
domains = set()
for cert in certs:
for name in cert.get("name_value", "").split("\n"):
name = name.strip().lower()
if name and brand.lower() in name and "*" not in name:
domains.add(name)
# Filter out the real domain
suspicious = [d for d in sorted(domains) if not d.endswith(f".{brand}.com")]
print(f"Potential lookalike domains for '{brand}': {len(suspicious)}")
for d in suspicious[:15]:
print(f" ⚠ {d}")
find_lookalikes("paypal")
`\
What You Can Build
- Subdomain enumeration — discover the full attack surface
- Certificate monitoring — alert on unauthorized cert issuance
- Phishing detection — find lookalike domains abusing your brand
- Compliance audit — verify all certs are from approved CAs
- Bug bounty recon — find forgotten subdomains with weak security
Zero cost. Zero authentication. The most underrated OSINT tool.
More free security APIs on my GitHub.
Top comments (0)