iSEC Research Labs

Fuzzing RTSP to discover an exploitable vulnerability in VLC

30 Dec 2013 - Michael Lynch

In this post, we will describe the bug iSEC recently discovered in the Live555 library (CVE-2013-6933, CVE-2013-6934). This yielded a remote code execution vulnerability in all client and server applications that use the Live555 library, including the popular media player VLC.

Background

Over the past several months, I've been using the Peach framework to create a fuzzer for client implementations of the RTSP protocol. For those not familiar, RTSP is a protocol that helps media players stream content. It is a text-based format that closely resembles HTTP. A simple RTSP request looks like the following:

GET_PARAMETER rtsp://streams.isecpartners.com/foo/bar.mp4 RTSP/1.0
CSeq: 9
Content-Type: text/parameters
Session: 12345678
Content-Length: 24

packets_received
jitter

My first two fuzzing targets were QuickTime and VLC, two popular media players that implement the RTSP protocol. After running 250,000 iterations against both, QuickTime had a few crashes, though none of them seemed exploitable (NULL pointer dereferences and the like). The VLC fuzzing yielded something more interesting.

Discovery

The issue is a write access violation when VLC receives an RTSP message of the following form:

 A RTSP/1.0
CSeq: 10
Content-Type: text/parameters
Session: 12345678
Content-Length: 24

packets_received
jitter

Note that instead of starting with an RTSP command, the request begins with a space character. To understand why this causes an access violation, we'll jump into VLC's RTSP handling code, which is actually a 3rd party library called Live555. The vulnerable function is parseRTSPRequestString(), which begins as follows:

unsigned i;
for (i = 0; i < resultCmdNameMaxSize-1 && i < reqStrSize; ++i) {
  char c = reqStr[i];
  if (c == ' ' || c == '\t') {
    parseSucceeded = True;
    break;
  }

  resultCmdName[i] = c;
}
resultCmdName[i] = '\0';
if (!parseSucceeded) return False;

Here we can begin to see what the problem is. If reqStr begins with a space or tab character, the function believes that it has parsed the RTSP command (stored in resultCmdName), when in fact it has parsed nothing. Continuing a bit further down in the function, we have the following code block:

// [Ed: At this point, variables have the following values:
//  i=0
//  k=1
//  k1=0
//  n=0]
n = 0; k2 = i + 1;
if (i <= k) {
  if (k1 - i > resultURLPreSuffixMaxSize) return False;
  while (k2 <= k1 - 1) resultURLPreSuffix[n++] = reqStr[k2++];
}

This means that the while statement is really equivalent to:

while (k2 <= 0xffffffff) resultURLPreSuffix[n++] = reqStr[k2++];

which is equivalent to:

while (true) resultURLPreSuffix[n++] = reqStr[k2++];

because k2 is an unsigned int and can never be greater than 0xffffffff.

Exploitation

Right now, this is looking very promising. reqStr points to an address on the heap, and the attacker has a great deal of control over the heap contents through previous RTSP messages. resultURLPreSuffix points to an address on the stack. This means that we can overwrite the entire stack with attacker controlled data. The problem, in the words of security researcher and singer, M. Cyrus:

Miley Cyrus - "We can't stop and we won't stop"

We can overwrite the stack, but we can't terminate the write and continue execution. We're trapped in this infinite loop until the access violation occurs when we reach unallocated memory.

At this point, I was stuck. I shared my results with some colleagues internally and Andreas Junestam, one of iSEC's Distinguished Security Engineers, pointed out to me that I could actually use the access violation to my advantage on Windows. The SEH chain is stored on the stack, so I could overwrite it and gain code execution when the access violation occurs (Corelan has a nice tutorial on how to do this). Within a couple days, I was able to produce a simple proof of concept that pops calc on Windows XP SP3.

VLC proof of concept exploit

I'm cheating a bit by using XP, as every VLC binary for Windows since v.1.0.5 is compiled with DEP, and ASLR. The last version of VLC that was compiled without ASLR or DEP was v.1.0.5, though that precedes the vulnerability, which was introduced in v.2.0.0. VLC v.2.1.1 has SafeSEH, DEP, and ASLR enabled, but I can bypass SafeSEH on XP by jumping to a ROP gadget located within process memory but outside of loaded modules. I could find no such reliable gadget available on Vista and above, especially with ASLR enabled.

