Full Disclosure mailing list archives

Re: BSD derived RFC3173 IPComp encapsulation will expand arbitrarily nested payload


From: Jeffrey Walton <noloader () gmail com>
Date: Fri, 1 Apr 2011 05:34:18 -0400

On Fri, Apr 1, 2011 at 4:00 AM, Tavis Ormandy <taviso () cmpxchg8b com> wrote:
BSD derived RFC3173 IPComp encapsulation will expand arbitrarily nested payload
-------------------------------------------------------------------------------

Gruezi, this document describes CVE-2011-1547.

RFC3173 ip payload compression, henceforth ipcomp, is a protocol intended to
provide compression of ip datagrams, and is commonly used alongside IPSec
(although there is no requirement to do so).

An ipcomp datagram consists of an ip header with ip->ip_p set to 108, followed
by a 32 bit ipcomp header, described in C syntax below.

struct ipcomp {
   uint8_t     comp_nxt;       // Next Header
   uint8_t     comp_flags;     // Reserved
   uint16_t    comp_cpi;       // Compression Parameter Index
};

The Compression Parameter Index indicates which compression algorithm was used
to compress the ipcomp payload, which is expanded and then routed as requested.
Although the CPI field is 16 bits wide, in reality only 1 algorithm is widely
implemented, RFC1951 DEFLATE (cpi=2).

It's well documented that ipcomp can be used to traverse perimeter filtering,
however this document discusses potential implementation flaws observed in
popular stacks.

The IPComp implementation originating from NetBSD/KAME implements injection of
unpacked payloads like so:

   algo = ipcomp_algorithm_lookup(cpi);

   /* ... */

   error = (*algo->decompress)(m, m->m_next, &newlen);

   /* ... */

   if (nxt != IPPROTO_DONE) {
       if ((inetsw[ip_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
           ipsec4_in_reject(m, NULL)) {
           IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);
           goto fail;
       }
       (*inetsw[ip_protox[nxt]].pr_input)(m, off, nxt);
   } else
       m_freem(m);

   /* ... */

Where inetsw[] contains definitions for supported protocols, and nxt is a
protocol number, usually associated with ip->ip_p (see
http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml), but in
this case from ipcomp->comp_nxt. m is the mbuf structure adjusted to point to
the unpacked payload.

The unpacked packet is dispatched to the appropriate protocol handler
directly from the ipcomp protocol handler. This recursive implementation fails
to check for stack overflow, and is therefore vulnerable to a remote
pre-authentication kernel memory corruption vulnerability.

The NetBSD/KAME network stack is used as basis for various other
operating systems, such as Xnu, FTOS, various embedded devices and
network appliances, and earlier versions of FreeBSD/OpenBSD (the code
has since been refactored, but see the NOTES section regarding IPComp
quines, which still permit remote, pre-authentication, single-packet,
spoofed-source DoS in the latest versions).

The Xnu port of this code is close to the original, where the decompressed
payload is recursively injected back into the toplevel ip dispatcher. The
implementation is otherwise similar, and some alterations to the testcase
provided for NetBSD should make it work. This is left as an exercise for the
interested reader.

Isn't this OK as long as the evil bit (RFC 3514) is not set?

_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/


Current thread: