Internet Security Systems - AlertCon(TM)

CanSecWest Follow-Up: MJPEG Vulnerability

Posted by Mark Dowd on June 11, 2008 at 2:53 PM EDT.

Back in March, John (McDonald) and I presented at CanSec West about finding media vulnerabilities in Windows playback software. Specifically, we focused on applications that utilize the frameworks available in Windows - mainly DirectShow, as it seems the most prevalent at this time. (We originally had planned to also speak more on Video for Windows and Media Foundation, but alas, there was not enough time.) We wanted to present some vulnerabilities that we had uncovered when auditing various media codecs, but none of them were ready for public disclosure at the time. Microsoft has just released a patch for two of the bugs that we had intended to present. Both vulnerabilities are in the same function and are somewhat related, and I will take a little time to describe them here.

The bugs in question are in the "Motion JPEG" (MJPEG) filter, which is accessible by default on Windows operating systems. As we mentioned in the presentation, the media codec selected for decoding data streams from video files is determined by a pair of GUIDs indicating the major type and sub type of each stream. In the case of AVI files, two 4-byte character codes (called FourCCs) are embedded in the file to identify each stream, rather than the full GUIDs being there. By using the major type FourCC "vids" and the sub type FourCC "MJPG", we can cause the MJPEG filter to be selected for decoding a particular data stream in our AVI file.

Before I explain specifically what the problem is, I need to provide some brief background information on video samples. When a video stream is encountered in DirectShow-based software, there is an initial negotiation step that takes place between two connected filters to communicate what kind of data is going to be sent down the pipe. In this case, the AVI splitter filter will negotiate with the MJPEG decoder filter, and indicate that the data for this particular stream is MJPEG data. Some additional information will also be conveyed - most notably, the dimensions and color depth of the supposed data being sent. How does the AVI splitter know the dimensions of the image? They are indicated in a BITMAPINFOHEADER structure, which can be found in the "stream format" chunk for this particular stream. The dimensions need to be known at the time of stream initialization because output sample buffers are pre-allocated in DirectShow, for stream-lining reasons. This whole negotiation process is fairly involved, and any interested readers should check out our slides for more information.

One of the things we pointed out as being a source for potential problems in DirectShow filters is size mismatches between header information in the container format (in this case, the BITMAPINFOHEADER in the AVI file), and those indicated in meta-data in the stream itself. Many data formats, including MJPEG, have internal headers that indicate things such as image dimensions. Why repeat this information? Because these data formats are often not made to be exclusively embedded in a container file such as AVI. At any rate, if a filter is writing into a pre-allocated output buffer, it needs to ensure that the sizes it's using as image dimensions match those that were used during the initial stream setup. In other words, if they use meta-data from internal stream headers, then that meta-data should match what was supplied in the BITMAPINFOHEADER in the container file. Failure to do so can lead to memory corruption problems, as is the case here. I'd like to go further into detail, but let's wait for everyone to patch first, eh? For those interested, we have a slide in our deck (from CanSec West) that is basically a watered down example of this exact scenario. This is a pretty easy mistake to make, and we expect to see more of this kind in the future.

Comments or opinions expressed on this Weblog are the opinions of the authors alone. They are not necessarily reviewed in advance by anyone but the individual authors, and neither IBM Internet Security Systems nor any other party necessarily agrees with them. The views expressed by outside contributors and links to outside websites do not represent the views of IBM Internet Security Systems, its management or employees. All content on this Weblog has been made available on an “as-is” basis, and IBM Internet Security Systems shall not be liable for any direct or indirect damages arising out of use of this Weblog.