Facebook Google Plus Twitter LinkedIn YouTube RSS Menu Search Resource - BlogResource - WebinarResource - ReportResource - Eventicons_066 icons_067icons_068icons_069icons_070

[R1] FreeSWITCH parse_string() Function Multiple Vector Remote Heap Buffer Overflow

Critical

Synopsis

On 2015-09-14, Marcello Duarte disclosed a vulnerability in FreeSWITCH on the Bugtraq mail list. This was assigned CVE-2015-7392 which reads:

Heap-based buffer overflow in the parse_string function in libs/esl/src/esl_json.c in FreeSWITCH before 1.4.23 and 1.6.x before 1.6.2 allows remote attackers to execute arbitrary code via a trailing \u in a json string to cJSON_Parse.

After investigation, Tenable found that this description is not fully accurate, and that the issue was not properly patched. It is still possible to trigger a heap overflow via crafted JSON in FreeSWITCH from version 1.4.4 to 1.6.2 (current), and 1.7.0 (development). Further, the original CVE entry only mentions exploitation in the third-party Event Socket library, but there are at least three other vectors of exploitation of the same (or similar) vulnerability in FreeSWITCH itself, one native to FreeSWITCH itself:

  1. FreeSWITCH command line via the “json” command (switch_json.c, local).
  2. Executing the FreeSWITCH command “json” via an Event Socket library connection to the Event Socket module (switch_json.c, local by default, remote potentially).
  3. Sending crafted JSON to the Verto module multicast listener (switch_json.c, remote).
  4. Malformed / malicious JSON traffic from the server to an ESL client (esl_json.c, remote and may require MitM)

The original Bugtraq disclosure indicates that the vulnerability was patched on September 14, 2015, and it is associated with a Jira ticket (inaccessible to the general public). Note that the patch fixes duplicate versions of the parse_string() function in src/switch_json.c, libs/libks/src/ks_json.c, and libs/esl/src/esl_json.c (the latter being the only file explicitly mentioned in the CVE entry).

