Interrogating DNS

30 November -0001

DNS (Domain Name System) is an important component of any reconnaissance or discovery phase of an attack on internet systems. DNS controls routing, but also enumerates all the host URLs on a particular domain. DNS specifies host names (CNAME and A records), default mail servers (MX records) and other name servers (NS records). DNS normally responds to queries on UDP port 53, however, for large queries such as zone transfers, TCP port 53 is used. Because DNS is hierarchical it is possible to query a DNS server about records that server may not actually possess. In these cases the request is forwarded to a server that can respond to the query. Because of this indirection, DNS lookups are a form of passive reconnaissance and these queries often escape unnoticed by a target.

The easiest way to collect full DNS data sets about a target URL is to simply perform a zone transfer request. A zone transfer request queries the DNS server for it's entire listing of URLs and corresponding IP information. Zone transfers are somewhat more intensive than normal DNS queries, so multiple concurrent zone transfers may induce a denial of service condition against a target. Note that sometimes your default name server may not allow zone transfers so you might have to send your query to the authoritative name server for a domain.

Queries from Windows

To perform a zone transfer on Windows use the 'nslookup' command. In the following example we'll attempt a zone transfer from wikipedia.org. To start well fire up nslookup from the command prompt, this will begin nslookup interactively:

C:\> nslookup
Default Server: NS1.madirish.net
Address: 10.0.0.5

>

Once nslookup is started you can type 'help' to see all of the commands that are available. First we'll set the query type to "any", meaning that we want to get all records for an associated domain. You could also set the type to "mx" to view mail servers for a domain, or "ns" to view name servers, and so on.

> set type=any

Next we'll attempt the zone transfer. To do this we'll utilize the "ls" command with the "-d" flag. You can optionally redirect the output of this command to a file, but for now we'll just list the output in the console.

> ls -d wikipedia.org
[NS1.madirish.net]
*** Can't list domain wikipedia.org: BAD ERROR VALUE

This error message indicates that our default name server isn't allowing the zone transfer. To get around this limitation we can query the authoritative name server for wikipedia.org directly. First, however, we'll have to find out what the authoritative name servers are. To do this we'll simply query the domain:

> wikipedia.org
Server:  NS1.madirish.net
Address: 10.0.0.5

Non-authoritative answer:
wikipedia.org   internet address = 208.80.152.2
wikipedia.org   nameserver = ns2.wikimedia.org
wikipedia.org   nameserver = ns1.wikimedia.org
wikipedia.org   nameserver = ns0.wikimedia.org

wikipedia.org   nameserver = ns0.wikimedia.org
wikipedia.org   nameserver = ns2.wikimedia.org
wikipedia.org   nameserver = ns1.wikimedia.org
ns0.wikimedia.org       internet address = 208.80.152.130
ns2.wikimedia.org       internet address = 91.198.174.4
ns1.wikimedia.org       internet address = 203.212.189.252

The name servers for wikipedia.org are all listed out. Once we switch the specifications in nslookup so they query the target server directly we can attempt the zone transfer again.

> server ns2.wikimedia.org
Default Server:  ns2.wikimedia.org
Address:  91.198.174.4

> ls -d wikipedia.org

This will spit out a whole long list of records, probably too much to actually view as they'll scroll by and fill up the command prompt's buffer. To save these records we can redirect them to a file:

> ls -d wikipedia.org > wikipedia.txt
[ns2.wikimedia.org]
#################
Received 1700 records.

Now we can simply browse to the text file output and browse through the records.

Queries from Linux

On a Linux platform there are several alternatives to nslookup that are also available. The dig and host command are both useful for querying DNS records. To use the host command to attempt a zone transfer use:

$ host -l -v -t any wikipedia.org

The "-l" flag is for list mode, or to request a zone transfer. The "-v" flag is for verbose output. The "-t any" flag specifies that we want records of any type. This request, however, will fail in the same way as our nslookup if our default server does not allow zone transfers. In this case we again have to specify that we want to query the wikipedia authoritative server by listing it last, like so:

$ host -a -l wikipedia.org ns2.wikimedia.org

In the preceding query we use the "-a" flag, which is the equivalent of the "-v" and "-t any" flags. The host command is also useful because with the -T flag it will make queries using TCP rather than the default UDP.

Linux platforms may also include the dig command. To perform queries using dig simply use:

$ dig @ns2.wikimedia.org wikipedia.org axfr

DNS Security Concerns

An attacker can use zone transfer lists to enumerate potential targets. Because this information leak can present a security problem, many DNS servers are configured specifically to prohibit zone transfers. In these cases they will only respond to direct queries for a specific domain name (or record type, such as MX). Zone transfers can be prohibited on most DNS servers, with the exact procedure varying depending on platform.

Brute Forcing DNS

