In the final days of 2010, an exploit for the Windows CreateSizedDIBSECTION vulnerability was added to the Metasploit trunk. The trigger bitmap was taken byte-for-byte from Moti and Xu Hao's slides from the Power of Community conference. However, the method for achieving code execution on Windows XP was slightly different.
Since this vulnerability is basically equivalent to "memcpy(stack_buffer, user_input, -1);", the most reliable road to exploitation is achieved using an SEH overwrite. Unfortunately, Windows XP SP2 and later protects all modules loaded in Explorer.exe with SafeSEH. Additionally, Windows opts in to DEP/NX for Windows Explorer by default. Therefore, both DEP and SafeSEH must be bypassed for successful exploitation.
In order to accomplish that feat, Moti and Xu Hao used the "l3codeca.acm" module. Sadly, that module didn't get loaded during my tests. I later found that it loads when determining the duration of video in the "Details" view mode. Still, relying on two different Explorer window view modes seemed like a bad idea. So I looked for another way.
After a minute or so, the "msacm32.drv" module gets loaded into Windows Explorer's address space. This module is presumably used for handling something to do with ACM sound, but that's largely unimportant. It does mean that this technique will only work on Windows XP machines that have a compatible sound device though. The key fact is that this module isn't protected by SafeSEH! Win! We can use any address in the code segment of this library as our fake SEH handler.
So, now the problem is how to leverage this module to kick off a ROP-stage. At first I was a bit frazzled and rather than deduce the solution logically, I used a technique I like to call trigger-fuzzing. That is, I repeatedly triggered the vulnerability each address in "msacm32.drv" code segment and monitored the results. After less than 512 attempts, I noticed I had a crash with EIP containing the tell-tale Rex::Text pattern.
After investigating the instruction sequence that led to EIP control, I realized the beauty of it. Trigger-fuzzing had led me to a technique that enables replacing pop/pop/ret addresses with something turning them into ROP fairly easily. The magic sauce boils down to this:
mov reg32, [esp+8] call [reg32+off]
As you can see, this will load the address of the SEH record from the stack, then use it's contents for the next gadget. As a bonus, we now have the address of the exception record in a register and can easily reference our payload (since we already know the SEH record offset in our buffer).
Of course, this isn't exactly breaking information, Nor is it the only instruction sequence that will work. While chatting with Peter Van Eeckhoutte, he pointed out that a similar gadget is on the corelan wallpaper. Here are some other possible instructions that could work, just to get your creative juices flowing.
mov reg,[ebp+0c] + call [reg] (from corelan wallpaper) mov reg, fs: / ... / ret (also from corelan wallpaper) pop regX / pop regY / pop regZ / call [regZ+8] push regX / mov regY,[esp+0xc] / call [regY+0xc] mov regY, [ebp+0xc] / push [regY-0x4] / ret mov regY, fs: / mov reg, [regY-0x8] / jmp reg
The question that remains – Which sequences are most common? Is there anything as common as Pop/Pop/Ret?
PS. If you're interested in these kinds of things, we're hiring! See our previous blog post, and try not to be too intimidated :-)