In a previous post we talked about taking over the .na, .co.ao, and .it.ao domain extensions with varying levels of DNS trickery. In that writeup we examined the threat model of compromising a top level domain (TLD) and what some avenues would look like for an attacker to accomplish this goal. One of the fairly simple methods that was brought up was to register a domain name of one of the TLD’s authoritative nameservers. Since a TLD can have authoritative nameservers at arbitrary domain names it’s possible that through a misconfiguration, expiration, or some other issue that someone would be able to register a nameserver domain name and use it to serve new DNS records for the entire TLD zone. The relevant quote from the previous post I’ll include here:
This avenue was something I was fairly sure was going to be the route to victory so I spent quite a lot of time building out tooling to check for vulnerabilities of this type. The process for this is essentially to enumerate all nameserver hostnames for a given extension and then checking to see if any of the base-domains were expired and available for registration. The main issue I ran into is many registries will tell you that a domain is totally available until you actually attempt to purchase it. Additionally there were a few instances where a nameserver domain was expired but for some reason the domain was still unavailable for registration despite not being marked as reserved. This scanning lead to the enumeration of many domain takeovers under restricted TLD/domain extension space (.gov, .edu, .int, etc) but none in the actual TLD/domain extensions themselves.
As it turns out, this method was not only a plausible way to attack a TLD, it actually led to the compromise of the biggest TLD yet.
The .io Anomaly
While graphing out the DNS delegation paths of various TLDs late on a Friday night I noticed a script I had written was giving me some unexpected results for the .io TLD:
One of the features of this script (called TrustTrees) is that you can pass it a Gandi API key and it will check to see if any of the nameservers in the delegation chain have a domain name that’s available for registration. It appeared that Gandi’s API was returning that multiple .io nameserver domains were available for purchase! This does not necessarily mean you can actually register these domain names however, since in the past I had seen multiple incidents where registries would state a domain name was available but wouldn’t allow the actual registration to go through due to the domain name being “reserved”. I decided to go straight to the source and check the registry’s website at NIC.IO to see if this was true. After a quick search for the nameserver domain of ns-a1.io I was surprised to find that the registry’s website confirmed that this domain was available for the registration price of 90.00 USD. Given that this was around midnight I decided to go ahead and attempt to purchase the domain to see if it would actually go through. Shortly afterwards I received an email confirming that my domain name registration was “being processed”:
It’s not clear why I received a confirmation from 101Domain but apparently .io’s registrations (and possibly their entire registry?) is managed via this company. Since it was well past midnight at this point I shrugged it off and eventually forgot about the registration until the following Wednesday morning when I got the following notification as I was walking out the door to go to work:
At this point I instantly was reminded of the details of that registration and I turned around to check if I had actually just gained control over one of .io’s nameservers. I dig a quick dig command for the domain and sure enough my test DNS nameservers (ns1/ns2.networkobservatory.com) were listed for ns-a1.io:
bash-3.2$ dig NS ns-a1.io ; <<>> DiG 9.8.3-P1 <<>> NS ns-a1.io ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8052 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;ns-a1.io. IN NS ;; ANSWER SECTION: ns-a1.io. 86399 IN NS ns2.networkobservatory.com. ns-a1.io. 86399 IN NS ns1.networkobservatory.com. ;; Query time: 4 msec ;; SERVER: 2604:5500:16:32f9:6238:e0ff:feb2:e7f8#53(2604:5500:16:32f9:6238:e0ff:feb2:e7f8) ;; WHEN: Wed Jul 5 08:46:44 2017 ;; MSG SIZE rcvd: 84 bash-3.2$
I queried one of the root DNS servers to again confirm that this domain was listed as one of the authoritative nameservers for the .io TLD and sure enough, it definitely was:
bash-3.2$ dig NS io. @k.root-servers.net. ; <<>> DiG 9.8.3-P1 <<>> NS io. @k.root-servers.net. ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19611 ;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 7, ADDITIONAL: 12 ;; WARNING: recursion requested but not available ;; QUESTION SECTION: ;io. IN NS ;; AUTHORITY SECTION: io. 172800 IN NS ns-a1.io. io. 172800 IN NS ns-a2.io. io. 172800 IN NS ns-a3.io. io. 172800 IN NS ns-a4.io. io. 172800 IN NS a0.nic.io. io. 172800 IN NS b0.nic.io. io. 172800 IN NS c0.nic.io. ;; ADDITIONAL SECTION: ns-a1.io. 172800 IN AAAA 2001:678:4::1 ns-a2.io. 172800 IN AAAA 2001:678:5::1 a0.nic.io. 172800 IN AAAA 2a01:8840:9e::17 b0.nic.io. 172800 IN AAAA 2a01:8840:9f::17 c0.nic.io. 172800 IN AAAA 2a01:8840:a0::17 ns-a1.io. 172800 IN A 184.108.40.206 ns-a2.io. 172800 IN A 220.127.116.11 ns-a3.io. 172800 IN A 18.104.22.168 ns-a4.io. 172800 IN A 22.214.171.124 a0.nic.io. 172800 IN A 126.96.36.199 b0.nic.io. 172800 IN A 188.8.131.52 c0.nic.io. 172800 IN A 184.108.40.206 ;; Query time: 70 msec ;; SERVER: 2001:7fd::1#53(2001:7fd::1) ;; WHEN: Wed Jul 5 08:46:14 2017 ;; MSG SIZE rcvd: 407
Yikes! I quickly SSHed into my DNS testing server that was now hosting this domain and quickly killed the BIND server that was running. If I was starting to receive DNS traffic I certainly didn’t want to serve up bad responses for people trying to legitimately access their .io domain names. With the BIND server no longer responding to queries on port 53 all DNS queries would automatically fail over to the other nameservers for the TLD and it wouldn’t greatly affect the traffic (other than a slight delay in resolution time while DNS clients failed over to working nameservers). In order to see if I was actually receiving traffic I did a quick tcpdump of all DNS traffic to a file to see just how many queries I was currently getting. I immediately saw hundreds of queries verbosely being printed to my terminal from random IP addresses across the Internet. It looks like I was definitely serving up traffic for the entire .io TLD, and worse yet this was likely only the beginning since many DNS clients likely were still operating on cached DNS records which would clear shortly.
Reporting a Security Issue in a TLD
With my server no longer responding to any DNS queries my mind was then set on getting this fixed as quickly as possible. My main concern was that there were still multiple other nameserver domains which could still be registered and that could be done by anyone with the money and the knowledge to do so. I looked up the contacts for the .io TLD in IANA’s root database:
I then wrote up a summary of the issue and emailed both contacts about the problem and conveyed the urgency of the fix. I stated my concern with the other TLD nameserver domains being available for registration and stated that if I didn’t receive a response within a few hours that I would go ahead and register those as well to protect the TLD. After sending the email I immediately received a bounce message indicating that the [email protected] was not an email address that existed at all:
This was not a strong vote of confidence that someone was going to see this notice. I decided to take action and just spend the money to buy the other nameserver domains to prevent anyone else from hijacking the TLD. Just like with the first domain I explicitly set my DNS server to not respond to inbound queries so that it wouldn’t interfere with regular .io traffic. Those domain orders were actually filled quite quickly:
Later that day I called NIC.IO’s support phone number and requested the appropriate email to contact any security personnel/team that they had for the TLD. The agent assured me that [email protected] was the appropriate contact for this issue (which I double verified just to be sure). While it seemed unlikely to be the correct contact I forwarded the report to that email address as well hoping that at the very least it would be forwarded by the abuse department to the appropriate place. With little further leads on reaching an appropriate security contact I waited for a response.
“Oops” – Remediation via Revoked Domains
Around noon the following day I received a blast of notifications from 101Domains stating that my domain privacy was deactivated, my “support ticket” was answered, and all of my domains had been revoked by the registry:
Looks like, shockingly enough, the [email protected] alias was the correct email address for the issue. After logging into my 101Domain account I found the following message from the 101Domain legal department:
All said and done this was actually an excellent response time (though usually I just get a “fixed it” response via email instead of a Legal Department notice). After verifying that I was not able to re-register these domains it would appear that this had been completely remediated.
Given the fact that we were able to take over four of the seven authoritative nameservers for the .io TLD we would be able to poison/redirect the DNS for all .io domain names registered. Not only that, but since we have control over a majority of the nameservers it’s actually more likely that clients will randomly select our hijacked nameservers over any of the legitimate nameservers even before employing tricks like long TTL responses, etc to further tilt the odds in our favor. Even assuming an immediate response to a large scale redirection of all .io domain names it would be some time before the cached records would fall out of the world’s DNS resolvers.
One mitigating factor that should be mentioned is that the .io TLD has DNSSEC enabled. This means that if your resolver supports it you should be defended from an attacker sending bad/forged DNS data in the way mentioned above. That being said, as mentioned in a previous post DNSSEC support is pretty abysmal and I rarely encounter any support for it unless I specifically set a resolver up that supports it myself.
*As an unrelated aside, it’s important to remember to kill tcpdump after you’ve started it. Not doing that is a great way to obliterate your VPS disk space with DNS data, which was an unexpected additional impact of this :). Please note that any DNS data recorded for debugging purposes has now been purged for the privacy of the users of the .io TLD/its domains.
Mitigations and TLD Security
I’ve already written at some length about how some of these issues could be mitigated from a TLD perspective (see Conclusions & Final Thoughts of the post The Journey to Hijacking a Country’s TLD – The Hidden Risks of Domain Extensions for more info on this). In the future I hope to publish a more extensive guide on how TLDs and domain extension operators can better monitor and prevent issues like this from occurring.
I promised a friend of mine that I would do a silly old-school hacker shout-out in my next blog post so I’m fulfilling this obligation here special thanks to the following folks for both moral and “immoral” support (as phrased by the one and only HackerBadger).