コンテンツにスキップ

certgraph

certgraph is a powerful reconnaissance tool for mapping relationships between SSL certificates using Certificate Transparency (CT) logs. It crawls CT logs to find all certificates issued for a domain, then queries those certificates to discover additional domains and subdomains. This creates a visual “graph” of the certificate infrastructure, revealing domains that may not be publicly listed.

# Prerequisites: Go 1.11+
go get -u github.com/lanrat/certgraph

# Or clone and build manually
git clone https://github.com/lanrat/certgraph.git
cd certgraph
go build
./certgraph -h
brew install certgraph
certgraph -version
# Install Go (if not present)
wget https://golang.org/dl/go1.21.0.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz

# Build certgraph
git clone https://github.com/lanrat/certgraph.git
cd certgraph
/usr/local/go/bin/go build
sudo mv certgraph /usr/local/bin/
certgraph -version
certgraph -help
# Basic usage - discover all certificates for domain
certgraph example.com

# Output shows certificate chain and discovered domains
example.com (root domain)
├── Certificate: XXXXX (issued to example.com, www.example.com)
│   ├── domain: api.example.com
│   ├── domain: cdn.example.com
│   └── domain: mail.example.com
├── Certificate: YYYYY (wildcard *.example.com)
│   ├── domain: staging.example.com
│   ├── domain: dev.example.com
│   └── domain: test.example.com
└── Certificate: ZZZZZ (issued to example.com)
    └── domain: internal.example.com
OptionDescriptionExample
-domainTarget domaincertgraph -domain example.com
-depthGraph traversal depthcertgraph -domain example.com -depth 2
-limitMax certificates to fetchcertgraph -domain example.com -limit 1000
-verboseVerbose outputcertgraph -domain example.com -verbose
-quietMinimal outputcertgraph -domain example.com -quiet
OptionDescriptionOutput Format
-jsonJSON output{ “domains”: […], “certificates”: […] }
-dotGraphviz DOT formatdigraph { … }
-csvCSV formatdomain,certificate,issuer
-listSimple domain listapi.example.com
OptionDescriptionDefault
-depthHow deep to traverse1
-timeoutCT log query timeout30s
-parallelParallel queries4
-dnsQuery DNS for verificationtrue
# Find certificates directly issued for example.com
certgraph -domain example.com -depth 0

# Output: Only certificates with example.com in SAN
# Find certificates for example.com and domains found in those certificates
certgraph -domain example.com -depth 1

# Finds: example.com → [cert domains] → no further traversal
# Expand search to related domains found in depth 1 certificates
certgraph -domain example.com -depth 2

# Finds: example.com → [cert domains] → [their cert domains]
# WARNING: Depth > 3 can take a long time
certgraph -domain example.com -depth 3 -limit 5000

# Only use for organizations with many related domains
certgraph -domain example.com -json > results.json
{
  "root": "example.com",
  "domains": [
    "example.com",
    "api.example.com",
    "cdn.example.com",
    "staging.example.com"
  ],
  "certificates": [
    {
      "fingerprint": "sha256:abc123...",
      "issuedTo": ["example.com", "api.example.com"],
      "issuer": "Let's Encrypt",
      "notBefore": "2026-01-01T00:00:00Z",
      "notAfter": "2027-01-01T00:00:00Z"
    }
  ]
}
certgraph -domain example.com -csv > domains.csv
domain,certificate_fingerprint,issuer,valid_from,valid_to
example.com,sha256:abc123...,Let's Encrypt,2026-01-01,2027-01-01
api.example.com,sha256:abc123...,Let's Encrypt,2026-01-01,2027-01-01
cdn.example.com,sha256:def456...,Cloudflare,2026-02-01,2027-02-01
# Generate Graphviz format
certgraph -domain example.com -dot > domains.dot

# Convert to PNG
dot -Tpng domains.dot -o domains.png
digraph {
  "example.com" -> "api.example.com"
  "example.com" -> "cdn.example.com"
  "api.example.com" -> "internal.api.example.com"
}
# Output just discovered domains
certgraph -domain example.com -list

