Back to Blog

Attackers Hijacked Three ccTLD Registries for Google Certificates. The Cleanup Starts When DNS Comes Back.

Hijacks of the .gh, .sl and .as registries got Let's Encrypt and ZeroSSL certificates issued for Google and YouTube domains in September 2026. CAA couldn't stop it, and cached domain validation outlives the hijack. Here's what to monitor and what to do once you have DNS back.

CertGuard TeamSSL Security Experts11 min read
A bright, empty data centre hall with a white tiled raised floor, rows of black and white server cabinets and blue network cables looping down from overhead cable trays, an orange traffic cone standing between the cabinets

Google got hijacked one level above its own DNS

Google runs its own certificate authority. It has CAA records, static pins in Chrome and a security team bigger than most companies. Between 22 and 27 September, someone still got Let's Encrypt and ZeroSSL to issue valid certificates for google.sl, google.as, google.com.gh and a handful of YouTube names.

Google wasn't breached. The registries for Ghana (.gh), Sierra Leone (.sl) and American Samoa (.as) were. The attackers changed authoritative DNS for names under those TLDs, passed domain validation the normal way, and walked off with certificates that every browser trusted. Google's own write-up, Chrome's Response to Recent ccTLD Registry Hijacks (6 October), says plainly that it has "no reason to believe" the issuing CAs did anything wrong.

That's the uncomfortable part. Every control in the chain did exactly what it was built to do, and the attacker still won for a few days. If it can happen to Google's regional domains, it can happen to the .io, .co or .me name your API lives on.

The timeline from the CT logs

Google didn't name the domains. The Hacker News went through Certificate Transparency and found at least 12 certificates covering seven Google and YouTube domains:

  • .gh certificates logged on 22 September, revoked on 26 September
  • .sl certificates logged on 25 September, mostly revoked on 1 October
  • .as certificates logged on 27 September, revoked on 1 October

Eleven came from Let's Encrypt, one from ZeroSSL. I pulled the .sl and .as entries from Cert Spotter myself and the revocation timestamps match: 1 October, 19:36 UTC for .sl and 19:18 UTC for .as. Matthew McPherrin of Let's Encrypt confirmed it on the community forum: "Yes, certificates for Google and Youtube were issued, and have been revoked."

Look at that sequence again. The .as certificates were issued a day after the .gh ones were revoked. Revocation didn't stop the campaign. The attackers just moved to the next registry.

Chrome blocked the certificates through CRLSets, Google's push-based blocklist, and then used CT data to find and block certificates for other organizations hit by the same attacks. It didn't name them either, except as "leading global brands and widely used online services." The HN thread on Ars Technica's coverage spent a while arguing about whether pinning would have helped. It wouldn't have, for anyone outside Chrome. Google says so itself: its interventions do not "reliably protect non-Chrome users."

Your DNS dashboard will show nothing wrong

Registry compromise is a different animal from the attacks most teams plan for. Your zone file at Cloudflare or Route 53 is untouched, and so is your registrar account. The registry answers queries for the TLD, so it can point your delegation at someone else's name servers, and every resolver on the internet follows along.

DNSSEC doesn't save you here either. The registry publishes your DS record, so whoever controls the registry controls which keys count as yours. If you came here from our post on DNSSEC as a certificate dependency, this is the other side of it. DNSSEC only covers the path below the registry.

Multi-perspective validation doesn't help, because it was built for localized routing hijacks. A registry hijack is global. Every vantage point the CA checks from gets the same lie.

What you can do is watch what the parent zone says about you, independently of your own provider:

# Ask a TLD server directly what it delegates your domain to
TLD_NS=$(dig +short NS com.gh | head -1)
dig +norecurse @"$TLD_NS" example.com.gh NS

The NS records in the authority section should be the name servers you pay for. Put that in a monitor that runs every few minutes and alerts on any change. It's crude. It's also the only check here that actually looks at the layer that got hit.

