Today we are telling the story of how we developed a cyber security tool to find subdomain takeovers and why the existing solutions just weren't good enough. It has been used internally for some time, but we decided to open-source our tool - Subdominator - to help secure our communities.
For a long time, we used the same open-source tools as the rest of the community. One day I asked, which tool is best? Turns out this wasn't a simple question. Different people use different tools and each tool has different fingerprints, schemas, coverage and methods.
Throughout this project, we analyzed a stack of tools but here are the most common ones we came across:
That last one isn't a tool specifically, but a repository of fingerprints. Many tools pull these dynamically to allow a single source of truth and avoid maintenance.
Our journey begins with a list of tools and no way to compare them. First, we need to gather subdomains and since we want to test at scale to make sure our numbers are correct, some automation will help. The objective is to find companies that have a decent attack surface and want to know about their issues, with this in mind we compiled this list of Google dorks:
intext:"bug bounty program"
intext:"report a security vulnerability"
intext:"ethical hacking" and intext:"program"
intitle:"white hat" program
intext:"submit a vulnerability"
intext:"security vulnerability reporting"
intext:"bounty program" and "security"
These were run through a script and all the root domains on the first 5 pages of each were grabbed.
Next, we needed to get subdomains for each of these. To get the subdomains we used the wonderful tool Subfinder. Subfinder does passive domain enumeration, so it can find lots of subdomains in a very short time. We could have used more comprehensive solutions, but any kind of brute-forcing can take a while so this is more than good enough for our purpose.
After running Subfinder over our domains, we ended up with 108,471 subdomains belonging to lots of companies including banks, fintechs, health, social media and all sorts. Now that we have our subdomains, let's run the tools!
For our comparison, we are going to compare 3 tools: Subjack, Subdover and Subdominator. We are only focusing on these because they consistently performed the best and were the most popular when polling penetration testers.
After running all the tools over our list (all with 50 threads), we can compare the runtime of the tools:
2 Hours, 30 Minutes, 2 Seconds
2 hours, 33 minutes, 27 seconds
19 minutes, 8 seconds
As you can see, both of the existing open-source tools take 2.5 hours to run, almost the same amount of time. On the other hand, Subdominator takes less than 20 minutes, around 8x as fast!
To make things fair, speed is nothing if it sacrifices results. So let's see how many takeovers they found:
Subdominator comes out on top again, a comparison showed that each tool found everything found by the tool above it except for quite a few results that Subdominator ignored correctly as false positives.
Subdominator comes out as a clear winner for both speed and accuracy, the key metrics in a subdomain takeover tool. To understand why our results vary so much, we need to analyze how all the tools work.
Every subdomain takeover tool I could find worked very similarly, they define fingerprints in various formats and iterate the provided subdomains against them. Here is a breakdown of the number of fingerprints:
The number of fingerprints explains our results from the previous test, Subjack defines fewer fingerprints so it finds fewer results. Their fingerprint schema is more reliable but has limitations, resulting in a lot less possible fingerprints. Subdover has fingerprints for over 80 services with a less reliable schema, note that a few were removed from the count because they were false positives and there's likely more.
When building Subdominator, we went through every tool, GitHub issue, and blog post we could find to make sure all our fingerprints were accurate, reliable and comprehensive. We also created a new schema to be reliable and complete, ensuring it not only has the most fingerprints but also the most reliable individual fingerprints.
In terms of running, all the tools go through their fingerprints and do a CNAME lookup and HTTP request to the site to check against the fingerprints. Our solution was similar but it's done in a more intelligent way, which we will go over next.
Enhancements and Features
In theory, a tool should be able to check the CNAME record for a match with the fingerprints and then only HTTP query the page for a fingerprint if there is a match. All the existing tools did both for every subdomain, this is because there are edge cases. More specifically, there can be nested DNS records, A/AAAA records for some services, or incorrect fingerprints.
None of the edge cases are managed by the existing tools, hence the need to make a HTTP request for each subdomain. In contrast, Subdominator was made with support for all this built-in, our schema is fully vetted, supports A/AAAA records, and checks nested DNS records so we have the luxury of only testing DNS records unless there is a match.
In our benchmarking, this did not cause us to miss a single takeover and actually helped us dodge a lot of false positives, like Google Cloud buckets which are not able to be taken over but have the same fingerprint as S3 buckets.
Several other optimizations were made, such as making a custom public_suffix_list.dat file for domain validation and detecting domains being pointed to that are unregistered. Subjack also detects unregistered domains, but we took it a step further and made a more resilient check utilizing WhoIs data which ended up with fewer false positives and more true positives.
We have thoroughly analyzed and optimized the tool to do what the other tools do and much more. Finally, let's discuss the final results from the Subdominator testing process since everyone loves some vulnerabilities!
In the end, there were a lot of false positives with all tools but part of that comes down to my input list. Github.com and Github.io both ended up in my list of root domains and that means our list was tainted with lots of Github Pages that weren't pointing anywhere and had already expired. There were also a few other false positives that can't be easily validated programmatically like Unbounce.
After that, we were left with 144 valid takeovers, for 64 different domains! Many of them are still working on fixing the issues so I will leave names out of it, but it includes global consultancies, banks, government entities, recruitment, news, utilities, and the whole spectrum of industries. This was only on a small scale so you can use your imagination to estimate how many would exist, I conducted another test with a dozen local power companies and found over 30 more takeovers.
Subdominator was developed by us in our constant pursuit of hacking all the things and open-sourced to make sure everyone else can do it too. The tool is only just beginning with more features and fingerprints to come but that's a tale for another day.
If anyone has anything specific they would like to see, head over to the repo and open an issue or PR for us. Otherwise, you can download a release or build it yourself, the tool is written in .NET but releases are published using Native AoT so it will run without any prerequisites.
At Stratus Security we are constantly working on all sorts of projects and state-of-the-art tools, so feel free to get in touch if you need help with your cyber security or just have some questions!