»An out of bounds memcpy() and integer underflow in Asterisk 1.4.x.
[=] The chan_skinny.c vulnerability reported last year was not patched properly.
[-] Sending 8 NUL bytes to an Asterisk server using the chan_skinny module
results in a segmentation fault due to an overly large memcpy(). In the
get_input() function of channels/chan_skinny.c, the length as read from the
user-supplied data is checked if it is less than zero and if it is greater
than the size of the inbuf (s->inbuf). The supplied length is used in a
memcpy() in skinny_req_parse():
memcpy(....., len-4)
Any length of 3 or less will result in the extremely large memcpy. A
length of 0 results in an empty skinny request object. The side effect of
that has not been investigated.
[+] Please see the attached patch for a simplistic solution. More aggressive,
documented checking is advisable.
[*] Any Asterisk-based code listening for skinny traffic is susceptible to this
attack. It requires no authentication or system-specific knowledge.
[?] To reproduce, run an asterisk server with skinny channel support (defaulting
to TCP/2000). The following command will result in a crash:
ruby -e 'print "\x00" * 8' | nc asterisk 2000
[=] An out of band read in the RTP handling code exists due to poor length
checking.
[-] The RTP handling code forks for cases where the packet appears to be a STUN
packet. The fork occurs in ast_rtp_read(), shunting the packet to
stun_handle_packet(). On line 446, a while loop is defined with the
predicate of "while(len)". 'len' is defined as a size_t and is the size of
the payload read from the socket. On each loop, 'len' is decremented by a
packet-supplied STUN attribute length and the size of the stun_attr struct.
There are two checks against 'len': (1) break if len < sizeof(struct
stun_attr), (2) break if attr->len > len. Since 'len' is decremented by
both values, it is possible to craft a packet of the correct length with
the correct embedded STUN attribute length to cause 'len' to be decremented
past 0. For example, if 'len' is equal to the size of a stun_attr struct
and 'attr->len' is equal to 'len' then 'len' will be decremented by twice
its value. Once it flips, the associated 'data' pointer will be
incremented out of accessible memory and the server will crash.
[+] Since 'len' is unsigned, it is not sufficient to attempt to check for it
becoming negative. In addition, data would still be increment out of
bounds. Instead, a check should be added to ensure that 'len' is no less
than the total value it will be decremented by. The attached patch
performs those checks.
[*] Any active asterisk server with open RTP-based media connections is
vulnerable. No information about the session is required, and given the
small size of the payload, it is possible to spray this data at all
standard RTP ports very quickly with a spoofed source address.
[?] To reproduce, run the following command against your asterisk server,
'asterisk', on a port with an open RTP session on 'rtpport':
ruby -e 'print "\x00\x01\x00\x18"*6' | nc -u asterisk rtpport
References
- CVE-2007-3764
- CVE-2007-3765
Post a Comment