Digging Up Dirt in the DNS Hierarchy, Part II

The examples used here were not invented. This article is really, really scary.

In the first part of this article [LJ, January 2008], we started the apparently simple journey of
navigating our way to the IP address of www.example.com and its
secure server online.example.com by traveling down the DNS hierarchy. We
finally received a referral from the gTLD .com servers pointing us to
the name servers ns2.example.com, an in-zone name server, and
ns1.example.net, an out-of-zone (or out-of-bailiwick) name server.

So, let's restart our quest for the IP address of www.example.com and
assume we have verified and obtained the IP address of ns1.example.net,
which, because it is out-of-zone, we have tracked to its authoritative
source via the .net gTLD servers. Now, it's time to check all our
authoritative servers for the example.com domain to see what else we can
find. First we check the front door:

dig @ns1.example.net version.bind txt ch

This command uses a legacy DNS resource record class called
CH(AOS)—Internet addresses use the IN class—to try to obtain information
about the software being used. We get this response:

And, we got lucky. This name server is telling us the supplier and
version number of its software. If we were bad guys, we would go and look up
the alerts for this version of software and see if there were any juicy
vulnerabilities. In this case, the news is extremely good (for the bad
guys), because the server is running BIND 4, last updated in 1997!
Between 3% and 7% of all the estimated 9 million name servers in
operation still use this redundant software, which is full of bugs and
exploit possibilities. Let's assume we repeat the command, substituting
ns2.example.com—our second authoritative server—and we get back
“my
name is Bind, James Bind”. The administrator of this DNS has a sense of
humor and some knowledge of BIND configuration parameters. In the
options clause of BIND's named.conf file (normally in /etc/named.conf),
the following parameter will appear:

options {
...
version "my name is Bind, James Bind";
...
}

You can place any text here, and it will be supplied in place of the
version number. If the statement is missing, BIND will return its version
number, as shown in the previous example. As we shall see, this may not
prevent us from discovering the information, but it does at least make it
more than a trivial one-line command. Finally, although BIND servers respond
to the above command, not all DNS software does, so we could have received
a timeout.

Now, it's time to move on to the next check. We're going to use the second of our
tools, fpdns, which is a DNS fingerprinting tool (see Part I of this article
for more information on fpdns). fpdns uses a range of benign techniques to try
to identify both
the software vendor and, in many cases, the release version or version
range. It is not infallible, but its accuracy is extremely good. Let's
use it to check our reluctant Mr Bind:

Now, this potentially is serious as well. First, the current version of
BIND at the time of this writing is 9.4.1-P1. So, we can simply check the security
alerts for the version range quoted and see whether we have some handy
poisoning possibilities. Second, this server is an open recursive
server, which means that any request for name resolution will be
accepted and acted on by this server, not only the names for which it is
authoritative. We could test this using a dig command like the following:

dig @ns2.example.com some.obscure.domain

Why are open resolvers a serious problem? There are three reasons. First, we
can load up the server for a simple Denial-of-Service (DoS) attack by
sending it requests for external name resolution. It will be so busy
following the referral chains that it will not have time to answer
requests for the domain for which it is authoritative—effectively taking
the domain off the air for at least a proportion of the traffic. Second,
it can be used in Distributed Denial-of-Service attacks. In this type of
attack,
requests are sent for the same name to many open name servers (there are
perhaps as many as one million open name servers on the Internet), each of
which then sends a query to the DoS target. No one single request breaks
any threshold monitoring, so it is difficult to identify all the sources. The
net effect is that the target DNS is bombarded with traffic and cannot
respond. Third, if I send a query to an open name server, I know what it
is going to do; it's going to send a query to the target domain's name
server. So, without even sniffing its traffic, I can start sending spoofed
responses, and if I get lucky, I can poison the open server's cache (there
are many documented weaknesses that I can exploit to
increase my chances significantly).

The function of a caching server is to save the
response until the Resource Record's TTL (Time to Live) expires and then
re-read the record. If the TTL for the requested RR is long (30 minutes
or more), I have a poisoning opportunity only every 30 minutes or
more, but if the TTL is short, say, five seconds or even zero
seconds,
my odds of getting poisoned responses into the cache shoot up
dramatically. And, of course, my poisoned response will not have a TTL of
five seconds; it will be more like five weeks, so when it's there it stays there
for a long time.

Now the real place to do this cache poisoning is not at
the authoritative name server. Instead, I would go looking for an open
recursive name server at an ISP and try to poison the cache using the
same technique, so that all the ISP's clients for www.example.com will
come to my pharming site.

All name servers should be closed to external traffic to stop this
behavior. If you are using BIND, there are three options:

1) If the name server is authoritative only (best practice recommends that
you never mix caching and authoritative functions in the same DNS), add
the following line to the /etc/named.conf file in the options clause:

2) If your server does provide both authoritative and recursive services,
limit who can use them by using the allow-recursion
statement in an options clause:

options {
...
allow-recursion {192.168.2/24};
...
};

This statement limits the allowable IP addresses permitted to make
recursive requests to 192.168.2.1–192.168.2.254. It is worth pointing
out that even if this statement is present, a recursive request from
outside the defined IP range will return the correct result if it
already exists in the cache (it previously was requested by a valid
internal user). BIND 9's view clause also can be used to
provide further control and separation in a mixed authoritative and
caching configuration.

3) Finally, if the server only provides caching services, use the
allow-query statement instead:

options {
...
allow-query {192.168.2/24};
};

Now, let's continue with our checks by requesting the IP address of our
target from one of its authoritative servers: