[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: win32 heap overflow exploitation

----- Original Message ----- From: "Barnaby Jack" <bjack@xxxxxxxx>
Sent: Monday, October 27, 2003 5:26 AM

----- Original Message ----- From: "Adik" <netninja@xxxxxxxxxx>
Sent: Sunday, October 26, 2003 3:29 AM

Hi there folks,

I'm havin a problem exploiting an application vulnerable to heap overflow. i can write 4 bytes to any place in the memory.

mov dword ptr[eax], ecx
mov dword ptr[ecx+4], eax

I control ecx and eax. I tried overwriting unhandledexceptionfilter pointer (located at address 77ee044c) with a pointer to call [ebp-28] this is
where a pointer to my shellcode is located.

eax=77ee044c <--- unhandledexceptionfilter pointer of my version of Windows
ecx=77f8ce83   <--- .text unwritable address points to -> call [ebp-28]

The second line mov dword ptr[ecx+4], eax suppouse to trigger access
violation on write , because ecx is unwritable address thus invokin exception handler. Because exception handler address is overwritten with pointer to call [ebp-28], it should theoretically execute call [ebp-28] then my shellcode. But its not doin so. Maybe i'm doin somethin wrong. A little help on that would b great.

Have you set a breakpoint on the filter to verify that the offset contains
your data?
If using the unhandled exception filter your data should also exist at

Another possibility is that you are running the code under a debugger. UnhandledExceptionFilter detects this, and deliberately doesn't call the pointer you've overwritten in that case. Here's the relevant code, from w2k sp2 - your version should be very similar:

0:001> u
77eb9910 6a07             push    0x7
77eb9912 e8c3d1fcff       call    KERNEL32!GetCurrentProcess (77e86ada)
77eb9917 50               push    eax
77eb9918 ff15b810e877 call dword ptr [KERNEL32!_imp__NtQueryInformationProcess (77e810b8)]
77eb991e 3bc3             cmp     eax,ebx
77eb9920 7c09 jl KERNEL32!UnhandledExceptionFilter+0x7a (77eb992b)
77eb9922 395dc8           cmp     [ebp-0x38],ebx
77eb9925 0f8529020000 jne KERNEL32!UnhandledExceptionFilter+0x2c3 (77eb9b54) 77eb992b a14cf4ed77 mov eax,[KERNEL32!BasepCurrentTopLevelFilter (77edf44c)]
77eb9930 3bc3             cmp     eax,ebx
77eb9932 740d jz KERNEL32!UnhandledExceptionFilter+0x98 (77eb9941)
77eb9934 56               push    esi
77eb9935 ffd0             call    eax

The call to NtQueryInformationProcess with info type 7 checks if a debugger is attached by seeing if the process debug port setting is non-NULL. If so, the code flow jumps to 0x77eb9b54, which exits and allows the debugger to get at the unhandled exception. So if you're running under the debugger, this branch will be taken. You can bypass this branch (replace with nops) so as to get the expected behaviour under the debugger. Or, noticing that if the NtQuery.... call fails, the test is bypassed and your overwritten exception handler is always called, you can edit the "cmp eax,ebx" to "nop; dec eax" so as to always trigger the jl on the next line: so on w2k sp2, in windbg, you'd just say

eb 77eb991e 90 48

and then your shellcode should be called.

Credit is due to Dave Aitel, for mentioning this in his writeup of the recent DCOM bug "MSRPC Heap Overflow ? Part II". I've only just started experimenting with heap-based overflows myself and it took me ages of single stepping through UnhandledExceptionFilter to see why my function wasn't getting called, then I remembered reading this paper and the penny dropped. Cheers Dave!


It's fast, it's easy and it's free. Get MSN Messenger today! http://www.msn.co.uk/messenger