| name | analyzing-certificate-transparency-for-phishing |
| description | Monitor Certificate Transparency logs using crt.sh and Certstream to detect phishing domains, lookalike certificates, and unauthorized certificate issuance targeting your organization. |
| domain | cybersecurity |
| subdomain | threat-intelligence |
| tags | ["certificate-transparency","ct-logs","phishing","crt-sh","certstream","ssl","domain-monitoring","threat-intelligence"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
| atlas_techniques | ["AML.T0052"] |
| nist_csf | ["ID.RA-01","ID.RA-05","DE.CM-01","DE.AE-02"] |
| mitre_attack | ["T1583.001","T1583.004","T1566.002","T1608.005","T1596.003"] |
| mitre_f3 | {"version":"1.1","tactics":["resource-development","reconnaissance","initial-access"],"techniques":[{"id":"T1583.001","name":"Acquire Infrastructure: Domains","tactic":"resource-development","source":"attack"},{"id":"F1020.002","name":"Create Fake Materials: Fake Website","tactic":"resource-development","source":"f3"},{"id":"T1593","name":"Search Open Websites/Domains","tactic":"reconnaissance","source":"attack"},{"id":"T1598","name":"Phishing for Information","tactic":"reconnaissance","source":"attack"},{"id":"T1660","name":"Phishing","tactic":"initial-access","source":"attack"}]} |
Analyzing Certificate Transparency for Phishing
Overview
Certificate Transparency (CT) is an Internet security standard that creates a public, append-only log of all issued SSL/TLS certificates. Monitoring CT logs enables early detection of phishing domains that register certificates mimicking legitimate brands, unauthorized certificate issuance for owned domains, and certificate-based attack infrastructure. This skill covers querying CT logs via crt.sh, real-time monitoring with Certstream, building automated alerting for suspicious certificates, and integrating findings into threat intelligence workflows.
When to Use
- When investigating security incidents that require analyzing certificate transparency for phishing
- When building detection rules or threat hunting queries for this domain
- When SOC analysts need structured procedures for this analysis type
- When validating security monitoring coverage for related attack techniques
Prerequisites
- Python 3.9+ with
requests, certstream, tldextract, Levenshtein libraries
- Access to crt.sh (https://crt.sh/) for historical CT log queries
- Certstream (https://certstream.calidog.io/) for real-time monitoring
- List of organization domains and brand keywords to monitor
- Understanding of SSL/TLS certificate structure and issuance process
Key Concepts
Certificate Transparency Logs
CT logs are cryptographically assured, publicly auditable, append-only records of TLS certificate issuance. Major CAs (Let's Encrypt, DigiCert, Sectigo, Google Trust Services) submit all issued certificates to multiple CT logs. As of 2025, Chrome and Safari require CT for all publicly trusted certificates.
Phishing Detection via CT
Attackers register lookalike domains and obtain free certificates (often from Let's Encrypt) to make phishing sites appear legitimate with HTTPS. CT monitoring detects these early because the certificate appears in logs before the phishing campaign launches, providing a window for proactive blocking.
crt.sh Database
crt.sh is a free web interface and PostgreSQL database operated by Sectigo that indexes CT logs. It supports wildcard searches (%.example.com), direct SQL queries, and JSON API responses. It tracks certificate issuance, expiration, and revocation across all major CT logs.
Workflow
Step 1: Query crt.sh for Certificate History
import requests
json
datetime datetime
tldextract
:
CRT_SH_URL =
():
.monitored_domains = monitored_domains
.brand_keywords = [k.lower() k brand_keywords]
():
params = {
: ,
: ,
}
include_expired:
params[] =
resp = requests.get(.CRT_SH_URL, params=params, timeout=)
resp.status_code == :
certs = resp.json()
()
certs
[]
():
certs = .query_crt_sh(domain)
suspicious = []
cert certs:
common_name = cert.get(, ).lower()
name_value = cert.get(, ).lower()
issuer = cert.get(, )
not_before = cert.get(, )
not_after = cert.get(, )
extracted = tldextract.extract(common_name)
cert_domain =
cert_domain == domain:
flags = []
domain.replace(, ) common_name.replace(, ):
flags.append()
(kw common_name kw .brand_keywords):
flags.append()
issuer.lower():
flags.append()
flags:
suspicious.append({
: cert.get(, ),
: cert.get(, ),
: issuer,
: not_before,
: not_after,
: cert.get(, ),
: flags,
: cert.get(, ),
: ,
})
()
suspicious
monitor = CTLogMonitor(
monitored_domains=[, ],
brand_keywords=[, , ],
)
suspicious = monitor.find_suspicious_certs()
cert suspicious[:]:
()