Domanda

Assuming an x86 system with no aslr I'd like to ask the following;

1) Theory says that when we execute a stack overflow attack, the value pointed to by the ebp register is overwritten with the new return address too.

Now, since we never go back to the caller function we don't really need ebp's original value to restore the previous stack frame but nevertheless, ebp register must point somewhere at all times. How ebp is set after the eip register starts pointing to our new shellcode? More specifically, which of the two assembly instructions (leave-ret) induces a further microinstruction which restores ebp to a value?

2) Last but not least, I would also like to ask how do we make sure that in occasions where our shellcode needs to push a couple of values on the stack, these values won't overwrite any part of the shellcode? In other words, how can we be certain that any shellcode generated variables will only be placed before the start of the shellcode and for instance not somewhere in between?

Thank you all in advance.

È stato utile?

Soluzione 2

In answer to part 2 of your question: Depending on the syscall you are making, you may have to put a value into esp (as an arg array). If that's the end of the shellcode then you are fine. However, if there is more to the shell code and you happen to do a push and the esp happens to point somewhere in the rest of your shellcode you might be in trouble (because at that point you will be writing over your own instructions). A simple fix is to do something like sub $0x99, %esp at the very beginning of the shellcode.

EDIT (in response to the comments)

Perhaps I misunderstood you question. When you said 'stack overflow' I assumed that you meant a buffer overflow. If I assumed correctly then read on. Assuming you really are talking about a classic smashing-the-stack sort of exploit (which seems to be the case based on the picture you linked to), then you are filling a buffer with a nop sled, shellcode and finally overwriting the return pointer. The shell code is "position independent code". That means that it is a series of instructions that can be executed regardless of the current state of the registers, flags etc.

Normally, (this is also the way the link that you posted depicts it) you fill the buffer with nops, followed by the shellcode, and finally a return address that points somewhere in tho nop sled. When the ret instruction is executed, the address in %esp is poped into %eip and %esp is incremented by 4 (in x86). The problem is that if your shellcode has several push instructions, this has a side effect of decrementing %esp. If you have enough of them and your shellcode is all the way at the end (i.e. adjacent to the return address) then you may end up overwriting your shellcode with the push instructions.

So, to actually answer your question. No, there is no 'mechanism' to separate your shellcode from 'its stack'. This is because there is no stack per-se for your shellcode. Remember, it is position independent code. It must be able to run regardless of machine state. Any stack management that needs to happen must be performed by the shellcode itself. That is why I suggested a sub $0x99, %esp at the begning of the shellcode if you have many push statements in the code. Another option is to make sure there sufficient space between the return address (which %esp-4 will be pointing at) and your shellcode.

Altri suggerimenti

1.When a function gets invoked, the value of esp gets copied onto ebp, then the stack frame for that particular function gets allocated by decreasing the value of esp (via ENTER instruction or push ebp; mov ebp,esp; sub esp, SIZE; instruction sequence). From this point on, the value of esp strictly grows upwards and thus does not interfere with the stack frame of the current function.

When the function reaches its end, it frees the stack frame by going through the steps described above, but backwards, i.e. via LEAVE instruction, or mov esp, ebp; pop ebp; instruction sequence. At this point, the value of esp points to the return address, and this is the address that the attacker wants to modify. Once this value is modified, upon the execution of RET instruction, the modified return address gets popped, and the eip now points to the modified address.

2.Since anything above your shellcode has been "freed", you simply need to allocate the stack frame for your shell code by going through the same steps described above.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top