The parse_string() function at line 155 in esl_json.c is supposed to take in a JSON string and convert it a normal (no escaped characters) C string. There are two things to consider; first, how the size of the string buffer is computed, and second, how the parser handles Unicode escaped values (i.e. \u0001). As mentioned in the Bugtraq disclosure, the return string buffer is calculated by counting the characters from the starting quote to the last unescaped quote (or NULL if it is encountered). The parser handles the escaped Unicode by identifying the “\u” and then passing the data one byte beyond the “u” to sscanf. In the following code, *ptr at line one would contain “\” and *ptr in line five would contain “u”. CVE-2015-7392 describes the attack as a “trailing \u in a JSON string to cJSON_Parse. This can be interpreted in two ways:

  1. { “key” : “value\u” }
  2. {“key” : “value\u

The first JSON example will fail sscanf conversion due to the ‘”’ character not being convertible. The second JSON example will also fail sscanf conversion since the NULL terminator is passed into sscanf. The break after sscanf fails increments over the ‘u’ and returns back to the top of the while loop. Based on the description found in CVE-2015-7392, there is not sufficient information to cause the heap overflow. However, if we observe how sscanf is used, we can find the overflow. The sscanf man page says this about the return value:

These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.

However, as written, if sscanf returns greater than 0 the string pointer is always incremented by four. Therefore a JSON string such as the one provided below, where sscanf will only consume one character, will cause the parser to skip the ” and start writing beyond the end of the allocated buffer:

{ “heap” : “overflow\u1” aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa }

The published fix for CVE-2015-7392 changed line 42 (that steps over the ‘u’ character) to be “ if (*ptr) ptr++;”. However, this doesn’t fix the issue since the root cause was with sscanf.

Details on the Vulnerability:

The CVE describes the vulnerability as a remote vulnerability in FreeSWITCH but cites the libs/esl/src/esl_json.c files. It is interesting to note that code in the libs/esl/ directory is not actually native FreeSWITCH code, instead, it is a library to be used by third-party applications to communicate with FreeSWITCH. As such, the vulnerability, as described in the CVE, is not a remote vulnerability in FreeSWITCH, rather a remote vulnerability in third-party applications that use the Event Socket library to communicate with FreeSWITCH. The FreeSWITCH tool Fs_cli is an example that may be affected, as well as any of the third-party GUI for FreeSWITCH.

The original fix was also applied in two other locations: libs/libks/src/ks_json.c and src/switch_json.c. Based on examination, it appears that libs/libks/src/ks_json.c is unused code and therefore not exploitable. However, src/switch_json.c is used in the FreeSWITCH base code. The first way this can be reached is via the FreeSWITCH command line. Specifically, the command “json” (part of mod_commands) is available to local users via CLI. When starting FreeSWITCH git master version (3f3b855 at the time of writing) using the following command:

user@host: ~/freeswitch$ sudo /usr/local/freeswitch/bin/freeswitch -conf ./conf/ -log ./log -db ./db

This gives a fairly wide attack surface in order to attempt to trigger the vulnerability remotely, enabling services on a variety of TCP and UDP ports. Of specific interest are UDP port 1337 and TCP port 8021.

UDP port 1337 is part of the Verto module, an interface for multicast traffic that accepts JSON-RPC as input. To trigger the heap overflow on this interface, an attacker needs to send a single UDP packet with the crafted JSON:

user@host: ~/freeswitch$ nc -u 192.168.1.12 1337
{ "heap" : "overflow\u1" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
^C

TCP port 8021 is part of the Event Socket Module (the server side of the Event Socket Library). This port is less interesting from an attack perspective because it is typically bound to 127.0.0.1 by default, it is password protected, and only IP addresses within an access control list can connect to it. In order to communicate with the Event Socket Module, it helps to understand the protocol or use the event socket library. You can find a suitable client using the event socket library in libs/esl/testclient.c. The client, as written, will log into a FreeSWITCH instance at localhost using the default password (no username, password "ClueCon") and send it a “status” command, which FreeSWITCH will reply to with system health information. If we change line 12 from the esl_send_recv() function to our own custom overflow string, we can trigger the exact same code path that caused the overflow in the FreeSWITCH command line that was mentioned earlier. This attack, of course, assumes you can overcome the ACL, password, and that the listener is not bound to localhost.

The vulnerable JSON parsing code in switch_json.c was first introduced to the code base in 2010 at revision c5086b15174. However, no official release is exploitable with the above methods until version 1.4.4 (May 23, 2014). This is because the code does not appear to accept input from a user until the switch command is introduced to the command line. The code appears to originally exist to reformat system generated "events" into JSON (instead of "plain" or "xml").

Solution

Upgrade to version 1.4.26 or 1.6.5.

Disclosure Timeline

2015-11-05 - Issue discovered
2015-11-19 - Vendor Informed
2015-11-19 - Vendor reply, patch committed to address issue
2015-11-20 - CVE ID requested
2015-11-21 - CVE ID assigned
2015-11-20 - 1.4.26, 1.6.5 released (not sure if fixes, no mention of FS-8160 in bug list)
2015-11-24 - Ping vendor to confirm fix, as well as clarify CVE assignment
2015-11-24 - FreeSWITCH questions why new CVE was assigned, Tenable shares mails / CVE abstraction policy. FreeSWITCH confirms 1.4.26 and 1.6.5 include the patch.

All information within TRA advisories is provided “as is”, without warranty of any kind, including the implied warranties of merchantability and fitness for a particular purpose, and with no guarantee of completeness, accuracy, or timeliness. Individuals and organizations are responsible for assessing the impact of any actual or potential security vulnerability.

Tenable takes product security very seriously. If you believe you have found a vulnerability in one of our products, we ask that you please work with us to quickly resolve it in order to protect customers. Tenable believes in responding quickly to such reports, maintaining communication with researchers, and providing a solution in short order.

For more details on submitting vulnerability information, please see our Vulnerability Reporting Guidelines page.

If you have questions or corrections about this advisory, please email [email protected]

Risk Information

CVE ID: CVE-2015-8311
Tenable Advisory ID: TRA-2015-05
Credit:
Jacob Baines, Tenable Network Security
CVSSv2 Base / Temporal Score:
10.0 / 7.4
CVSSv2 Vector:
(AV:N/AC:L/Au:N/C:C/I:C/A:C/E:U/RL:OF/RC:C)
Affected Products:
FreeSWITCH 1.6.2, 1.7.0
FreeSWITCH Event Socket Library (not versioned)
Risk Factor:
Critical

Advisory Timeline

2015-11-24 - [R1] Initial Release