Often times an attacker will want to enumerate all the domains listed in a particular DNS server. This is useful for many things, including enumerating web sites. Many web servers can be configured to respond to page requests based on the URL, sending request for one URL to a certain document root, and another URL to a different document root. For instance, an organization may have a web server that has a content management system (CMS) installed and a webmail system installed. Browsing to www.sitename.tld would bring up the front page of the CMS, and browsing to mail.sitename.tld would bring up the webmail interface. An attacker could probably guess the www.sitename.tld existed and explore that system, but they would have no way of knowing that the same server hosted a webmail system unless they could discover that the server also responded to HTTP requests to mail.sitename.tld. The easiest way to discover the existence of this site would be a DNS query. However, if the DNS server is configured to prevent zone transfers the attacker must guess, or brute force, the name.

Brute force attacks work because DNS servers respond to queries either with an authoritative response, or an error. For instance, if the attacker did an nslookup of foo.sitename.tld they would get a response that there was no record for that host. However, if the attacker performs an nslookup of a name that does exist they'll get a valid, affirmative response. Thus, if an attacker were to query the DNS server for every possible alphanumeric combination they could find out what records the DNS server held.

This might sound daunting at first, but it's not as bad as it seems. DNS records contain a limited number of characters, are generally alphanumeric, and are case insensitive. If an attacker employed a large word list they could simply loop over the word list, querying each entry for the domain (for instance, querying a.sitename.tld, b.sitename.tld, c.sitename.tld and so on). While this is tedious to do by hand, tools exist to automate the process.

DNSBruteforce

DNSBruteforce (http://www.revhosts.org/DNSBruteforce) by the Revhosts project, is a DNS brute force tool written in python. DNSBruteforce is multi threaded, meaning it spawns a new process for each DNS query. This adds speed to the program as each query involves a lag. DNSBruteforce is able to fire off multiple concurrent DNS queries and interpret the responses as they arrive. DNSBruteforce is also able to support multiple domain servers, so if you can provide more than one name server, DNSBruteforce will divide up queries amongst multiple name servers, further aiding in performance.

Installing DNSBruteforce

DNSBruteforce requires python be installed, the pyDNS (http://pydns.sourceforge.net/) libraries are installed, and subversion for grabbing the latest source code. To install DNSBruteforce on Fedora, CentOS or another Red Hat based distro use yum as root:

# yum install python
# yum install subversion

Once these are installed download and install the pyDNS libraries from Sourceforge:

# wget http://superb-east.dl.sourceforge.net/sourceforge/pydns/python-pydns-2.3.3-2.el5.noarch.rpm

Install the RPM:

# rpm -ivh python-pydns-2.3.3-2.el5.noarch.rpm

If you're not on an rpm based distribution you can download the source tar.gz and build it on your system. Once pyDNS is installed check out the latest version of DNSBruteforce using subversion:

$ svn co http://trac.revhosts.org/svn/DNSBruteforce/trunk

This will download a directory called 'trunk' that is probably easier to use if you rename it to DNSBruteforce like so:

$ mv trunk DNSBruteforce

The downloaded directory contains three files: DNSBruteforce.py, hosts-txt, and README. The README file is fairly comprehensive so you may want to start there. To use DNSBruteforce you'll need a better host list (or dictionary of potential host names) than the hosts-txt that comes with the program. You can either build your own sequential dictionary file or download any number of dictionaries from sites online, such as SCOWL from Kevin's Word List Page (http://wordlist.sourceforge.net/). It may be helpful to read RFC 1178 (http://tools.ietf.org/html/rfc1178) on "Choosing a Name for Your Computer" that may provide some insight into how machines are named.

Next you should compile a list of DNS servers you can use to query. You can either use your ISP's defaults or find some publicly available DNS servers (such as OpenDNS (http://www.opendns.com/)). These can be listed one per line in a file called servers.txt. Once you have a good word list you can start up DNSBruteforce using: Using:

$ python DNSBruteforce wikipedia.org servers.txt scowl-6/final/english-words.10

DNSBruteforce will then dutifully begin chewing through he word list and firing off DNS queries:

DNSBruteforce program running

Your mileage may vary with DNSBruteforce. Some domains have wildcard DNS records , meaning that any subdomain will resolve to a top level domain. For instance, foo.sitename.tld may not exist, but DNS can be configured to have queries to anything that doesn't match a specific record resolve to www.sitename.tld. It is for this reason that you're better off to query the authoritative domain name servers for the domain you're attempting to interrogate (although this is less stealthy).

Conclusions

DNS contains a host of valuable information that many attackers will seek out as a precursor to an attack on an organization. Carefully protecting your DNS records by prohibiting zone transfers will assist in obscuring information, but like many services offered on the internet, DNS is designed to be open. In order to function properly DNS must provide records to both legitimate requestors and potentially malicious attackers. It may be worth keeping an eye on your DNS logs to look for zone transfers or excessive queries, but there really isn't much that can be done to prevent this type of activity.

As an attacker gaining DNS information provides a valuable footprint of targets. Used in conjunction with IP lookups for an organization, DNS information can provide a roadmap to machines that can be profiled and evaluated for vulnerabilities.