Subdomain Takeover

What it is

A subdomain takeover happens when a subdomain’s DNS record still points to a third-party service that the organization no longer controls or has deleted. You claim that service, and now you control what anyone visiting that subdomain sees.

How it happens

  1. blog.example.com is set up with a CNAME record pointing to a blogging platform (e.g. example.ghost.io)
  2. The organization stops using the blogging service and deletes the account
  3. The CNAME DNS record is never removed - it still points to example.ghost.io
  4. You create an account on the blogging platform and claim example.ghost.io
  5. Anyone visiting blog.example.com now sees your content

How to find it

  • Run subdomain enumeration (subfinder, assetfinder, amass)
  • Check CNAME records: dig blog.example.com CNAME
  • Visit the subdomain - look for error messages from the third-party service:
    • GitHub Pages: There isn't a GitHub Pages site here
    • Heroku: No such app
    • AWS S3: NoSuchBucket
    • Netlify: Not found - Request ID
    • Shopify: Sorry, this shop is currently unavailable
  • A 404 Not Found alone doesn’t confirm takeover - look for service-specific errors

Automated checking

subzy run --targets subdomains.txt
subjack -w subdomains.txt -t 100 -o results.txt

Reference

Impact

  • Serve malicious content under a trusted domain
  • Steal cookies if the subdomain is in the same cookie scope
  • Bypass CSP policies that whitelist the domain
  • Phishing under a legitimate domain name

Open Redirects

What it is

An open redirect happens when an application takes a URL from user input and redirects the user to it without validating where it goes. Simple but useful for phishing and chaining with other vulnerabilities.

What to look for

Parameters in the URL or POST body that contain a URL or path:

return_url=./dashboard.php
redirect=./home
next=/profile
goto=https://example.com
url=./page
dest=./settings

Similar to SSRF - you are looking for anywhere a URL is being passed and acted upon.

Exploiting it

Lab example - URL contains: ?return_url=./test.php Change it to: ?return_url=http://google.com

When the victim clicks “Return to list” (or any button that uses that redirect), they land on your page instead. They trust the original domain in the URL bar, so they don’t notice until it’s too late.

Common attacks using open redirects

  • Phishing - send a link to trusted-site.com/login?next=http://evil.com/fake-login - user thinks they’re on a trusted site, gets redirected to a credential harvesting page
  • SSRF bypass - if the SSRF filter allows a trusted domain, point it to an open redirect on that domain that redirects to http://localhost - url=https://trusted.com/redirect?to=http://127.0.0.1/admin
  • OAuth token theft - manipulate redirect_uri to send the auth code to an attacker-controlled domain

PoC

Original: https://TARGET/page?return_url=./home
Modified: https://TARGET/page?return_url=https://google.com

If clicking the button redirects to google.com - confirmed.

Filter bypasses (exam scenarios)

If the app tries to validate the URL:

  • //google.com - protocol-relative URL
  • https://trusted.com@evil.com - browser ignores the trusted.com part
  • https://evil.com%2F@trusted.com - encoded slash
  • https://trusted.com.evil.com - subdomain trick
  • https://trusted.com\evil.com - backslash

Vulnerable Components

What it is

Modern web apps use third-party libraries, frameworks, and plugins. If these are outdated or misconfigured they may have known CVEs with public exploits.

Step 1 - Identify the stack

Tools:

  • Wappalyzer - browser extension, auto-detects tech stack
  • BuiltWith - web-based, shows libraries and services
  • Browser dev tools - check Network tab response headers (X-Powered-By, Server)

Places to look manually:

  • Page source / HTML comments
  • HTTP response headers
  • /README, /CHANGELOG, /LICENSE, /INSTALL files
  • Footer of the application (“Powered by X v1.2.3”)
  • /robots.txt often reveals CMS or framework paths
  • Error pages sometimes leak framework and version

Step 2 - Find the version

Once you know the component, find the exact version:

  • Source code and HTML comments often contain version strings
  • package.json, composer.json, requirements.txt if accessible
  • Admin panels often show version on the dashboard (Jenkins, WordPress, etc.)
  • JS files sometimes have version numbers in the filename or content

Step 3 - Search for known vulnerabilities

searchsploit nginx 1.14
searchsploit wordpress 5.2

Step 4 - Automate it

Manual component checking does not scale. Use:

  • Nuclei - has thousands of templates for known CVEs and exposed panels:
nuclei -u https://TARGET -t cves/ -t exposed-panels/
  • Retire.js - specifically for JavaScript library CVEs (browser extension or CLI)
  • Trivy - if you have access to the codebase or containers

Common high-value targets

  • WordPress plugins/themes (enormous attack surface, new CVEs constantly)
  • Outdated jQuery, Bootstrap, Angular versions
  • Jenkins, Jira, Confluence (often exposed internally)
  • Apache, nginx, IIS with old versions
  • phpMyAdmin, Adminer exposed to the internet
  • Log4j (still found in the wild)

Key principle

Automated scanning (Nuclei) gives the best return on time for known CVEs. Save manual testing for custom code, business logic, and complex chaining. The instructor explicitly said: “doing this manually is often not the best use of our time” - use automation here.

Testing Checklist

Subdomain Takeover

  • Run subdomain enumeration: subfinder, assetfinder, amass
  • Check CNAME records for discovered subdomains: dig subdomain.target.com CNAME
  • Visit each subdomain and look for service-specific error messages (GitHub Pages: “There isn’t a GitHub Pages site here”, Heroku: “No such app”, AWS S3: “NoSuchBucket”, etc.) - a generic 404 alone does not confirm takeover
  • Run automated takeover checks: subzy run --targets subdomains.txt or subjack -w subdomains.txt
  • Cross-reference with https://github.com/EdOverflow/can-i-take-over-xyz for the full list of vulnerable services and their fingerprints
  • Include in report: the subdomain, the dangling CNAME, the third-party service, proof that you can claim it, and impact (phishing, cookie theft, CSP bypass)

Open Redirects

  • Look for URL or path parameters in requests: return_url=, redirect=, next=, goto=, url=, dest=
  • Change the parameter value to an external URL (e.g., ?return_url=https://google.com) and check if clicking the redirect button takes you there
  • Test filter bypasses: //evil.com, https://trusted.com@evil.com, https://evil.com%2F@trusted.com, https://trusted.com.evil.com
  • Consider chaining: open redirect + SSRF filter bypass, open redirect + OAuth token theft, open redirect + phishing
  • Include in report: the vulnerable parameter, the redirect PoC URL, and the chaining potential (phishing, SSRF bypass, OAuth abuse)

Vulnerable Components

  • Identify the technology stack: use Wappalyzer, BuiltWith, browser DevTools (response headers, page source, HTML comments, X-Powered-By, Server headers)
  • Find exact version numbers: check page source, package.json, composer.json, README/CHANGELOG files, admin panels, JS filenames, error pages
  • Search for known CVEs: searchsploit <component> <version>, NVD, Exploit-DB, Snyk, GitHub
  • Automate with Nuclei: nuclei -u https://TARGET -t cves/ -t exposed-panels/ - best return on time for known CVEs
  • Use Retire.js for JavaScript library CVEs and Trivy for container/codebase scanning
  • Include in report: the component and exact version, the CVE ID, a working PoC or reference, and the recommended patched version