[LWN Logo]
[Timeline]
Date:         Mon, 29 Jan 2001 06:31:55 -0800
From: COVERT Labs <seclabs@NAI.COM>
Subject:      [COVERT-2001-01] Multiple Vulnerabilities in BIND
To: BUGTRAQ@SECURITYFOCUS.COM

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

______________________________________________________________________

                     Network Associates, Inc.
                  COVERT Labs Security Advisory
                        January 29, 2001

                 Vulnerabilities in BIND 4 and 8

                         COVERT-2001-01
______________________________________________________________________

o Synopsis

BIND 8 contains a buffer overflow that allows a remote attacker to
execute arbitrary code. The overflow is in the initial processing of
a DNS request and therefore does not require an attacker to control
an authoritative DNS server.  In addition, the vulnerability is not
dependent upon configuration options and affects both recursive and
non-recursive servers.  This vulnerability has been designated as
CVE candidate CAN-2001-10.

RISK FACTOR: HIGH


BIND 4 contains a buffer overflow that can allow a remote attacker
to execute arbitrary code. The overflow occurs when BIND reports
an error while attempting to locate IP addresses for name servers.
Exploitation of this vulnerability is restricted by the fact that
the target name server be recursive and that the attacker has
control of an authoritative DNS server.  This vulnerability has
been designated as CVE candidate CAN-2001-11.

RISK FACTOR: MEDIUM


BIND 4 contains a format string vulnerability that can allow a
remote attacker to execute arbitrary code.  This vulnerability
also occurs when BIND reports an error while attempting to locate
IP addresses for name servers, and thus has the same restrictions
on exploitation as the buffer overflow.  This vulnerability was
fixed several versions prior to the current version of BIND 4,
but is still present in certain Unix distributions.  This
vulnerability has been designated as CVE candidate CAN-2001-13.

RISK FACTOR: MEDIUM

______________________________________________________________________

o Vulnerable Systems

BIND 8 versions: 8.2, 8.2.1
                 8.2.2 through to 8.2.2-P7
                 8.2.3-T1A through to 8.2.3-T9B

BIND 4 versions: buffer overflow - 4.9.5 through to 4.9.7
                 format string   - 4.9.3 through to 4.9.5-P1

______________________________________________________________________

o Vulnerability Overview

BIND (Berkeley Internet Name Domain) is an implementation of the DNS
(Domain Name System) protocol distributed by the Internet Software
Consortium (www.isc.org).  Two versions of BIND distributed by the
ISC, BIND version 4 and BIND version 8, are vulnerable to the
attacks described in this advisory.  The most recent release of
BIND, version 9, is not susceptible to these attacks.


BIND version 8 contains a buffer overflow in the implementation
of Transaction Signatures (TSIG) for DNS security as defined in RFC
2845.  Because the overflow occurs within the initial processing
of a DNS request, both recursive and non-recursive DNS servers are
vulnerable, independent of the DNS security configuration.  The
mechanisms employed by the DNS server make it susceptible to two
potential methods of attack.

An attacker can perform a stack based buffer overflow, with two
important qualifications: first, that the number of bytes past the
end of the buffer that the attacker can overwrite is limited in
length, and second, that the values of those bytes are mostly fixed.
On the x86 architecture, the attacker can manipulate a sufficient
number of bytes such that they can modify the saved frame pointer.
Overwriting the least significant byte of the saved frame pointer
can result in the execution of arbitrary code in certain predictable
installations of the name server.  The "infoleak" bug, discovered by
Claudio Musmarra, and described in CERT advisory CA-2001-02, permits
an attacker to remotely retrieve stack frames from named, which
allows for direct calculation of the effect of the one byte overflow.

An attacker can also perform a heap overflow, overwriting malloc's
internal variables.  This method is very effective, though it
requires that an operating system's implementation of malloc stores
internal data structures in the allocated memory. For this attack
to be successful, TCP port 53 must be accessible.


BIND version 4 contains a buffer overflow in a section of code that
formulates a warning message for a call to syslog.  There are several
conditions that can lead to the triggering of this overflow, all of
which involve the resolution of NS records into IP addresses. This
vulnerability is a standard stack overflow, but the information an
attacker is able to present is limited to printable characters. This
limitation makes susceptibility to exploitation contingent upon the
layout of the named process within memory, and possibly upon the
amount of memory available to be allocated by the name server.


In older versions of BIND 4, the previously mentioned call to syslog
utilizes a user controllable string as the second argument, which
creates an exploitable condition.  The same restriction applies, in
that the format string is limited to printable characters.  Despite
this restriction, a remote attacker is still able to create a
malicious format string to exploit the vulnerable syslog function
call.

