Vulnerability Development mailing list archives

Re: win32 call dword ptr [eax] help needed


From: <dave () immunitysec com>
Date: 9 Sep 2003 11:30:24 -0000

In-Reply-To: <web-17355992 () gator darkhorse com>

What you've done is overwrite a C++ object's vtable in
the heap. This is almost never reliable, in my
experience. Your best bet is to go back, perhaps use a
much smaller attack string, and find some way to do the
chunk-overwrite instead. Then overwrite a known
function pointer (or, if you know the target's SP, the
unhandled exception function pointer). (Or write a
instruction somewhere and then set the function to
point to that with another word-write...)

Dave Aitel
Immunity Inc. 



I'm working on writing an exploit for a unnamed
program. (I will release details once i'm told a patch
is available.
But i'm having serious issues making this exploit
reliable. Currently, I'm referencing hardcoded values
in the stack.
This is obviously a terrible idea, even though i've
had this exploit work on multiple machines even with
reboots.
But all of a sudden the addresses changed on my
machine which obviously broke my exploit.
Execution flow is altered via a:
.text:10011032                 call    dword ptr [eax+4]
Here is where my problem is, I need to find two
reliable addresses.
one address to contain another address to contain the
address of my shellcode.
I searched memory looking for my overflow string, it
*only* resides in the stack. So I tried searching
for addresses that would reference that area of the
stack and i've come up with nothing. The overflow string
only exists once in memory. What i need help with is,
is there a specific technique for this type of
exploitation?
Here are some of my notes to make this situation a
little bit more clear:
This is a network client based overflow so my exploit
listens on a specific port.
Once the client connects I send a large string, the
first 4 bytes appear to be use in calling w32.recv();. 
How this relates to the overflow i'm not sure i've
only followed the full execution once and i was tired
at the time :).
Here is the actual function of the execution being
altered:
.text:1001101E loc_1001101E:                         
 ; CODE XREF: sub_10010F80+69j
.text:1001101E                                     
   ; sub_10010F80+147j ...
.text:1001101E                 mov     eax, [ebx]
.text:10011020                 mov     ecx, ebx
.text:10011022                 mov    
[esp+328h+timeout.tv_sec], 78h
.text:1001102A                 mov    
[esp+328h+timeout.tv_usec], 0
.text:10011032                 call    dword ptr [eax+4]
.text:10011035                 test    al, al
.text:10011037                 jnz     loc_100110E2
.text:1001103D                 mov     edx,
[esp+328h+writefds]
.text:10011044                 mov     edi,
[esp+328h+readfds]
.text:1001104B                 lea     ecx,
[esp+328h+timeout]
.text:1001104F                 push    ecx           
 ; timeout
.text:10011050                 push    ebp           
 ; exceptfds
.text:10011051                 push    edx           
 ; writefds
.text:10011052                 push    edi           
 ; readfds
.text:10011053                 push    0             
 ; nfds
.text:10011055                 call    ds:select     
 ; Determine the status of one or more
.text:10011055                                       
 ; sockets, waiting if necessary
.text:1001105B                 mov     esi,
[esp+328h+arg_10]
.text:10011062                 mov     ecx, ebx
.text:10011064                 mov     [esi], eax
.text:10011066                 mov     eax, [ebx]
.text:10011068                 call    dword ptr [eax+4]
this would be the overflow function, execution is
redirected by the call dword ptr [eax+4] via 10011032.

00DA02EF   8BBC24 3C010000  MOV EDI,DWORD PTR SS:[ESP+13C]
00DA02F6   8B06             MOV EAX,DWORD PTR DS:[ESI]
00DA02F8   8B9424 38010000  MOV EDX,DWORD PTR SS:[ESP+138]
00DA02FF   8BCF             MOV ECX,EDI
00DA0301   2BC8             SUB ECX,EAX
00DA0303   6A 00            PUSH 0
00DA0305   03C2             ADD EAX,EDX
00DA0307   51               PUSH ECX
00DA0308   50               PUSH EAX
00DA0309   8B45 04          MOV EAX,DWORD PTR SS:[EBP+4]
00DA030C   50               PUSH EAX
00DA030D   FF15 9058DA00    CALL DWORD PTR
DS:[<&WSOCK32.#16>]                                   ;
WSOCK32.recv
00DA0313   8BD8             MOV EBX,EAX
now EAX contains 6C3 (size of our buffer of
characters) which was read.


Sets buffsize to 41414141?!?! i presume it reads in
the data from the server, the server
should be responding with 'hey i have this much data
for you to read', so the client ack's 
and uses the 41414141 as the size to wsock32.recv
function call.


this is for calling WSOCK32.recv

0182E660   00000174  |Socket = 174
0182E664   0182E820  |Buffer = 0182E820
0182E668   41414141  |BufSize = 41414141 (1094795585.)
0182E66C   00000000  \Flags = 0
0182E670   0182E820  ASCII "127.0.0.1"



edi contains 5th-8th bytes of our data
eax is null
edx is our ip
ecx is set to edi (5th-8th byte)

so buffsize is set to 5th to 8th bytes for the call to
wsock32.recv

------------------- later on in the program
----------------------

00DA101E   8B03             MOV EAX,DWORD PTR DS:[EBX]
00DA1020   8BCB             MOV ECX,EBX

eax is set to the beginning of the string 0x41414141
ebx contains the address of our string, which is
copied into ecx.


00DA1022   C74424 14 780000>MOV DWORD PTR SS:[ESP+14],78
00DA102A   C74424 18 000000>MOV DWORD PTR SS:[ESP+18],0
00DA1032   FF50 04          CALL DWORD PTR DS:[EAX+4]

boom. our address 0x41414141+4 (0x4141414145) is
called for execution.
and since we control this address we overwrite it with
a *ugh* hardcoded
address in the stack. 
0x0182eb40 -> overwrite eax with this address, which
gets +4 added to it. this is 
the address of the next 4 bytes after the address
which we used to overwrite eax with.
since its a call dword ptr call, we need to put the
NEXT address of the four bytes in this 
location.
so here's the flow:
overwrite EAX at 808th (decimal) byte which is addr:
0x0182eb3d, with the address of
0x0182eb40. which gets 4 added to it making 0x0182eb44.
the address of 0x0182eb44 contains the address of
0x0182eb48 which is the address
of our shellcode. 

CALL DWORD PTR EAX+4 => [Next 4 bytes] => Address of
Next 4 Bytes which is the beginning of our shellcode.

As you can see this is a *terrible* exploit, so, once
again is there any technique I am missing?
any help would be *greatly* appreciated.

Sorry I can not give out any more information on the
program but i have to wait until i hear something from
the makers!
-wire
--
Visit Things From Another World for the best
comics, movies, toys, collectibles and more.
http://www.tfaw.com/?qt=wmf



Current thread: