January 14, 2014

This is the third article in this series that I didn't expect to write but it turns out the fix for CVE-2013-5332 insufficiently addresses the issue around the dialog boxes. Adobe had issued a fix that prevents the testcase I provided them from crashing the plugin but it's still possible to reach the bug just by adding an additional step to that testcase. I talked to Adobe about this.

Now the crash state is different to the crash state previously seen but in both cases the instruction dereferences freed memory. The vulnerability enables the attacker to divert the execution flow via the dispatch table that can be constructed due to a use-after-free issue.

I'm using Application Verifier and GFlags tool to make the vulnerability easy to see, and I'm also doing this because I observed that the application didn't crash at certain times. It could have happened because an object was allocated to the freed memory in a way to contain a valid function pointer. So rather than dereferencing freed memory the wrong function was called by the dispatcher and the execution completed without access violation.

Anyway here is the configuration. I configured GFlags for Internet Explorer 11 like below.

Configured Application Verifier, too.

In Windbg, I set debug of child process so when to open iexplore.exe from the disk I'm able to debug both broker and renderer processes. In the beginning of the article I mentioned that an additional step is required to the testcase in order to trigger the bug. It is to visit a web page that contains a Flash object which simply is to exercise the Flash plugin. After that, we can load the testcase to trigger the dialog box seen below.

At this point we can see many problems reported by Application Verifier. Here are two.

call [rax] suggests to pay attention because the issue could be exploitable if rax is attacker controlled.

We can see the crash happens when we read address near null so you may think it's a non-exploitable null pointer dereference. However to confirm this we need to investigate how rax is set to null. If null is read from previously freed memory we may have the chance to corrupt the memory in a way to inject arbitrary pointer therefore to make the issue exploitable.

We can see the address is fixed, relative to tk85, which was allocated when the module was being loaded in the virtual address space. Now we can say with more confidence the issue is a non-exploitable null pointer dereference.

January 9, 2014

There are functions that can take source and destination parameters to copy data. That functions include the followings: strncpy(), strncat(), memcpy(), wcsncpy(), wcsncat(), strcat(), strcpy(), wcscat(), wcscpy(), CopyMemory(), sscanf(), printf(), swscanf(), swprintf(). If the destination and source regions overlap the behavior is undefined. This really means one of the regions can get partly overwritten when copying. I wrote about this earlier.

Some time ago I wrote a tool to detect such errors runtime and I used Pin framework. Though I've never seen an exploitable bug regarding this classification it's still valuable to detect these issues as the attacker could write memory that he's not supposed to. This could lead to enter the program in an inconsistent state.

The tool I wrote produces the following straightforward output on the test sample.

You may ask what's the news to detect this bug as Valgrind can do for ages. Well, my approach is not to use symbols, source code, or any debug information so I can apply my tests against arbitrary binaries.

Even just few string copy functions were added to the tool I had found plenty low-severity bugs in high-profile applications by this approach.