# Output:
# example.com
# api.example.com
# cdn.example.com
# staging.example.com
Browser Issues Certificate

   Certificate Logged to CT Log

   certgraph Queries CT Log

   Discovers Certificate Details

   Extracts All Domains (SAN)
CT LogOperatorCoverage
Google ArgonGoogle~60% of CAs
Google TesseractGoogleSSL/TLS certs
Sectigo CT LogsSectigoPublic CAs
DigiCert CT LogsDigiCertDigiCert issued
# certgraph queries configured CT logs automatically
# Logs are hardcoded, no CLI override (yet)

# Typical: 4-6 major CT logs queried per domain
certgraph -domain example.com -verbose

# Output will show which logs are being queried
# Find *.example.com certificates
certgraph -domain example.com

# May reveal:
# *.example.com (wildcard cert)
# staging.example.com (issued to wildcard)
# dev.example.com
# test.example.com
# internal.example.com
certgraph -domain amazon.com -depth 1 | head -20

# Output may include:
# amazon.com
# www.amazon.com
# api.amazon.com
# s3.amazonaws.com
# ec2.amazonaws.com
# rds.amazonaws.com
# lambda.amazonaws.com
# For large organizations with multiple subdomains
certgraph -domain company.com -depth 2 -limit 2000

# Discovers: internal divisions, geographic branches, acquisitions
# Save to file and filter
certgraph -domain example.com > results.txt

# Keep only subdomains
grep "^\." results.txt

# Keep only specific pattern
certgraph -domain example.com | grep "api\|staging\|test"

# Exclude wildcards
certgraph -domain example.com | grep -v "\*"
# Verify discovered domains resolve (optional)
certgraph -domain example.com -dns

# Only shows domains that resolve via DNS
# Filters out dangling/inactive subdomains
# 1. Export DOT format
certgraph -domain example.com -dot > cert_graph.dot

# 2. Convert to PNG
dot -Tpng cert_graph.dot -o cert_graph.png

# 3. Convert to SVG (for web)
dot -Tsvg cert_graph.dot -o cert_graph.svg

# 4. View with graphviz tools
circo -Tpng cert_graph.dot -o circular.png  # Circular layout
neato -Tpng cert_graph.dot -o spring.png    # Spring layout
# Export as JSON for custom processing
certgraph -domain example.com -json | jq '.domains[]' > domains.txt

# Feed into other reconnaissance tools
cat domains.txt | while read domain; do
  nmap -p 80,443 $domain
done
# Complement certgraph with subfinder
certgraph -domain example.com -list > cert_domains.txt
subfinder -d example.com -o subfinder_domains.txt

# Combine and deduplicate
cat cert_domains.txt subfinder_domains.txt | sort -u > all_domains.txt
# Use certgraph for CT-based discovery
certgraph -domain example.com -json > ct_results.json

# Cross-reference with assetfinder
assetfinder --subs-only example.com | sort -u > asset_domains.txt

# Find domains in cert but not in assetfinder (potential shadow IT)
comm -13 asset_domains.txt cert_domains.txt
# Enumerate domains
certgraph -domain example.com -list > targets.txt

# Scan discovered domains
nmap -sV -p 80,443 -iL targets.txt -oX results.xml
#!/bin/bash

DOMAIN=$1

echo "[*] Running certgraph..."
certgraph -domain $DOMAIN -json -limit 1000 > ct_results.json

echo "[*] Extracting domains..."
jq -r '.domains[]' ct_results.json | sort -u > domains.txt

echo "[*] Resolving domains..."
while read domain; do
  if dig +short $domain &>/dev/null; then
    echo "[+] Active: $domain"
  else
    echo "[-] Inactive: $domain"
  fi
done < domains.txt > active_domains.txt

echo "[*] Port scanning..."
nmap -p 80,443 -iL active_domains.txt -oX nmap_results.xml

