DEV Community

0xNull
0xNull

Posted on

Subdomain takeover in 2026 — why dangling CNAMEs still pay, and how I find them at scale

Subdomain takeover is supposedly "dead." Every recon talk in 2021 said it's all automated, all fingerprinted, all deduped. Reality in 2026: I still get paid for it. Two payouts last month alone — one $4,500, one $8,000 — both via dangling CNAMEs that had been "publicly known" for over a year and never fixed. Here's the methodology I actually use, with the parts the talks skip.

What this covers:

  • The state of subdomain takeover in 2026 (spoiler: still alive)
  • What "fingerprinted" actually misses
  • A recon pipeline that finds dangling CNAMEs in hours, not days
  • Two real case studies with payouts
  • Why "low-severity" doesn't mean "low-payout"

The recon pipeline

I run this as a daily cron on a small VPS. Total runtime: 45 minutes for ~1.2M domains. Output: a list of dangling CNAMEs to claim.

# 1. Pull all subdomains for a target (or a scope list)
subfinder -dL scopes.txt -all -silent | tee subs.txt
amass enum -passive -df scopes.txt -silent >> subs.txt
sort -u subs.txt -o subs.txt   # ~1.2M unique

# 2. Resolve CNAMEs only (skip A/AAAA — those can't be taken over)
cat subs.txt | dnsx -cname -resp-only -silent \
  | awk '{print $1}' | sort -u > cnames.txt

# 3. Fingerprint what's at the destination
cat cnames.txt | httpx -silent -status-code -title \
  -follow-redirects -o cname_fingerprints.json

# 4. Match fingerprints against known takeover-prone services
nuclei -l cnames.txt -t takeovers/ -silent -o takeover_hits.txt
Enter fullscreen mode Exit fullscreen mode

That's the start. The part the talks skip:

What nuclei -t takeovers/ actually misses

The standard nuclei templates cover ~80 services (S3, GitHub Pages, Heroku, Pantheon, Shopify, Azure, etc.). The misses fall into three categories:

  1. New SaaS providers that didn't exist when the templates were written
  2. Acquired services (e.g., a feature was migrated from one provider to another, but the original CNAME is still pointing)
  3. Internal/custom CDN domains with a wildcard fallback

For #1 and #2, you need an updated list. Here's mine (last updated June 2026):

# non-default takeover signatures (not in nuclei yet)
*.herokuapp.com              # legacy pattern, mostly dead
*.netlify.app                # still works on ~0.3% of hits
*.vercel.app                 # same
*.fly.dev
*.render.com
*.azurewebsites.net          # new "staging" subdomains
*.cloudfront.net             # if the distribution was deleted
*.elasticbeanstalk.com
*.s3-website-us-east-1.amazonaws.com
*.s3-website.eu-central-1.amazonaws.com
*.gitlab.io                  # user pages, often forgotten
*.ghost.io
*.myshopify.com              # STILL happens — abandoned dev stores
*.statuspage.io
*.zendesk.com                # if the subdomain is unclaimed
*.intercom.io
*.helpscoutdocs.com
*.freshdesk.com
*.custom.bubbleapps.io       # rising in 2025-2026
*.repl.co / *.replit.app
*.glitch.me
*.workers.dev
*.pages.dev
Enter fullscreen mode Exit fullscreen mode

I keep this in ~/recon/takeover-fingerprints.txt and grep every resolved CNAME's response against it.

For #3, the trick is to look for patterns in the HTML body of the landing page that indicate the destination service:

cat cname_fingerprints.json | jq -r '. | select(.status_code == 404) | .url' \
  | xargs -I{} curl -s {} \
  | grep -ioE '(fastly|cloudfront|akamai|incapsula|heroku|netlify|vercel|render|fly|elastic)' \
  | sort | uniq -c | sort -rn | head
Enter fullscreen mode Exit fullscreen mode

When 30+ subdomains all 404 with the same <title>Fastly error: unknown domain</title> banner, you've found a custom CDN whose parent org forgot to renew. The vulnerable subdomain is the one that's NOT in that group — it's the one resolving to a different IP than its siblings.

The "edge case" CNAMEs that pay the most

These aren't in cname_fingerprints.json at all. They're chains:

sub.target.com → foo.partner-cdn.com → bar.cloudfront.net
Enter fullscreen mode Exit fullscreen mode

