Subdomain Takeover: Going beyond CNAME

After writing the last post, I started thinking that I pretty much covered all aspects of subdomain takeover. Recently, I realized that there are no in-depth posts about other than CNAME subdomain takeover. I briefly mentioned NS subdomain takeover in my other posts. The problem is that there are not many known cases of successful subdomain takeover using NS records. I carefully used this wording, because NS subdomain takeover is indeed possible! This post covers all technical aspects so that you can extend takeover scans with other signatures. Note however that NS takeover is a little bit difficult to understand than normal CNAME takeover.

Let's start with explaining how NS takeover differs from traditional CNAME subdomain takeover. I assume you are well-informed about CNAME subdomain takeover (if not, continue here). In NS subdomain takeover, we want to be able to control the whole DNS zone on (authoritative) DNS server. As you might know, DNS has a hierarchical structure, and each level can be served by different nameservers:

To make things more clear, let's explain the whole scenario with a simple example. I own a domain called wolframe.eu which I used for testing purposes. These are the (authoritative) nameservers for this domain:

As you can see, the DNS zone is managed by AWS (more specifically AWS Route53). The result we got in dig is non-authoritative answer. Non-authoritative means that it was not returned by authoritative DNS servers (one of four AWS in this example), but rather by some middleman. This middleman is 8.8.8.8 recursive Google DNS server as indicated by @8.8.8.8 in dig command. You can get authoritative answer by changing @8.8.8.8 to one of four AWS server such as @ns-1276.awsdns-31.org. This distinction will be crucial in later sections.

This is my DNS zone inside the Route53 portal:

There is only one A record for wolframe.eu itself set to 1.1.1.1.

Once DNS request is an issue for any of *.wolframe.eu, one of these four AWS nameservers is randomly selected, and DNS result is returned:

Now imagine this. I delete my DNS zone in Route53, but I keep NS records pointing to AWS. Now I get:

Oops, not good. Now, if an attacker simply creates the new DNS zone in Route53, he can return any DNS response. This is a basic premise of NS subdomain takeover. There are multiple caveats with the scenario I just explained. We cover these things in the next sections.

Custom nameserver domains

DNS specification does no require nameservers to be on the same domain. Imagine that example.com is served by two nameservers:

ns.gooddomain.com
ns.baddomain.com

If the base domain of canonical domain name of at least one NS record is available for registration, the hosted domain name is vulnerable to NS subdomain takeover.

In other words, if baddomain.com does not exist, an attacker can register that and have full control over example.com (and even its subdomains). The real question is, does this ever happen? I highly recommend reading post by Matthew Bryant where he explained how he got a subdomain takeover using precisely this approach. I also highly recommend his project called TrustTrees. It is used to generate delegation graphs for any domain. He was able to discover more similar problems using this tool.

From the automation perspective, the process is rather straightforward:

  1. Resolve all nameservers for the scanned domain
  2. Check if any of the nameservers are available for registration
  3. Alert based on the result from the previous step

Checking the only status in DNS reply is not sufficient indicator. The problem is that multiple servers are authoritative for a given domain. If one nameserver is not working, you get NOERROR because the other server is working just fine. DNS resolution does this quietly in the background. That's why tools like TrustTrees come handy in these type of analysis.

Managed DNS

For DNS zones which are hosted on third party providers like AWS, the story is a little bit different. The nameserver domains won't usually be available for registration. As I shown in the example above, there might be a case where NS records point to a hosted provider, but the DNS zone is not claimed in the portal. In 2016, Matthew Bryant managed to take over 120k domains which had NS records set to one of the DNS providers, but not claimed inside it. I highly recommend reading that post.

From the automation perspective, the process is a little bit different. It also varies from provider to provider, because all of them can have different signatures for non-existing zones. Let's take for instance DigitalOcean. My site (0xpatrik) is not hosted on DigitalOcean. Let's try to query its nameservers for it.

As we can see, DigitalOcean nameserver returns REFUSED DNS status. If the nameservers for 0xpatrik.com would be set to ns1.digitalocean.com, subdomain takeover would be possible.

As described in Matthew's post, AWS generates a new set of nameservers for each DNS zone, so for successful PoC, you will need to brute force these nameservers (but it is possible).

I don't write signatures for each DNS provider. The cases for NS subdomain takeover are so rare (in scopes I am interested in) that I don't care about the few false positives each month. Let's now look at the automation process for hosted DNS:

  1. For domain, extract its nameservers
  2. Iteratively resolve domain against each of these servers separately
  3. Look for responses like SERVFAIL or REFUSED and alert based on it

You can easily achieve this using dnspython and custom resolvers like so:

import dns
import dns.rdatatype

for NAMESERVER_IP in NAMESERVER_IPS:
    custom_resolver = dns.resolver.Resolver()
    custom_resolver.nameservers = [NAMESERVER_IP]
    q = custom_resolver.query(DOMAIN, dns.rdatatype.A)

Overall, your automation should be extended with the following process:

Check out my other posts about subdomain takeovers:

Until next time!

Patrik