______________________________________________________________________

o Detailed Information

The BIND 8 vulnerability is the result of a DNS request utilizing a
particular code path that invalidates the logic used to calculate
the length of the request buffer.

When a request is received, it is either stored in the heap or on
the stack, depending on the transport mechanism.  Upon receipt of a
UDP request, it is read into a 513 byte buffer on the stack called
"u.buf" by the function datagram_read().  When a TCP request is
received, the message is read by stream_getlen() into a 64k buffer
called "sp->s_buf", which is allocated from the heap for every
socket.  An interesting feature of BIND is that it uses the incoming
buffer of both transport mechanisms to read the request from the
network and then modifies it to create an appropriate response.
Two key variables are maintained to track the usage of the buffer:
one containing the actual length of the data in the buffer, called
"msglen", and a second variable "buflen" that tracks the remaining
length free in the buffer.

When a DNS message is received, msglen is initialized to the length
of data received from the network. With a UDP message, this is the
amount of data returned by a recvfrom() call, whereas with a TCP
message, it is the value provided as the length by the client.
buflen is set to the size of the buffer used to read the message
(512 for UDP, 64k for TCP).

Under normal circumstances, as BIND processes a request, it appends
the answer, authoritative, and additional records to the query.  It
then modifies the DNS header to reflect these changes and delivers
the response.  During this processing, msglen will reflect the
length of the response as it is being formed, and buflen will be
used to track the remaining space available in the buffer.
Throughout the processing, BIND assumes that msglen plus buflen
will equal the original length of the buffer.

Upon receipt of a DNS message, it is processed as either a request
or response based upon the query response flag set in the message
header.  If a request is received, BIND then determines whether it
is a query, iquery, update or notification.  Beginning with BIND
8.2, prior to request processing, the additional section of the
DNS message is examined for a TSIG resource record.  The function
ns_find_tsig() is called to perform this functionality as well as
to enforce a basic level of validity on the TSIG resource record.
If a valid TSIG is identified but an appropriate security key can
not be found, an error is signaled and BIND bypasses the normal
request processing.  As a result, msglen and buflen remain close
to their initial values, instead of being set to their "working"
values.

BIND processes the request as an error since a TSIG was identified
but an appropriate security key was not found. As part of the error
generation, BIND reuses the request buffer and appends a TSIG after
the question section.  At this point, BIND assumes that the size of
the request is msglen plus buflen which, under normal circumstances,
would be correct.  However, in this special case, the request was
never processed and "msglen + buflen" is in fact almost twice the
size of the original buffer. BIND is then willing to append a TSIG
via ns_sign() beyond the limits of the buffer.

Since a valid security key was not found, ns_sign() will only
append a small number of bytes with limited values. As mentioned
above, this makes the vulnerable BIND installation susceptible to
two types of attack.

Combining this oversight with the way a compiler positions the
stack variables in datagram_read(), it is possible for an attacker
to overwrite portions of the saved stack activation records in
datagram_read() with certain fixed values. In this case, executing
arbitrary code is possible under the x86 architecture by overwriting
the saved frame pointer's least significant byte with zero resulting
in the saved frame pointer pointing into the original DNS request
in the majority of cases.

Predicting the effect of this one byte overflow can be difficult
as it varies depending upon how BIND was started.  However, the
"infoleak" bug allows an attacker to retrieve the stack
activation record of datagram_read().  This information can then
be used to calculate the exact number of bytes that will displace
the frame pointer when the least significant byte of the saved
ebp is overwritten with 0.

The second method of attack utilizes certain implementations of
dynamic memory allocation.  It is possible to overwrite malloc's
boundary tags with predictable values, changing the standard
libraries' notion of the length of the buffer following the
buffer processed in the DNS request.  Thus, the next set of
boundary information is read from within a buffer that an
attacker can control, allowing for a malicious pointer overwrite
upon compaction.

This technique is applicable to malloc implementations that store
linkage information in the actual allocated memory. The following
implementations are known by COVERT to be exploitable: IRIX libc,
Linux glibc, and Solaris libc.


The BIND 4 vulnerability is a sprintf into a 999 byte stack buffer
that occurs when BIND formulates a message warning the administrator
of an inconsistency or error resolving a Name Server record to an
IP address. The vulnerability occurs within nslookupComplain(),
which is a static utility function used by nslookup().

