Type
Guide
Published
Reading time
6 min read
Author
rootzero
Lire en français
Lire en français →

Attack surface mapping: CT logs, forgotten assets and typosquats

Certificate Transparency, forgotten staging servers, open cloud storage, typosquats, SPF/DKIM/DMARC: what an attacker sees of you before you do.

  • Exposure
  • Network
  • Web
  • Governance

Ask a team for the list of its services exposed on the Internet. It will produce an inventory: the website, the extranet, the webmail, two APIs. Then ask for the same list from someone who only has public sources and never touches your servers. Their list may reveal names missing from the internal inventory; each name still needs verification.

The gap between the two is the forgotten attack surface: services that exist, answer, and that nobody monitors. The ANSSI guide to IT hygiene (France’s national cybersecurity agency) places knowledge of your information system among its very first measures, ahead of hardening, since an unknown asset receives neither patches nor monitoring.

The examples below use the fictional domain example.com.

What certificates reveal

With Certificate Transparency (RFC 6962), certificate authorities publish the certificates they issue in public logs. The major browsers require this publication before they trust a certificate. Every name for which you have obtained a public TLS certificate can therefore be looked up by anyone, including names you never announced.

The crt.sh service indexes these logs:

# Every name seen in certificates for example.com and its subdomains
curl -s "https://crt.sh/?q=%25.example.com&output=json" \
  | jq -r '.[].name_value' | tr 'A-Z' 'a-z' | sort -u

Results may include staging.example.com, vpn2.example.com, jenkins.example.com or old-crm.example.com: in other words, a readable history of past projects, migrations and suppliers. A wildcard certificate (*.example.com) hides individual names without preventing anything: DNS enumeration, search engines and web archives take over.

Working through the list

Run this query against your own domains. A name in a certificate need not still resolve or serve anything. For each name, ask three questions: does it still exist, who is responsible for it, and should it remain public? A reachable service with no identified owner deserves prompt investigation.

Forgotten staging and test environments

Test environments are one case to check. Created quickly, for a project, by a team that will eventually move on, they often run with debug mode enabled (stack traces and environment variables on display), test accounts with trivial passwords, a copy of production data that is sometimes complete, and components that are never updated.

A staging environment reachable from the Internet gives an attacker the same opportunities as production, often with less resistance. The effective measures are simple: authentication placed in front of the application (SSO, VPN or at least an IP address restriction), anonymised data and an end date set at creation. A robots.txt file or a noindex tag protects nothing. They ask search engines not to index, and in doing so point out where to look.

Orphaned DNS records

Take a subdomain that points, through a CNAME, to a deleted cloud resource: a hosted application, a storage bucket, a static page. If the provider lets any customer recreate a resource with the same name, an attacker can create it and serve whatever content they like under your domain. That gives them credible phishing, access to session cookies depending on their scope, or a way around security policies based on the domain. The OWASP testing guide describes this subdomain takeover under reference WSTG-CONF-10.

A first DNS check:

# What does this name point to, and does the target still exist?
dig +short CNAME promo2024.example.com
dig +short promo2024.example.com

A DNS response alone does not prove that a resource can be claimed: check the behaviour of that specific provider. When decommissioning, order matters: delete the DNS record first, then the resource. In the reverse order, a window opens during which the name points to a resource that anyone can claim.

Open cloud storage

An S3 bucket, an Azure Blob container or a Google Cloud Storage bucket can become public with one ticked box. Temporary public access can outlive the sharing need; give each exception an owner and an expiry date.

To test anonymous listing on a bucket you manage, try this request without credentials:

# A denied listing does not prove that anonymous object reads are denied
aws s3 ls s3://example-exports/ --no-sign-request

A denied listing does not rule out a public object accessible by its direct URL; also inspect the bucket policy, ACLs and object permissions in your account. On AWS, Block Public Access applied at account level prevents these accidental exposures. Azure and Google Cloud offer equivalent controls at storage account or organisation level. Public code repositories follow the same logic: an API key committed by mistake and then deleted remains readable in the Git history.

Domains that look like yours

Your attack surface also includes domains you do not own. example-com.net, examp1e.com or example.com.secure-login.example are used to phish your customers and staff, and to set up payment fraud.

The open source tool dnstwist generates plausible variants of a name (omissions, swaps, homoglyphs, changes of extension) and checks which ones are registered:

dnstwist --registered example.com

Once a typosquat has been spotted, several responses are possible: monitor it, report it to anti-phishing lists, or ask the hosting provider or registrar to suspend it. For .fr names, Afnic (the French registry) offers a dispute resolution procedure, SYRELI. Registering the most obvious variants yourself is often the cheapest option.

Your domain as a sender

One angle is often neglected: the ability of a third party to send email in the name of your domain. Three complementary mechanisms limit it. SPF (RFC 7208) declares which servers may send for the domain. DKIM (RFC 6376) signs messages cryptographically. DMARC (RFC 7489) tells recipients what to do with a message that fails these checks, and sends you reports.

dig +short TXT example.com | grep spf1
dig +short TXT _dmarc.example.com
dig +short TXT selector1._domainkey.example.com   # the selector depends on your provider

A DMARC policy of p=none is for collecting reports; spoofed messages are still delivered. The goal is p=quarantine and then p=reject, once the rua reports have been analysed and every legitimate source declared.

Domains that send no email at all (campaign names, former brands, defensive typosquats) are ideal targets for spoofing, precisely because nobody watches them. Lock them down explicitly:

example-promo.com.          TXT  "v=spf1 -all"
_dmarc.example-promo.com.   TXT  "v=DMARC1; p=reject;"
example-promo.com.          MX   0 .        ; "null MX", RFC 7505

The null MX (RFC 7505) declares that the domain does not accept email.

From a one-off inventory to continuous monitoring

Everything above can be done by hand, once. The difficulty is that the attack surface changes constantly: a new certificate every week, a bucket created for a demo, a supplier deploying a subdomain, a lookalike domain registered on a Friday evening. A yearly inventory describes a state that has already changed by the time you read it.

DataShield, rootzero’s attack surface management product, automates this discovery and monitoring work: it maps what the Internet knows about you, watches it every day and ranks the signals by severity. The starting rule remains organisational and no tool replaces it: every exposed asset has a named owner and an end date.

#Product · DataShield

See what the Internet knows about you.

DataShield discovers and monitors your real exposure (subdomains, services, storage, lookalike domains) and ranks signals by severity.