I'm currently practicing buffer overflows, but there is one thing I don't understand yet. I have read this similar question. I understand that if you don't know the address of ESP you must look for an address that executes JMP ESP to jump to the injected shellcode.
But do you really don't know the address of ESP? You do know the address of EIP, because you detected the point where EIP is overwritten or do you only know the offset of the EIP from your injected buffer? If so, then even no address is known to an attacker (ESP included ofcourse) and the attacker has to work with offsets only?
The picture below I've made shows the position right when the program has popped the return address.
Can't you just do any of these actions:
- Inject JMP ESP directly into the address of EIP, why do you need to find an address that performs this call?
- Add +4 to the return address as the shellcode comes right after the return address
I've read that the return address must point to another address that does JMP ESP is necessary, because of ASLR and a possible different depth of the call stack. I don't understand what is meant with the latter, does somebody have an example? Isn't the shellcode always right after the overwritten EIP?
And if ASLR is not enabled, do you then still have to find an address with JMP ESP?
My main question is: Why does the state of the stack at a moment in time influence the stack pointer? I've read that this makes it hard for the attacker to predict the stack addresses. But if you have a program that you start up again and again, then the same amount of variables and procedures are executed, so the stack size always will be the same.
After some talking with a colleague, he thinks they mean with that the situation of a Apache Webserver that handles requests and responses and performs a lot of actions. When you fire your buffer overflow exploit you don't know where in the execution the stack is. This opposed to having a program on your own pc that you can start over in the same manner again and again. Is this assumption correctly?
With all protections disabled; can you know the location of the stack in memory? Is the bottom of the stack a fixed address?
All the examples of exercises made me confusing, because that is not the real-world scenario. In the debugger you CAN see the stack addresses being modified, but you can't when remotely exploiting a buffer overflow. That's the reason why I thought you know the EIP and ESP address while exploiting, but that is only when you are using a debugger.