threatfound
Attack Surface & Exposure
Attack Surface & Exposure · lesson 04

Certificate Transparency for subdomain discovery

Certificate Transparency logs are public, append-only records of every TLS certificate a CA issues — a passive goldmine that reveals staging, internal, and forgotten subdomains the instant they get a cert.

8 min read

Certificate Transparency (CT) is a system of public, append-only logs where Certificate Authorities record every TLS certificate they issue. Defined by RFC 6962 and enforced by browser policy — Chrome and Safari reject certificates that lack a valid SCT (Signed Certificate Timestamp), the log's signed promise that it has received the certificate and will publish it — it means every hostname you get a cert for becomes a public record within seconds. For anyone mapping an organization's attack surface, that is one of the richest passive data sources available.

Why CT logs exist

CT was created to catch mis-issued certificates: a CA fooled into signing a cert for a domain it should never have, whether through compromise, error, or a rogue insider. Before CT, such a cert could be used silently to intercept traffic and nobody would know. By forcing every issuance into a public log that anyone can audit, domain owners and researchers can monitor for certificates they never requested and revoke them. The transparency that protects defenders, however, is the same transparency that hands a map to attackers.

  • Append-only and public — entries cannot be deleted or hidden after the fact.
  • Merkle-tree backed — the log is tamper-evident and cryptographically auditable, so once a certificate is submitted the log cannot quietly drop it or alter the record.
  • Browser-enforced — a public cert without SCTs is untrusted, so issuance without logging is not a practical option.

Turning certificates into subdomains

Every certificate carries the hostnames it covers in its Common Name and Subject Alternative Name fields. Query the logs for a domain and you get back the full list of hostnames that have ever been certified for it — including the ones nobody meant to expose. dev., staging., vpn., jenkins., internal-api., and long-abandoned hosts routinely show up because someone, at some point, ran an ACME client or clicked issue in a panel.

The fastest entry point is crt.sh, a searchable frontend over the CT logs. Its JSON output pipes straight into a hostname list:

# Pull every logged name for a domain and its subdomains
curl -s 'https://crt.sh/?q=%25.example.com&output=json' \
  | jq -r '.[].name_value' \
  | sed 's/\*\.//g' \
  | sort -u

# The %25 is a URL-encoded % wildcard; matches any subdomain

Dedicated recon tools fold CT into a broader passive sweep, correlating it with other public sources so you are not relying on one log or one API:

# subfinder — CT is one of many passive sources it queries
subfinder -d example.com -all -silent

# amass passive mode — CT plus DNS aggregators, no packets to the target
amass enum -passive -d example.com
note

This is passive reconnaissance. You are reading public logs and third-party databases, never sending a single packet to the target's infrastructure. Nothing here touches their servers or shows up in their logs, which is exactly why it is a first move in any assessment.

What CT will not show you

CT is powerful but not complete, and treating it as the whole picture leaves gaps:

  • Wildcard certificates hide specific names. A cert issued for *.example.com proves subdomains exist but names none of them — secret-admin.example.com stays invisible behind the wildcard.
  • Only certified names appear. A host served over plain HTTP, behind an IP with no cert, or using a cert from a private internal CA that never touches public logs will not be in CT at all.
  • Names can be stale. A hostname in an old cert may no longer resolve or may point somewhere new — CT tells you a cert was issued, not that the host is live.

Because of these gaps, CT is a starting layer, not the finish line. Combine it with DNS brute forcing (resolving a wordlist of candidate names against the target's nameservers), reverse-DNS sweeps, search-engine and archive scraping, and ASN or IP-range analysis. Each source catches what the others miss; CT's job is to hand you the real, human-chosen names that no wordlist would ever guess.

careful

Reading CT logs is public data and requires no permission. But acting on what you find — resolving, probing, scanning, or connecting to the hosts you discover — is active testing. Only do that against assets you own or have explicit written authorization to test. Discovery is passive; exploitation is not, and the legal line sits between them.

tip

Set up continuous CT monitoring for your own domains. Services like crt.sh support periodic queries, and CT-watch tools can alert you the moment a new certificate is logged for your namespace. This catches both shadow IT (a team spinning up an unsanctioned host) and genuinely malicious mis-issuance — often before an attacker's own recon finds it.

The defense

You cannot opt out of CT — it is baked into how the web's certificate trust works — so the only sound posture is to assume it. Adopt one operating principle: the instant you get a public certificate for a hostname, that hostname is public knowledge. Design accordingly.

  • Never treat a subdomain as secret. staging-x9f2.example.com will be in the logs within seconds of issuance; obscurity in the name buys you nothing. Put real authentication, IP allowlisting, or a VPN in front of anything not meant for the public.
  • Inventory yourself first. Run the same crt.sh and subfinder queries against your own domains on a schedule. Whatever an attacker would find, find it before they do and either lock it down or decommission it.
  • Hunt for forgotten hosts. CT is the most reliable way to surface the dev box or demo site someone stood up two years ago and never took down — the exact stale, unpatched target attackers love.
  • Consider wildcard certs for genuinely internal names so specific hostnames stay out of the logs — but only as defense in depth, never as the sole control, since the host is still reachable if someone guesses or brute-forces the name.