r12 is the base address of a structure. The instruction reads a word value from the structure using a delta value that is RCX*2. In our case, RCX is 0`ffffffff which cannot be a valid delta value as the size of the memory region of the structure is only 4000 bytes as seen below. Therefore by executing the instruction it reads out of the bounds of the structure, that is likely an invalid memory address.

As seen below, movzx now tries to access to a valid memory region recently allocated by .dvalloc, filled with zeroes. If we let the program execute now it doesn't crash. Even if we refresh the SVG file it doesn't cause a read access violation because now the memory movzx tries to access is a valid address in the virtual address space.

Using the PoC, later on the execution the program doesn't read the tainted data from the second structure that is verified by processor breakpoint.

The tainted word value was zero as .dvalloc filled the memory with zeroes. Since we know the address of the word value we can try all the 65536 possibilities and watch what happens when processing the different word values. To achieve this I wrote a wrapper HTML which calls the SVG file periodically. Also, I set up the below commands which does the job automatically, so in every iteration we provide different tainted input in range of 0 to 65535.

If this code can be reached when [rdi+7c] is the tainted data that might have consequence due to the complexity of the code paths in this function. I however was unable to reach this code path in my experience.

The address of invalid read is predictable by the attacker as it's always 2 x 0`ffffffff plus something which can be filled with attacker controlled data. But this doesn't seem to be relevant as Microsoft just confirmed that they had finished their investigation into this crash and as they say "[we] can confirm that this crash is caused by a read AV which is not exploitable." I believe them and I no longer investigate this but will focus on other crashes, but thought to share this.

November 12, 2012

When performing security testing of the native application I often attach Windbg to the target process. The obvious benefit of this methodology is that when an exception occurs it's possible to immediately analyze and save the state information of the program. There is one more important benefit, and that is you can get additional information of the running application if you set certain options beforehand. For example, sxn ud command sets up the debugger to send notification when a module is unloaded. I find very useful to analyze Windbg log during security testing, rather than just relying to find exception or memory corruption.

Some time ago, during testing Internet Explorer 9, I noticed that Windbg screen had been flooded with the following messages.

The application continued running without displaying more of these messages and there was no sign the integrity of the application corrupted. My first thought was it's the result of one of Windbg commands I set up earlier just before executing the test. The second thought was that it is unlikely because it seems to be a CRT error message, that most likely comes from the runtime DLL. I knew there is a way to send message to the debugger from an executable and that is to call OutputDebugString function.

I set up a breakpoint for OutputDebugString, and rerun the test. Here is the call stack when the breakpoint hit.

string2 and count both look healthy however string1 is NULL but the API documentation expects a string.

To make sure everything is ok with string2 let's check.

0:005> du @rdx00000000`60903848 "http://"

It's fine, so the only problem with parameter string1 and the problem is that a NULL pointer is passed rather than a pointer to the string.

Microsoft long time ago added security enhancements in the CRT library. One of them involves to call invalid parameter handler which, for example, checks for NULL pointer parameters, and we terminate gracefully rather than with invalid memory access exception.

As you can see the return value is the highest positive value that can be represented in signed 32-bit. If the application is not prepared to handle this edge value it could cause problem later on the execution. Fortunately, that was not the case with Internet Explorer.