from: http://lists.grok.org.uk/pipermail/full-disclosure/2011-April/080031.html
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.
Read more »
No Comments »