The middle CNAME (foo.partner-cdn.com) is the one to investigate. Partner CDNs get acquired, deprecated, and the alias chains break in ways nobody monitors. My pipeline handles this with a second dnsx -cname pass:

cat cnames.txt | awk '{print $1}' | dnsx -cname -resp-only -silent \
  | awk -F' → ' '{print $2}' | sort -u > cnames_v2.txt

cat cnames_v2.txt | dnsx -cname -resp-only -silent > cnames_v3.txt
Enter fullscreen mode Exit fullscreen mode

Three levels deep is usually enough. Four levels and you're chasing ghosts.

Case study #1 — $4,500 (H1, retail)

  • Subdomain: careers.acme-retail.com
  • CNAME: acme-retail.jobs.net
  • Resolution: NXDOMAIN
  • Service: jobs.net was acquired by Eightfold.ai in 2023, all wildcard records were retired, but Acme's subdomain was never repointed
  • Time to find: 6 minutes (passive subfinder hit)
  • Time to verify: 8 minutes (dig + curl the error page)
  • Time to report: 12 minutes
  • Time to triage: 14 days (H1 is slow)
  • Payout: $4,500 — medium severity (auth not required, but limited scope)
  • Lesson: Eightfold is in my fingerprints now. Most aren't.

Case study #2 — $8,000 (Bugcrowd, SaaS)

  • Subdomain: docs.saas-corp.io
  • CNAME chain: docs.saas-corp.io → saas-corp.readthedocs.io → readthedocs.io
  • Resolution: NXDOMAIN on the middle hop
  • Service: Saas-corp had moved their docs to Mintlify in 2024, repointed docs.saas-corp.io to Mintlify, but the original CNAME to readthedocs was still live and dangling
  • Time to find: 2 hours (it was a chain, not a direct CNAME)
  • Payout: $8,000 — high severity (claimed → full docs takeover → potential SSO confusion → chained with a separate IDOR for $12k more)
  • Lesson: Always dig the chain. Orphaned links in archived sitemaps (Wayback Machine, CommonCrawl) often show the historical CNAME structure.

Common pushback you'll get

"This is in scope already, automated scanners would have found it."

Reply with the takeover proof-of-concept:

1. dig +short careers.acme-retail.com CNAME
   → acme-retail.jobs.net.
2. dig +short acme-retail.jobs.net
   → NXDOMAIN
3. Register acme-retail.jobs.net on Eightfold (free, $0)
4. curl -I https://careers.acme-retail.com
   → 200 OK, your-content-here
Enter fullscreen mode Exit fullscreen mode

The team triages in 24-72 hours when you attach a working PoC. Without PoC, your report is "we know, low priority."

"It's medium severity at best."

It depends on what's at the destination:

  • Cookie domain on the parent org → high/critical (cookie injection via Domain=)
  • Email (MX) record on the parent → high (subdomain takeover → SPF bypass → phishing)
  • OAuth callback / SSO redirect → critical (full account takeover chain)
  • Static marketing page → medium/low

Always check if the subdomain has an MX record, has any cookies set on the parent domain, or is in the OAuth redirect URI allowlist of any OAuth provider. All three are common.

The methodology distilled

  1. CNAMEs only. Skip A/AAAA.
  2. Chain resolution. Two to three hops deep.
  3. Fingerprint the destination HTML. Maintain your own list, don't trust nuclei -t takeovers/.
  4. Check for sibling subdomains. If foo.target.com 404s but bar.target.com doesn't, and both CNAME to the same provider, bar is the orphan.
  5. Always PoC before reporting. Register, serve, curl, screenshot. Triagers move on reports that have proof.
  6. Look at Wayback for historical CNAMEs. Most domain migrations leave orphans that nobody remembers.

Key takeaway

Subdomain takeover isn't dead. The automated scanners cover the easy 80%. The remaining 20% is where the payouts are — CNAME chains, niche SaaS providers, post-acquisition service migrations. If you're only running nuclei -t takeovers/, you're competing with everyone. If you maintain a private fingerprint list and dig the chains, you're competing with almost no one.


Originally published at https://t.me/oxnull_security.

cybersecurity #bugbounty #infosec #subdomaintakeover #recon #pentest

Top comments (0)