How Do You Detect Security Strikes? Part 2: File-Format strikes
In a previous blog post, I described some of the different ways we alter, rearrange, and otherwise obfuscate exploit code within our Application and Threat Intelligence (ATI) service strikes. In this continuation blog post, I'm going to discuss some of the measures we take to change things up for our file-format strikes.
File-format vulnerabilities offer ample opportunity for randomization and truly testing protection devices. We can send a given file over the wire in several different ways (HTTP, SMTP, POP3, etc.) and some of these affect how an inspection device sees the bytes.
In the case of some strikes, we generate the entire file dynamically at runtime into which the bad values are inserted. The strike for CVE-2013-3174 is great example of that – for each run of the strike, we dynamically generate a raster block, wrap it in an image block, and insert it between a dynamically-generated header and trailer. Each run of the strike can generate a unique and otherwise valid .gif file, after which we insert bad values at the appropriate locations. The vulnerability is related to bad values in the image header, and without a signature that can thoroughly parse the .gif file-format, it can be very difficult to detect an exploit for this vulnerability.
Most frequently though, when we write a strike for a file-format vulnerability, we'll start with a harmless file, generated by the vulnerable application. And while this may limit the range of possible forms an exploit can take, we strive to provide as many variations as possible. This can include choosing from one or more locations to place the bad values, choosing variations of bad values, and in some cases, even modifying significant parts of the file before sending over the wire.
The strike for CVE-2013-1017 shows several techniques for modifying a file prior to transmission. This vulnerability is related to the MPEG-4 file format, with bad values inside a dref atom contained in a .mov file. In the case of this particular strike we start with one of two different .mov files are used as the basis for this strike, and one of which is found fairly frequently on the Internet – so no simple string matches here. First the bad atom is built using random but valid values. Next we dynamically create the layers of parent atoms, up to the moov atom. The replacement values are built at runtime, but for this strike, each of the four primary variations sends the original file modified in a different manner, resulting in these variations:
- Replace just the dref atom (one permutation for each of the existing dref atoms)
- Replace the parent atoms up to and including the moov atom
- Insert our dynamic moov atom at the beginning (the .mov file now contains two moov atoms)
- Send the moov atom by itself
Each of these modified files can be used to exploit the vulnerable application. The FalsePositive version of this strike appends the moov atom (two moov atoms again) at the end of the .mov file, but it is ignored by the application; which means that while there may be bad bytes that show up on the wire, it is not a valid exploit for this vulnerability.
Below are screenshots showing examples of the primary variations.
Replaced dref atom:1
Replaced moov atom: 2
Prepend moov atom: 3
Moov atom only: 4
And of course, in these images you can see random strings of varying lengths used for the data and file names, as well as case-insensitive file extensions.
In cases where there are multiple vulnerable fields, we try to have at least one variation of the strike for each field. But assuming the transport methods and file structures are known, these should not present too much difficulty for a detection device. The difficulty for protection devices comes primarily from two areas: how much of a file to read, and understanding values at the network layer. If a device tries to walk down the structure of a large file it's going to take some time; and it's going to take even longer if there are multiple pathways that need to be explored. So you'll typically you'd try to identify some unique aspects of a file so that you can identify the filetype you're inspecting; and then look for some identifying contextual aspects, before finally looking for the bad value.
But the problem with that approach is 'context-awareness': unless your protection device can understand how to determine an offset or make a decision based on the result of a calculation, you'll never really be sure where you are within a file when you come across a bad value. And this is exactly what we do with the strike for CVE-2009-3955. The vulnerability is related to a bad value within a Region of Interest header in a JPEG 2000 file (.jp2).
The strike has four variations, each of which contains a bad Region of Interest header in a different location. Since the header is relatively small (2 byte type, 2 byte length, 3 or 4 bytes of data), it should be pretty easy to detect any bad headers. But as you can see from the FalsePositive variation of this strike below, the byte pattern for this bad Region of Interest header (8 bytes starting with FF 5E) actually falls inside another header (type \xff\x64, length \x00\x23), and is treated by the application as data.
Badness in header data: 5
The example above illustrates one of the reasons that writing good quality protection signatures is so difficult.
While preventing the bad stuff is paramount, something else to consider while we're discussing file-format strikes: not only do you want to block the bad stuff, you also want to know what you are blocking. And to that end, we do our best to ensure that a device that blocks our strike is blocking it for the right reasons. For the cases where we modify a harmless file at runtime, as often as possible we reuse files. And by that I mean, modifying a file in different ways depending on the vulnerability being exploited. For example, we have one base .mov file that's used by 11 different strikes – which means modifying the base file for 11 different vulnerabilities. And many of our strikes will randomly select from a number of previously-used files.
Not only does this keep the size of our updates smaller, I believe that this also assists in compelling vendors to develop better protections. If a vendor were to claim protection for a specific vulnerability, but the underlying signature relied on a unique string match found in one of our files, they would have a hard time detecting other vulnerabilities using that file.
While this may seem like we're just making life more difficult for protection vendors, I believe that as a testing company, we should provide the most robust testing possible. Rather than a negative, I believe that this provides vendors with an opportunity for differentiation, a chance to show that their product is better. Hopefully this raises the bar for all vendors – which should translate to better protection for all of us. In the end, we want vendors to be able to block our attacks – we just want them to block them for the right reasons; no cheating :)
Leverage Subscription Service to Stay Ahead of Attacks
The Ixia BreakingPoint Application and Threat Intelligence (ATI) program provides bi-weekly updates of the latest application protocols and attacks for use with Ixia platforms.