echo "[*] Done! Results in domains.txt, active_domains.txt, nmap_results.xml"
# Increase parallel queries for speed
certgraph -domain example.com -depth 1 -parallel 8

# Speed up large enumerations (caution: may hit rate limits)
# Default: 4, Range: 1-16
# Increase timeout for slow networks
certgraph -domain example.com -timeout 60s

# Default: 30s
# If hitting rate limits:
# 1. Reduce parallel queries
certgraph -domain example.com -parallel 2

# 2. Increase timeout
certgraph -domain example.com -timeout 90s

# 3. Wait and retry
sleep 300
certgraph -domain example.com
certgraph -domain example.com -csv | grep -E "cloudflare|aws|azure|gcp"

# May reveal cloud infrastructure usage
# Subdomains with different naming patterns may indicate:
# - Company acquisitions (product.acquired-company.com)
# - Third-party integrations
# - Regional operations (region.example.com)

certgraph -domain company.com -depth 2 | sort | uniq
certgraph -domain example.com -json | \
  jq '.certificates[] | {issuer, notAfter}' | \
  grep "2024\|2025"  # Find soon-to-expire certs
# Initial reconnaissance
certgraph -domain target.com -depth 1 -list > in-scope.txt

# Find all subdomains
certgraph -domain target.com -depth 2 -list > all-subdomains.txt

# Filter likely in-scope
grep "target.com$" all-subdomains.txt > final-targets.txt
# Map organization's public SSL infrastructure
certgraph -domain company.com -depth 2 -json > company_certs.json

# Analyze coverage
jq '.certificates | length' company_certs.json

# List all public facing domains
jq -r '.domains[]' company_certs.json | grep -v "\*"
# Discover competitor's infrastructure
certgraph -domain competitor.com -depth 1 -list

# Reveals: services, acquisitions, integrations
# 1. Verify domain has SSL certificates
certgraph -domain example.com -verbose

# 2. Check if domain is in CT logs
# (New/obscure domains may not be logged yet)

# 3. Try with larger limit
certgraph -domain example.com -limit 5000
# 1. Reduce depth to save time
certgraph -domain example.com -depth 1

# 2. Reduce limit
certgraph -domain example.com -limit 500

# 3. Run without DNS verification
# (DNS lookup is slowest part)
# CT logs have rate limits (~100 queries/minute)
# Solutions:
# 1. Reduce parallel queries
certgraph -domain example.com -parallel 2

# 2. Wait before retrying
sleep 60

# 3. Use smaller limit
certgraph -domain example.com -limit 100
# 1. Quick initial scan
certgraph -domain example.com -depth 1 > quick_results.txt

# 2. Export for visualization
certgraph -domain example.com -dot > structure.dot

# 3. Detailed analysis
certgraph -domain example.com -depth 2 -json > detailed.json

# 4. Integration with other tools
certgraph -domain example.com -list | while read sub; do
  echo "Testing: $sub"
  # Run additional tests
done
# Multi-format export for sharing
certgraph -domain example.com -list > domains.txt
certgraph -domain example.com -json > domains.json
certgraph -domain example.com -csv > domains.csv
certgraph -domain example.com -dot > domains.dot
# Create timestamp-dated results
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
certgraph -domain example.com -json > results_$TIMESTAMP.json
certgraph -domain example.com -dot > graph_$TIMESTAMP.dot

# Version control
git add results_*.json
git commit -m "CT log enumeration for example.com"
ToolPurposeComparison
subfinderDNS-based subdomain enumerationFaster, broader
assetfinderMultiple sources (CT, TLS, etc)More comprehensive
crt.shWeb interface to CT logsManual, slower
ShodanNetwork device searchDifferent approach
CensysCertificate database searchMore detailed certs
ResourceURL
GitHub Repositoryhttps://github.com/lanrat/certgraph
Certificate Transparency Projecthttps://www.certificate-transparency.org/
crt.sh Web Toolhttps://crt.sh
CT Log Listhttps://www.certificate-transparency.org/known-logs
Google CT Logshttps://ct.googleapis.com/logs/