When BIND encounters a query that it can not answer from its cache
or zone files, it attempts to forward the query to a name server that
is capable of resolving it or referring BIND to a more appropriate
server.  When BIND forwards a query, it creates a qinfo structure to
keep track of the request.  It also creates this structure in order
to track requests initiated by itself in order to find various
linkage information.  BIND can determine potential name servers for
which to forward to by walking through each label in the query in
its database, looking for stored NS records.

The purpose of the nslookup() function is to take a list of NS
records and populate a qinfo structure with their corresponding IP
addresses.  BIND can then use those IP addresses as a list of
name servers for which to attempt forwarding or sending a query.

nslookup() performs certain sanity checks on the information that
it retrieves.  For example, if it finds that a particular name server
has an IP address of 0.0.0.0, 255.255.255.255, or a multicast
address, then it will flag this condition as an error, warn the
administrator via syslog, and move on to the next NS record.  The
function nslookupComplain() is called to warn the administrator
and, as mentioned above, contains a stack overflow.

In order to trigger this overflow, an attacker needs to get BIND
to cache an NS record with a very large length.  Furthermore, the
attacker needs to cache a record for the resolution of the NS
record that contains one of the problem conditions for the
logging.  This is achievable by sending a query to a recursive
name server, asking it to resolve a large name that is under the
authority of a malicious name server.  The malicious name server
then needs to refer the request to another name server also with
a large name, and provide an additional record giving an invalid
address for that name server.

The limitations placed upon the character set allowed in domain
names makes the construction of a viable return address difficult.
However, there is a potential for an attacker to make the name server
return into memory that the attacker has forced the name server to
allocate. In this case, vulnerability is contingent upon the
location of the heap and the amount of memory available, as well as
whether or not the operating system has a policy of lazy swap page
allocation as opposed to an eager reservation policy. COVERT has
verified that it is possible to exploit named running under Linux
by growing the heap to sizes that far exceed that amount of memory
and swap available. This was performed by utilizing specific patterns
of memory allocation that maximize untouched memory.

The situation may be further complicated by the overwriting of two
other stack based buffers, nsbuf and abuf, which are read from within
the same sprintf that overflows the stack based buffer.  This does
not come in to play, however, if the value chosen to overwrite
the saved return address does not utilize the terminating null byte
of the string.  It is worth noting that this behavior could make it
easier for an attacker to exploit the problem under operating
systems that implement sprintf such that overlapping copies are
handled correctly.


The format string vulnerability in BIND 4 occurs in the syslog call
in nslookupComplain().  This vulnerability is in the same section
of code as the previously described buffer overflow, and thus can
be triggered in a similar fashion by using an authoritative name
server under malicious control.  This vulnerability was corrected
in bind-4.9.5-P1, although certain vendors' named implementations
based upon this code remain vulnerable.

______________________________________________________________________

o Resolution

ISC has produced patches to address these issues.  Except as
otherwise noted, BIND version 4.9.8 and 8.2.3 resolve the
vulnerabilities described in this advisory.

For ISC's description of these problems:

 http://www.isc.org/products/BIND/bind-security.html

To download updated versions of BIND:

 ftp://ftp.isc.org/isc/bind/src/


In cooperation with COVERT Labs, the CERT/CC is coordinating the
collection of information on vulnerable distributions from third
party vendors.  For the most current vendor information, please
read CERT Advisory CA-2001-02 "Multiple Vulnerabilities in BIND"
available at:

 http://www.cert.org/advisories/CA-2001-02.html

______________________________________________________________________

o Credits

Discovery and documentation of these vulnerabilities was conducted
by Anthony Osborne and John McDonald of the COVERT Labs at PGP
Security.

______________________________________________________________________

o Contact Information

For more information about the COVERT Labs at PGP Security, visit our
website at http://www.pgp.com/covert or send e-mail to covert@nai.com

______________________________________________________________________

o  Legal Notice

The information contained within this advisory is Copyright (C) 2000
Networks Associates Technology Inc. It may be redistributed provided
that no fee is charged for distribution and that the advisory is not
modified in any way.

Network Associates and PGP are registered Trademarks of Network
Associates, Inc. and/or its affiliated companies in the United States
and/or other Countries. All other registered and unregistered
trademarks in this document are the sole property of their respective
owners.

______________________________________________________________________


-----BEGIN PGP SIGNATURE-----
Version: PGP 7.0.1

iQA+AwUBOnVuH6F4LLqP1YESEQJeAQCdEYWBrcstWvbnJy2LKwETm/SHkqoAmPp6
BCeuRNPzbt9tt3MuJ2W55gk=
=xzwT
-----END PGP SIGNATURE-----