Kamailio SEAS module encode_msg heap buffer overflow
CENSUS ID: | CENSUS-2016-0009 |
CVE ID: | CVE-2016-2385 |
Affected Products: | Kamailio 4.3.4 (and possibly previous versions) |
Class: | Heap-based Buffer Overflow (CWE-122) |
Remote: | Yes |
Discovered by: | Stelios Tsampas |
Kamailio (successor of former OpenSER and SER) is an Open Source SIP Server released under GPL, able to handle thousands of call setups per second. Kamailio can be used to build large platforms for VoIP and realtime communications, presence, WebRTC, Instant messaging and other applications. It can also easily be applied to scaling up SIP-to-PSTN gateways, PBX systems or media servers.
There is a (remotely exploitable) heap overflow vulnerability in Kamailio version 4.3.4 and possibly in previous versions. The vulnerability takes place in the SEAS module, which enables Kamailio to transfer the execution logic control of a SIP message to a given external entity, called the Application Server.
Details
The heap overflow can be triggered if Kamailio is configured to use the SEAS module, more specifically if Kamailio calls the module’s single exported function as_relay_t(). The heap overflow is located in function encode_msg(), file encode_msg.c, line 269:
int encode_msg(struct sip_msg *msg, char *payload,int len)
{
...
/*now we copy the actual message after the headers-meta-section*/
memcpy(&payload[j],msg->buf,msg->len);
LM_DBG("msglen = %d,msg starts at %d\n",msg->len,j);
j=htons(j);
...
}
msg is a pointer to a sip_msg structure and it is basically the current SIP packet being processed by Kamailio. msg->buf is a buffer which holds the packet's contents and msg->len is the packet's length. Unsurprisingly, msg->len can take arbitrary values (bound by the packet size) while j takes the value of 180 in most cases.
The destination buffer payload is allocated in encoded_msg()'s caller function, create_as_event_t(), specifically in file seas.c, line 442:
char * create_as_event_t(struct cell *t, struct sip_msg *msg, char processor_id,
int *evt_len, int flags)
{
...
if(!(buffer=shm_malloc(ENCODED_MSG_SIZE))){
LM_ERR("Out Of Memory !!\n");
return 0;
}
...
if(encode_msg(msg,buffer+k,ENCODED_MSG_SIZE-k)<0){
LM_ERR("Unable to encode msg\n");
goto error;
}
...
}
Preprocessor constant ENCODE_MSG_SIZE is defined as 3200 and variable k at line 521 holds the value 34. The problem is that the program does not check the packet's length if it is larger than the destination buffer. If a user makes a request with a large enough packet then the buffer will overflow.
Discussion
We were able to trigger the bug remotely using a large UDP packet.
A proof-of-concept packet is provided here that crashes the Kamailio process handling the request. From bash the packet can be sent using the following command:
cat seas-trigger.packet > /dev/udp/KAMAILIO-IP/KAMAILIO-PORT
This bug may potentially provide attackers with remote code execution capabilities.
Recommendation
The security defect has been fixed in version 4.3.5 of Kamailio. Upgrading to the latest stable version is strongly advised.Disclosure Timeline
Vendor Contact: | February 12th, 2016 |
CVE assignment: | February 15th, 2016 |
Vendor Patch Release: | March 3rd, 2016 |
Public Advisory: | March 30th, 2016 |