Hey punks, welcome to 2011. I’ve spent the first couple of months this year perfecting my Ac1db1tch3z catwalk pose (they call it “white hat steel”). But now that I’ve got that out of the way, I figured its time to do some more research.
I thought I’d start by sharing a minor Windows 7 exploitation technique for linear heap overflows*. Don’t get excited, as it’s only useful 1) on a small subset of applications and 2) when standard heap manipulation techniques aren’t working. In all honesty there are probably about a half-dozen people in the world who will find this technique interesting.
So anyway, I found this method while reverse engineering the 32-bit structured exception handling routines in NTDLL. This would seem like a strange place to come across a heap technique, since SEH is traditionally the stack-based overlow exploit vector. To get an idea of where this going, it might help to have a look at the reversed SEH implementation on XP:
Perhaps not commonly known, applications can choose to override standard SEH by using a mechanism called Vectored Exception Handling. An application can use the AddVectoredExceptionHandle or AddVectoredContinueHandle API calls to insert either a first chance or last chance exception handling routine distinct from the normal SEH chain. The curiosity is that each VEH entry is backed by a small structure which is allocated on the default process heap.
Unfortunately the VEH function pointer is protected by RtlEncodePointer (even in XP SP3), so we can’t directly manipulate that. However, the fun starts in Windows Vista and later when the VEH dispatch method ended up looking something like this:
In what appears to be an attempt to clean up a race condition with RemoveVectoredExceptionHandler, Microsoft has added code to handle removing a VEH structure when it is no longer referenced (when Depth is 0). How do they destroy a VEH entry? With a classic example of a double-linked list unlink condition, and then a subsequent HeapFree of a potentially corrupted VEH structure.
Our exploitation technique defines itself:
- Position a heap overflow (in the default process heap) next to a VEH entry.
- Overflow the Prev and Next fields of the VEH entry with an arbitrary value.
- Use the NULL-terminating overflow byte to clear the Depth field.
- Trigger an exception and use the VEH unlink to get an arbitrary write primitive.
- Hope (or arrange) that the VEH handler returns EXCEPTION_CONTINUE_EXECUTION (or that there is another exception handler you can abuse with the 4-write!) :]
As you can see, it certainly isn’t universally trivial like the heap-fu of old – but it is interesting, and that’s enough for me.
* It has to be said that memcpy-style heap corruption is rapidly going out of fashion in favour of the more fuzzer-friendly client-side object-use-after-free/uninitialized-variable style vulns. Who needs aa4bmo when you have a referenced vtable sitting in unallocated memory, right?