Exploitation Vectors

Clients

The video demonstrates three different vectors through which an attacker can exploit this vulnerability against VLC users. The simplest and most straightforward vector is to trick a user into manually connecting to a malicious RTSP server by instructing the victim to select Media > Open Network Stream and enter the malicious RTSP server address.

A more realistic attack vector is to use .pls files. These are playlist files that specify a list of files or streams for a media player to play. When a user installs VLC, it registers itself as the default handler for .pls files. When VLC opens a .pls file, it will automatically connect to any RTSP streams specified in the file.

The most practical and frightening attack vector is via the VLC browser plugin. By default, VLC installs both a Mozilla-based and ActiveX plugin for all available browsers. This allows any web site that a victim visits to launch VLC with site-supplied parameters. An attacker can easily use this to force VLC to connect to a malicious RTSP server and compromise the victim's system.

Servers

Because the vulnerable code is in a component that both RTSP clients and servers share in the Live555 library, an attacker can exploit this against Live555-based RTSP servers as well (including VLC). On Windows platforms, the attacker can gain remote code execution using a similar method to the client attack described above. Regardless of the platform, the attacker can perform denial of service attacks against the server, as the malformed requests will cause the server to crash.

Versions Affected

VLC Version | Live555 Version | Vulnerability
------------+-----------------+--------------
2.1.2       | 2013.12.05      | Fixed
            | 2013.11.29      | Fixed
            | 2013.11.26      | Partial fix
2.1.1       | 2012.12.18      | Vulnerable
2.1.0       | 2012.12.18      | Vulnerable
2.0.0       | 2011.12.23      | Vulnerable
            | 2011.08.13      | Vulnerability introduced
            | 2011.07.21      | Unaffected
1.1.9       | 2011.01.06      | Unaffected
1.1.0       | 2010.03.16      | Unaffected
1.0.5       | 2010.01.07      | Unaffected

Disclosure Timeline

  • 11/25/2013 - iSEC notifies vendor (Live Networks) of the issue (CVE-2013-6933)
  • 11/26/2013 - Live Networks partially fixes issue
  • 11/29/2013 - iSEC tests the fix, identifies remaining variant of original vulnerability (CVE-2013-6934), notifies Live Networks
  • 11/29/2013 - Live Networks fixes issue, encourages clients to upgrade in changelog
  • 12/01/2013 - iSEC confirms fix in Live555
  • 12/09/2013 - VLC releases version 2.1.2, which includes Live555 version 2013.12.05, fixing the issue

Mitigations

For end-users

Upgrade to VLC 2.1.2. To limit your exposure to future vulnerabilities, consider leaving the VLC plugin disabled in your browser or setting it to Click-to-Play. Do not use VLC to open untrusted .pls files.

For users of other applications that depend on Live555, do not connect to untrusted RTSP streams until the client is updated to use live.2013.11.29 or higher.

For developers that use the Live555 library

Update your application to the latest version of Live555 as soon as possible. Urge your users to patch quickly.

For RTSP server administrators

Upgrade your RTSP server to use a Live555 library version 2013.11.29 or later. If you cannot immediately do this, download the latest Live555 source and build the Live555 Proxy Server. Run vulnerable RTSP servers on the back end, where they are not exposed to malicious RTSP requests. Use the Live555 Proxy Server as the externally facing server to route RTSP requests to back end RTSP servers. If the Live555 Proxy Server receives an RTSP request that is attempting to exploit this vulnerability, it will reject the request with RTSP 400 Bad Request without passing it along to a vulnerable back end server.

Conclusions

This type of attack should serve as a reminder to users to be very conservative with their browser plugin configurations. Remember that browser plugins (meaning Mozilla-based and ActiveX plugins) run in processes outside of the browser sandbox and are responsible for parsing arbitrary data from arbitrary web sites. For an application such as VLC, which accepts many file formats and protocols, the attack surface is quite large. Users should enable plugins, not only if they trust the plugin to be non-malicious, but if they trust it to withstand attacks from any web site that's malicious.