Vulnerabilities in Asterisk version 1.4.x

»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
[-] 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
  • CVE-2007-3764
  • CVE-2007-3765
This work was sponsored by my employer.

This page does not necessarily reflect the views of my employer or anyone I'm associated with.