By Jake Edge
November 14, 2012
The domain name system (DNS) seems relatively straightforward, at least
from a high level, but there are some darker corners of the protocol that
could easily trip
up the unwary—or even the wary. A recent vulnerability
in the Exim mail transfer agent shows one
such example, but there are more. In fact, Exim developer Phil Pennock,
who patched the recent vulnerability, has collected up a number of these places
where DNS parsing can go awry.
The Exim hole was a fairly standard buffer overflow, but it came about
because of the way DNS messages are structured. When a program requests a
TXT record (for, say, a DomainKeys
Identified Mail (DKIM) public key), the reply is broken up into
multiple DNS "strings". The TXT record itself can be up to 64K in
size, with an overall length specified in the "resource record"
(RR) header, but it is broken up into multiple strings, each of
which is prefaced with a length.
Each string is a one-octet length value, followed by that many octets of data.
To construct the full TXT record, one collects each of the
string payloads into a buffer, which is where Exim went astray. For DKIM
verification, a 4K buffer was allocated for the TXT record. Each
string was length checked, so that it couldn't overrun the buffer, but the
loop did not terminate once the buffer was exhausted. An
attacker-controlled DNS server (or a benign server that just had a
TXT record larger than 4K) could send a large record and either
crash Exim or execute arbitrary code.
The fix
is simple, making two changes: check for buffer exhaustion before looking
at the next string and increase the size of the buffer to 64K. Either of
those would be sufficient to fix the problem, doing both just provides a
more robust fix. It's not clear why the original 4K buffer size was
chosen, but Pennock speculated that it seemed a reasonable limit to the
original developer given that there was a test for overflow (though it
turned out to be incorrect).
The problem was found in an Exim DKIM code
inspection that was done after a
US-CERT advisory as
and a Wired
article raised DKIM issues. While the specific problems reported were
not present in
Exim, Pennock was
concerned that increased attention would be focused on that code, thus the
code review.
There are other implications to consider with the strings that make up a
TXT record. At first blush, joining the strings directly (rather
than with a space or newline character) makes sense, but there are
protocols that depend on the strings within a TXT record being
treated as separate entities. DKIM and Sender Policy
Framework (SPF) both explicitly say that the strings
should be joined directly, but forcing that behavior for all TXT
records retrieved by Exim broke some ad hoc uses.
Likewise, there is a question of how to handle multiple TXT
records. Those records will be returned in random order, so two DKIM key
TXT records (i.e. prefaced with "v=DKIM1;") could be returned in a
query. If
applications don't check for that possibility, or handle it differently
than the DNS administrator creating the TXT records expected,
problems could result. Once again, DKIM and SPF explicitly disallow
multiple TXT records for their information, so compliant programs
need to check. Other protocols may not be as clear.
Beyond that, DNS has some surprises in the kinds of names it allows. Many
believe that domain and host names are restricted to certain subsets of
characters, but that is not true. As RFC 2181 specifies, the
limits are purely length-based (63 octets per component, 255 octets for a
domain name). Each octet of the name can contain any value from 0 to 255.
Looking at the host names returned by the following command is rather
interesting:
$ host -lva test.globnix.net nlns.globnix.net
...
foo\\.bar.test.globnix.net. 600 IN A 192.0.2.8
...
cr\013\010lf.test.globnix.net. 600 IN AAAA 2a02:898:31:dead:beef::32
...
i-want-nul.test.globnix.net. 600 IN CNAME nul\000gap.test.globnix.net.
...
That domain is one that Pennock has had for years, and the entries are
meant to be somewhat eye-opening. For example, note that '.' is legal in
the components
of a host name (represented textually as foo\.bar...). And that
brackets ([, ]), colons, NULs (\000), newlines, backslashes, and so on are all
legal. Any of those could pose a problem for a program that didn't expect
to receive them. One of the ways that might happen is with a reverse
lookup, where an IP address to host name mapping is sought.
For actual domain names, it may be difficult or impossible to
register any with "weird" characters, but they are definitely legal as far
as DNS is concerned.
The registrars will shy away from those kinds of domains because they
aren't legal in email addresses or URLs. But, as Pennock's examples show,
domains with their own DNS can create all sorts of problematic host names.
These dark corners are hopefully well-known to DNS server and library
developers, but they aren't necessarily obvious to those outside of those
specialties. One
can well imagine that there are bugs lurking in applications and tools that
use DNS at a medium or low level. Some of those could easily result in security
vulnerabilities.
[I would like to thank Phil Pennock for sharing his research and answering
questions about DNS handling.]
(
Log in to post comments)