The Great Subdomain Heist

How I Took Over 5,000 GitHub Pages Domains (And Why GitHub Doesn't Care)

Table of Contents

I was deep into an intense Helldivers 2 session when Google Search Console notifications interrupted my battle against the alien hordes. Someone had claimed ownership of a subdomain I didn't even know existed: ftp.malvetro.corsica.

Within minutes, I went from fighting digital aliens to investigating a real security incident, one that would eventually reveal a massive vulnerability affecting thousands of domains worldwide. More concerning? GitHub knows about it and isn't fixing it.


The Initial Discovery

Opening the suspicious subdomain revealed a gaudy online gambling site plastered.

My first instinct: someone had compromised my domain registrar account. But the truth turned out to be more insidious.

$ dig malvetro.corsica +noall +answer -t A
malvetro.corsica. 442 IN A 185.199.110.153
malvetro.corsica. 442 IN A 185.199.109.153
malvetro.corsica. 442 IN A 185.199.108.153
malvetro.corsica. 442 IN A 185.199.111.153

Those IP addresses were familiar—they belong to GitHub Pages. My root domain (malvetro.corsica) was legitimately pointing there for my GitHub Pages site. But I'd never configured the ftp subdomain. Checking my DNS records at OVH revealed something disturbing:

$ dig ftp.malvetro.corsica +noall +answer -t CNAME
ftp.malvetro.corsica. 430 IN CNAME malvetro.corsica.

This CNAME record had been created automatically by my registrar without my knowledge, pointing to my main domain. Since my main domain used GitHub Pages, anyone could claim this subdomain by creating their own GitHub Pages site with the same subdomain in their repository's CNAME file.

This wasn't a sophisticated hack—it was a systematic exploitation of common DNS practices, GitHub Pages configuration, and lack of domain verification.


Down the Rabbit Hole

To understand the scope, I needed to see if this was an isolated incident or part of a pattern. Searching GitHub for "HANTUSLOT" (the gambling site name) revealed several repositories using the same template across various subdomains.

But GitHub's search was too limited for a comprehensive analysis. I turned to the GitHub CLI to dig deeper:

# Search for repo owners with "ftp." in repo names
$ (gh search repos ftp --sort updated --limit 1000 | while read -r repo _; 
   do if [ $(echo "$repo" | grep -E "\/ftp\.") ]; 
      then echo $repo | cut -d/ -f1; 
   fi; done) | sort -u > accounts

# Clone all repositories from these users
$ while read -r user; do 
    gh repo list "$user" --limit 1000 | 
    while read -r repo _; do 
      mkdir -p "$user"; 
      git clone "https://github.com/$repo" "$repo"; 
    done; 
  done < accounts

To catch repos that might have been deleted (like the one targeting my domain), I improved the script to mirror-clone repositories and analyze their historical CNAME files:

# Mirror clone all repos to get full history
$ while read -r user; do 
    gh repo list "$user" --limit 1000 | 
    while read -r repo _; do 
      mkdir -p "$user"; 
      GIT_TERMINAL_PROMPT=0 git clone --mirror "https://github.com/$repo" "$repo.mirror"; 
    done; 
  done < accounts

# Extract all domain additions from CNAME files in git history
$ (TMP=$(pwd); for f in $(find $(pwd) -maxdepth 2 -mindepth 2 -type d); do 
     cd $f; 
     git log -p --follow --all -- CNAME | grep -E "^\+[a-zA-Z0-9]" | sed 's/^+//'; 
   done; 
   cd $TMP;) | sort -u > subdomains

# Analyze frequency of subdomain prefixes
$ cat subdomains | cut -d. -f1 | sort | uniq -c | sort -n
[...]
      5 status
      6 blog
      6 depo10bonus10
      6 depo20bonus20
      6 linkserverinternasional
      6 linkservervietnam
      7 beta
      7 docs
      7 linkserverasia
      7 linkserversensasional
      8 cpanel
      8 test
     13 duit188
     13 whm
     26 webmail
     37 www
     48 mail
   2091 ftp

The results were staggering. The frequency analysis revealed 2091 instances of "ftp" subdomains being targeted. Other common targets included "mail" (48 instances), "www" (37), "webmail" (26), and other standard subdomains often created by default by domain registrars. You can find the list of all subdomains here. There are likely subdomains in the list that are legitimate, but I don't see cases where one would host a GitHub Pages on an ftp subdomain. This confirms my belief that:

  • Attackers are using automated tools.
  • ftp is generated by default on some registrars.

The subdomain takeover is quite well-known. Take, for example, can-i-take-over-xyz, a superb tool for checking how to takeover domains or dangling subdomains with unused CNAME DNS records like mine. This is discussed in this issue: EdOverflow/can-i-take-over-xyz#68 (comment). To GitHub credits, they actually "warns" about it in the documentation:

We recommend verifying your custom domain prior to adding it to your repository, in order to improve security and avoid takeover attacks.

However, here the source of the issue is not on a legacy subdomain that wasn't properly decommissioned but a subdomain generated by default by the registrar.


Taking It to The Next Level

The scale of this vulnerability demanded a more comprehensive approach. I developed a custom tool in Python that:

  1. Used public reverse DNS data to identify all domains and subdomains pointing to GitHub Pages IPs

  2. Checked which ones could be claimed through GitHub Pages

  3. Systematically identified vulnerable domains and subdomains

The result? I was able to take over approximately 5,000 domains and subdomains in less than three weeks before GitHub banned my account.

While the ban was technically justified under their Acceptable Use Policy, I hadn't been using these takeovers for malicious purposes. In fact, I redirected affected users to GitHub's documentation on how to regain control of their domains.

I had already reported this vulnerability to GitHub via HackerOne in March 2024, but their response was dismissive:

We have determined that it is a known issue that does not present a significant security risk. We may make this functionality more strict in the future, but we don't have anythingto announce right now.

A year later, in May 2025, nothing has changed.


Why This Matters: The Anatomy of a Subdomain Takeover

The vulnerability pattern follows a predictable flow:

  1. Domain owner sets up GitHub Pages for their main domain (e.g., example.com)

  2. Registrar automatically creates additional subdomains (e.g., ftp.example.com) with CNAME records pointing to the main domain

  3. GitHub allows anyone to claim any subdomain without verifying ownership or alerting the main domain owner

  4. Attackers discover and exploit these dangling subdomains

The worst cases involved wildcard CNAME records that redirected any subdomain to the main domain, making infinite subdomain takeovers possible.


The Security Implications Are Severe

Subdomain takeovers enable attackers to:

  1. Host malicious content under your trusted domain

  2. Capture cookies set for your domain

  3. Perform cross-site scripting attacks

  4. Damage brand reputation through phishing or scam sites

  5. Bypass certain security controls that trust your domain

For organizations using GitHub Pages, this represents a significant, unaddressed security risk hiding in plain sight.


Recommendations: A Shared Responsibility

For Domain Owners and Security Teams:

  1. Audit all your DNS records, particularly automatically created subdomains

  2. Remove unnecessary CNAME records pointing to your main domain, especially the auto-generated ones created by the registrar

  3. Set up Google Search Console with DNS domain verification to be alerted of ownership claims on the Search Console

  4. Verify custom domains for GitHub Pages using GitHub's DNS verification system

  5. Monitor for new subdomains on an ongoing basis

For GitHub:

  1. Implement proper domain verification before allowing Pages to be published

  2. Alert domain owners when a subdomain of their verified domain is claimed by another user

  3. Proactively scan for and prevent obvious takeover attempts

  4. Take vulnerability reports seriously rather than dismissing documented risks

For Registrars (like OVH):

  1. Stop creating DNS records by default without clear user notification

  2. Warn users about potential security implications of default subdomain creation

  3. Implement verification steps for subdomain creation


The Big Picture

This issue represents a classic case of responsibility diffusion. GitHub claims it's the domain owners' responsibility to verify their domains. Domain registrars create potentially vulnerable subdomains without warning. Domain owners often don't know what they don't know.

Meanwhile, attackers are systematically exploiting this gap—I personally identified and could have maliciously taken over 5,000 domains with minimal effort. The real number of vulnerable domains is likely much higher.

What's most concerning is GitHub's dismissal of the issue as not presenting "a significant security risk," when the evidence clearly suggests otherwise. This highlights a troubling disconnect between security researchers identifying real-world vulnerabilities and platform providers willing to address them.

Until GitHub implements proper verification, the burden falls on security teams to regularly audit their DNS configurations and monitor for subdomain takeovers. Sometimes security isn't about sophisticated zero-days—it's about checking your DNS records for the digital equivalent of unlocked doors.

Comments