Apple has released its latest Security Update for OS X.
Dubbed simply 2013-003, the update fixes a trifecta of memory corruption bugs in QuickTime caused by buffer overflows.
Technically, one of the bugs is listed as a buffer underflow, which is just a buffer overflow the other way round.
An overflow writes past the end of your own memory buffer, trampling on the next block of memory, which may well be in use for something else; an underflow writes in front of your memory, with a similarly risky outcome.
These bug fixes should all be considered critical, because they could be exploited for remote code execution.
In other words, a deliberately-tweaked movie file could trick your Mac into running program code hidden in the movie itself, even though such files are supposed to consist entirely of data.
Getting the update
As usual, Apple Menu followed by Software Update... will sort you out if you want a single-click update. (Annoyingly, but not entirely unusually, a reboot is required to install this update, so don’t do it smack in in the middle of something interesting or important.)
If you want to do the update by hand or to grab the installer now in case you ever want to reinstall OS X, here is a table of co-ordinates:
If you have: | Size | Download page |
---|---|---|
Mountain Lion (OS X 10.8) | 21 MB | DL1667 |
Lion (OX 10.7) | 61 MB | DL1668 |
Lion Server (OX 10.7) | 112 MB | DL1669 |
Snow Leopard (OX 10.6) | 350 MB | DL1670 |
Snow Leopard Server (OX 10.6) | 425 MB | DL1671 |
The flaws described
All three of the flaws get a very cursory explanation from Apple, limited to a boilerplate comment for each one, in this format:
Buffer overflow in Apple QuickTime...
...allows remote attackers to execute arbitrary code or cause a denial of service (application crash) via N
The various values of N are:
- CVE-2013-1019: N = “a crafted movie file with Sorenson encoding.”
- CVE-2013-1018: N = “a crafted movie file with H.264 encoding.”
- CVE-2013-1022: N = “crafted mvhd atoms in a movie file.”
So much for the update.
Why movie files?
Why, you may be wondering, do files such as images and movies, as well as documents of various sorts, appear frequently in this sort of vulnerability report?
What is it that makes files of this type especially suited to “crafting”?
→ Crafting a file is geek shorthand for manipulating a file so that, although it is out of specification and ought to be rejected by the application it is targeting, it will nevertheless load and deliberately trigger dangerous misbehaviour in that application.
Part of the problem with multimedia files is that they are often pacakaged as a giant blob of binary data that resembles machine code for a virtual machine.
The files consist of opcodes, also known as instructions, and variably-sized operands, or data to go with the instructions.
So, an application that parses and processes a file like this has to take it apart byte-by-byte and manipulate it in memory, often relying on the correctness of individual data items inside the blob itself to work out what to do next.
A QuickTime file, for example, consists of a sequence of instructions called atoms that each require special processing, and which can be nested and packaged together into MOV files of considerable complexity:
Each atom starts with a fixed four-byte value that tells you how big it is.
Here you can see the main Movie atom in a sample MOV file, denoted by the header moov, and stated to be 47,074 (0xB7E2 in hexadecimal) bytes long:
The MOOV starts with an embedded Movie Header of 108 (0x6c) bytes, labelled with mvhd:
The MVHD is followed by a Track, labelled with trak:
And the TRAK, already nested inside the MOOV, itself contains a nested Track Header, denoted tkhd:
It’s already looking pretty complex, and that’s before you’ve even tried to turn the MVHD or the TVHD atoms into any meaningful data inside your application.
The MVHD vulnerability
You’ll note that the MVHD atom is one of the object types listed above as exploitable.
We don’t know exactly what form the bug took, and Apple will probably never publicly say, but we can use the sample file above to remind ourselves of the sort of problem that processing this type of data can cause.
So let’s speculate – it doesn’t matter if we’re right or wrong, as our goal here is just to think about the sort of mistake that is easy to make when coding.
Firstly, notice that the size marker of each atom includes the 4-byte size of the size marker itself.
So you might write code like this to process an atom:
That’s not going to work, because size includes the size of itself, so there are only size-4 bytes of data:
This code works, but it’s fragile.
For example, what happens if someone deliberately creates an atom with a size of 1?
You should notice that and reject it, since the mimimum size of an atom is the 4-byte size field.
If you don’t look for and block this error, then a “crafted” size of 1 makes your code do this:
What happens here depends on many things, notably whether the calculation size-4 is done using signed or unsigned integers.
If you subtract 3 from a value of zero treated as a 32-bit unsigned number, you can’t get a negative result, because unsigned integers wrap around at zero.
It’s like winding a clock back one hour from midnight: you don’t get minus-one o’clock, you get 11pm on a 12-hour clock or 23:00 on a 24-hour clock.
So an unsigned 32-bit value of zero with 3 subtracted turns into 232-3, or 4,294,967,293, so your code suddenly does this:
In this example, an integer underflow leads to a buffer overflow.
Another possible problem is that the mvhd atom has a fixed-length structure that is always supposed to be 108 (0x6C) bytes long:
So you might slip up, and write the above code inflexibly, coding straight from the specification:
Faced with a well-formed file, your code will work just fine, because size will be 108 (as it is in the sample file above) and everything will line up.
If someone “crafts” a file with a size of -4096, however, you’ll be doing this:
When you come to manipulate the buffer for the next atom, you will be operating on memory in front of your own memory block, and things will almost certainly go wrong.
That’s just two examples of potential coding bugs in one multimedia file type – and so far, we haven’t even tried to do anything with the data in the file.
Check, check, and check again
In real life, we’ll have loads more to do, such as extracting and using the movie header and track data, as well as actually decompressing and displaying the video images.
So be careful out there if you’re a programmer, and remember that you can never have too much error-checking:
And don’t wait for cybercrooks to come up with movie files containing negative MVHD sizes.
Stay ahead of your attackers with a robust and well-thought out set of test files.
Love the article!
Glad you liked it!
If you're interested in this sort of article, we run them as a sort of occasional series (meaning that they appear fairly frequently, but not necessarily regularly :-), covering topics like browser security, cryptography, phishing, exploits, targeted attacks, and more.
Just go to the [search articles] box at the top right of any Naked Security page, and out in the word "Anatomy".
If you have a wish-list for articles in the Anatomy Of series, please let us know: just email tips@sophos.com.
Love this article, already a subscriber but I love the details. (Y)
I wonder if this vulnerability exists in iOS? Presumably there's a lot of shared code between higher level functions like the ability to play Quicktime movie formats?
Thanks for an Amazing enlightenment article…
Am still running Tiger (10.4.11), because of the architecture (PeoplePC) of my machine. At times I think Sophos, is all that allows me to stay on line. I do wish however that Apple could still send out updates to old machines.
A very clarifying explanation, ty.
🙂