Vulnerability Development mailing list archives
Re: win32 call dword ptr [eax] help needed
From: "wirepair" <wirepair () roguemail net>
Date: Wed, 10 Sep 2003 07:47:18 -0700
Thank you very very much for taking the time to respond. Unfortunately I have Zero C++ knowledge. I only code in C, and for the most part just *nix. I am kind of unsure as to how one would tell if this is in the heap or the stack. In Unix (linux anyways) it is very easy because the addresses are easily identifiable 0xbfffxxxx , stack ect. I pushing an insane amount of data into the buffer and it still crashes on the call dword ptr[eax+4]. I tried putting in much less data and this was the *only* function I could overwrite. I have not tried overflowing the buffer and seeing if i can keep the thread alive (I forgot to mention this is a multithreaded app, sorry) past the first call. It looks like #4 is the way i will probably head. I don't know anything about windows internal memory allocation/heap structures so if this is in the heap i'm definitly SoL. As for relying on hardcoded addresses in the stack/heap where ever the hell I am, it *definitly* changes, and oddly enough the address seems to change every 3-4 days. Thanks again for your reply and I have another question brewing on the server portion of this program. Anyone got any good documents on overwriting the SEH in a multithreaded application? (I already read Havlar Flake's ppt.)
Thanks! -wire On Tue, 09 Sep 2003 17:16:49 -0300 Gerardo Richarte <gera () corest com> wrote:
wirepair wrote:But i'm having serious issues making this exploit reliable. Currently, I'm referencing hardcoded values in the stack.Execution flow is altered via a: .text:10011032 call dword ptr [eax+4]James Michael Wakefield wrote:I'm coming up against this problem myself at the moment.This happened to me too, and is probably pretty common, probably more in windows, where there is more C++ code, but it also happens in *nix. There are a bunch of things going on, one, as Dave said, may be that you are overwriting an object's vtable in the heap, another may be that you are just overwriting some function pointers. But from what you said, and from now on is all guess work, I believe you are overwriting a pointer to an object, not the object itself, not its vtable directly, you are overwriting a pointer to an object, may be passed as argument to the function where the bug is... so, in C++ (as I said, this is all guess work, and I don't even know what application it is we are talking about, so EVERYTHING may be wrong) vuln_function(SomeClass *obj_arg, char *str_arg) { char *buf; ... strcpy(buf,str_arg); ... obj_arg->someMethod(); ... } In this example, if you overflow buf, you'll overwrite some local variables, the saved frame pointer, the saved return address and the saved argument [note that your object pointer may be anywhere, not only in an argument and not only in the stack, lets assume you are changing an object pointer]. So, when the line "obj_arg->someMethod()" is reached, this may be a possible assembly of it: mov ecx, [ebp+8] ; pointer to object in eax mov eax, [ecx] ; pointer to SomeClass' vtable call [eax+4] ; call 2nd method of SomeClass each object, as first field, have a poitner to its class' vtable, and vtables are no more than a list (array) of function pointer (for the compilers I know at least). For the level of indirections you said you have, I guess this, or something pretty similar is going on: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.So, let me say, this has become pretty common lately. now, what to do? Several options... but first, why do you think relaying on a hardcoded address for the stack is not reliable enough? What does stack addresses depend on on windows? Well... stack addresses in windows tend to be more reliable than what we think, this is not to say that it's always ok to trust them, but when talking about reliability we should ponder all options, and then choose the more reliable... so we need to know what things depend on, or why the change. Simply said, on windows, stack addresses depend on the program itself, and on the thread that's using that stack (they don't depend on program's args or environment, as in *nix). So, for a given program, with only one thread, it's pretty common that the stack address will stay "fixed". Now, let me add that this is not "science", it's just empirical observation (plus some other things). In multi threaded programs, if the threads are created and used allways in the same order, it's also possible that the address can be trusted. (Similar things happen, in for example, Solaris' lightweight threads). So... anyway, let's go back to what to do in your situation. Several ideas. 1. James' idea of trying to supply your own pointers and code, and somehow raise the possibilities of hitting both. This can work, it depends on lots of things though. 2. If the overflow is in heap, doing what Dave said And, assuming the overflow is in stack, as I think you said: 3. making an even bigger overflow if possible, hit and change the Exception Registration Record, and using JMP EBX (in 2k), or a similar techinque in XP. 4. trying to make the code survive the call [eax+4] without crashing, trying to make the code survive everything else until the return of the vulnerable function and then use the overwritten return addr to jump to your code (probably through a jmp esp) 3 may look interesting, but on some situations it may not be desirabe. (for example, if the exploited applicacation knows how to survive an exception, etc). There is not much to say about it, there is at least one exception handler in the stack for every application, again, if the application is multithreaded, it depends on what thread's stack you are overflowing, etc. After changing the ERR you'll need to make the application/thread crash, but in your case this is pretty easy :-) [just make call [eax+4] do it for you] 4 may be complicated, but we had good lcuk when we needed it... lets go back to what we are doing: Overwriting a pointer to an object. So, if we find any fixed pointer to an object, whose 2nd vtable entry will not crash, that's your option... Now, when an object is instantiated in C++, some space is allocated for its data, and in its first field the "class pointer" is stored, so the "new" for SomeClass may look like: newObjetc = malloc(space_needed) ((int*)newObject)[0] = &SomeClass_vtable so, in assembly, the second line would be something like: 10013106: C7 06 22 35 02 10 mov dword ptr [esi], offset SomeClass_vtable then, in the middle of this instruction you have a pointer to the class pointer (SomeClass_vtable, in this stupid example, the pointer is 10023522, and is at the address 10013108)... Now, at 10023522 you can find the vtable, and if the 2nd entry is a function that won't crash in your situation, the that's what you need. You just change whatever needed to 10013108, so eax will be 10023522, and [eax+4] will be your "void function"... now, if mi assuptions are not correct (overflow is in stack, and you are overwriting an object pointer), then, this is not probably going to work for you, but I hope at least it makes sence to somebody :-) let me know if all this words were helpful gera
-- Visit Things From Another World for the best comics, movies, toys, collectibles and more. http://www.tfaw.com/?qt=wmf
Current thread:
- win32 call dword ptr [eax] help needed wirepair (Sep 08)
- <Possible follow-ups>
- Re: win32 call dword ptr [eax] help needed dave (Sep 09)
- Re: win32 call dword ptr [eax] help needed James Michael Wakefield (Sep 09)
- Re: win32 call dword ptr [eax] help needed Gerardo Richarte (Sep 09)
- Re: win32 call dword ptr [eax] help needed wirepair (Sep 11)
- Re: win32 call dword ptr [eax] help needed Gerardo Richarte (Sep 11)
- Re: win32 call dword ptr [eax] help needed Gerardo Richarte (Sep 09)