CAA was never going to stop this

CAA is checked at issuance, by the CA, through DNS. If an attacker controls the DNS answers, they control your CAA record too. Delete it, or rewrite it to name their own CA and account, and the CA will honour it, because that's how CAA is supposed to work. Google's post says it directly: CAA "can not prevent certificate issuance during an active DNS hijack."

On 8 October, google.sl, google.as and google.com.gh all serve 0 issue "pki.goog", restricting issuance to Google Trust Services. Whether those records were in place before the hijack doesn't really matter. During the hijack the attackers were the ones answering CAA queries.

So why does Google tell everyone to publish strict CAA records with account binding? Because of what happens after.

The hijack ends, but the validation doesn't

CAs are allowed to cache a successful domain validation and reuse it for later orders. Under Baseline Requirements section 4.2.1, domain validation data can be reused for up to 200 days since 15 March 2026. It drops to 100 days on 15 March 2027 and to 10 days on 15 March 2029. That schedule comes from ballot SC-081v3, passed in April 2025.

Let's Encrypt is stricter than the rules require. Its authorization reuse period is 30 days today, and for the default classic profile its December 2025 announcement says that falls to 10 days on 10 February 2027 and 7 hours on 16 February 2028.

So you get your delegation back. Your DNS is clean. The attacker's ACME account still holds a valid authorization for your domain, and that authorization doesn't care who runs your name servers today. For the next 30 days, at Let's Encrypt, they can order fresh certificates without passing a single new challenge. At a CA that uses the full BR allowance, the window is measured in months.

The one thing every issuance still has to pass is CAA. Section 4.2.2.1 requires the CA to fetch and process CAA as part of every issuance, cached validation or not. That's why CAA still matters. It's the only control that's re-evaluated after you've regained control of DNS.

But a bare issue "letsencrypt.org" doesn't help if the attacker used Let's Encrypt. Their account is a Let's Encrypt account. You need the binding:

example.com.  CAA 0 issue "letsencrypt.org;accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/1234567890"
example.com.  CAA 0 issuewild ";"

With accounturi, the attacker's cached authorization is worthless, because their account isn't the one you named. Let's Encrypt honours it now. Every public CA has to from 15 March 2027, under ballot SC098v2. I covered setup and the ways it can break your own renewals in pinning CAA to one ACME account. Read that before you deploy it. A pinned record with a lost account key is an outage you scheduled yourself, which is why the account key is now production-critical.

Watch CT for the names you forgot you own

Google's advice is to monitor CT across your "entire domain portfolio, including parked or regional ccTLD properties." That clause is doing a lot of work. Nobody watches example.com.gh. It redirects to .com, it was registered in 2014 to stop squatters, and its certificate gets renewed by something nobody remembers setting up.

Those are the names that got hit. Here's a script that lists every logged certificate for a domain from an issuer you didn't expect, using SSLMate's Cert Spotter API:

#!/usr/bin/env bash
# ct-unexpected.sh DOMAIN "Expected CA name"
set -euo pipefail
domain="$1"; expected="$2"; after=""
while :; do
  page=$(curl -s "https://api.certspotter.com/v1/issuances?domain=${domain}&include_subdomains=true&expand=dns_names&expand=issuer&expand=revocation${after:+&after=$after}")
  if ! echo "$page" | jq -e 'type == "array"' >/dev/null; then
    echo "Cert Spotter error: $page" >&2; exit 2
  fi
  [ "$(echo "$page" | jq length)" -eq 0 ] && break
  echo "$page" | jq -r --arg exp "$expected" '.[]
    | select(.issuer.friendly_name != $exp)
    | [.not_before, .issuer.friendly_name, (.dns_names | join(",")), (.revocation.time // "NOT REVOKED")]
    | @tsv'
  after=$(echo "$page" | jq -r '.[-1].id')
done

Run against google.as with "Google Trust Services" as the expected issuer, it prints the three Let's Encrypt certificates from 27 September with their 1 October revocation times. The unauthenticated quota is small, and I hit it within a few domains. For a real portfolio, get an API key and send it as Authorization: Bearer.

The script takes ten minutes. The domain list is where you'll lose the afternoon. Pull it from your registrar accounts, not from whatever your Terraform happens to manage. If your CT alerting already drowns you, the post on CT monitoring at scale covers filtering. "Issuer is not the CA we use" is the best filter you'll find, and it fires on exactly this case.

Revoke it without the attacker's account

You found a certificate you didn't order. You don't need the attacker's key to kill it. The Let's Encrypt revocation docs describe the procedure: prove control of the names from your own account, then revoke as if you'd issued the cert.

# Get authorizations without issuing: the bogus name makes the order fail
certbot certonly --manual --preferred-challenges=dns \
  -d example.com -d nonexistent.example.com

# Download the rogue cert as PEM from crt.sh, then
certbot revoke --cert-path ./rogue-cert.pem

For other CAs, file a Certificate Problem Report using the contact in their CPS. Under BR section 4.9.5 the CA has to investigate and send a preliminary report within 24 hours. A certificate whose domain validation "should not be relied upon" sits in the 24-hour revocation bucket of section 4.9.1.1. Don't count on revocation alone, though. Revocation checking in clients is still patchy, so a revoked rogue cert is still out there, and some clients will happily accept it.

The order matters

When you get DNS back after something like this, the sequence is what separates a cleanup from a second incident:

  1. Confirm the parent delegation points at your name servers, from outside your own resolver.
  2. Publish CAA with accounturi for every CA you actually use, and issuewild ";" if you don't need wildcards. Do this before anything else runs, because cached authorizations are live from the moment DNS returns.
  3. Pull CT for every affected name back to at least a week before the earliest suspicious change.
  4. Revoke everything you didn't issue, and keep a record of the report IDs.
  5. Rotate anything that might have been phished through the impersonated site: sessions, API tokens, OAuth grants.
  6. Keep the CT monitor running for the full reuse window of every CA in your CAA. Thirty days is the minimum. Two hundred is the honest number.

Short certificate lifetimes will shrink the damage over time. By 2029 a rogue certificate is good for 47 days at most, and a cached validation for 10. Neither number helps you this month.

Frequently asked questions

Would DNSSEC have prevented the .gh, .sl and .as certificates? No. The registry publishes the DS record that anchors your DNSSEC chain, so an attacker in control of the registry can replace your keys with theirs and the CA's validating resolver will accept the forged answers. DNSSEC only protects against tampering below the registry.

Does restoring my CAA record revoke certificates the attacker already has? No. CAA is only checked when a certificate is issued, so it blocks new issuance from cached authorizations but does nothing to certificates that already exist. Those you have to find in CT and revoke through the CA, either with your own ACME account or a Certificate Problem Report.

How long can an attacker keep issuing after I recover my DNS? As long as the CA's validation reuse period, provided your CAA still permits the CA and account they used. Under the Baseline Requirements that is up to 200 days today, 100 days from 15 March 2027 and 10 days from 15 March 2029. Let's Encrypt currently reuses authorizations for 30 days.

Is Registry Lock enough to protect a domain against this? Registry Lock stops unauthorized changes going through the normal registrar-to-registry path, which covers the much more common case of a compromised registrar account. It cannot protect you when the registry itself is compromised, because the attacker is then operating on the other side of the lock.

Should I move important services off small ccTLDs? For anything that authenticates users, it's worth weighing. Your security includes the registry operator's security, and you have no visibility into it. Many teams keep regional ccTLDs only as redirects to a primary domain under a large registry, which limits what a hijacked ccTLD can impersonate. It doesn't remove the need to monitor them.

Related posts

Never miss an expiring certificate again

CertGuard watches your SSL certificates and domains, and alerts you long before anything expires. Free for your first five domains.