Usually we all see the basic buffer overflow format which has :-
NOPs + shellcode + return_address
Why dont we use,
NOPs + return_address + shellcode?
where we make the return address point to the start of the shellcode?
Im guessing that this is because we might be trying to write data outside the stack segment if the vulnerability is in the main(). Am I right? If I am, is that the only reason?
Oh, and yes I am not referring to other kinds of attacks which use return-to-libc, ptrace etc. ; I just wish to know why the most basic buffer overflow attack is demonstrated in the first way and not the second everywhere.
The return address can come before the shellcode+nop sled
or after. For instance if you are writing to a variable close the top of the stack you might have to write your nop sled+shell code
past the Return address (EIP) because there might not be enough room.
However, the NOP sled will always be next to the shell code. The reason why is because you use a nop sled to make the target of your shell code as much large as possible. If your EIP is pointing +=100 bytes from your shell code then you need to use a nop sled of more than 100 bytes to guarantee you'll hit your target. Thus NOPs + return_address + shellcode
is invalid. A common exploit string will look like this:
JUNK + return_address + NOPs + shellcode
And of course a "return-to-libc"
style attack doesn't require shellcode or a nop sled.
This simplistic stack-based buffer overflow exploit will not work on a modern system. Alpeh-One's Smashing The Stack For Fun and Profit no longer works because of NX zones, stack canaries, and ASLR, all of which are default on Windows and Linux.
You should pick up a copy of: