I am working through the OverTheWire Narnia wargame and I don't completely understand one of my buffer overflow solutions.
The following code is what is confusing me.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char * argv[]){
char buf[128];
if(argc == 1){
printf("Usage: %s argument\n", argv[0]);
exit(1);
}
strcpy(buf,argv[1]);
printf("%s", buf);
return 0;
}
My solution uses the lack on length checking on the strcpy
function to overflow main
's return address. There are 8 bytes of unused memory between the end of the 128 bytes reserved for buf
and the start of the stack frame control data (the saved ebp
and return address). Hence, my payload needs to be 8 bytes longer than I originally thought to overflow the control data (144 bytes instead of 136). Stack canaries are not being used. What are the possible reasons for the 8 bytes of unused memory?
uname -a: Linux melinda 4.9.15-x86_64-linode81 #1 SMP Fri Mar 17 09:47:36 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux
gcc --version: gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
Here is the output of disassemble main
in gdb
:
0x0804845d <+0>: push %ebp
0x0804845e <+1>: mov %esp,%ebp
0x08048460 <+3>: and $0xfffffff0,%esp
0x08048463 <+6>: sub $0x90,%esp
0x08048469 <+12>: cmpl $0x1,0x8(%ebp)
0x0804846d <+16>: jne 0x8048490 <main+51>
0x0804846f <+18>: mov 0xc(%ebp),%eax
0x08048472 <+21>: mov (%eax),%eax
0x08048474 <+23>: mov %eax,0x4(%esp)
0x08048478 <+27>: movl $0x8048560,(%esp)
0x0804847f <+34>: call 0x8048310 <printf@plt>
0x08048484 <+39>: movl $0x1,(%esp)
0x0804848b <+46>: call 0x8048340 <exit@plt>
0x08048490 <+51>: mov 0xc(%ebp),%eax
0x08048493 <+54>: add $0x4,%eax
0x08048496 <+57>: mov (%eax),%eax
0x08048498 <+59>: mov %eax,0x4(%esp)
0x0804849c <+63>: lea 0x10(%esp),%eax
0x080484a0 <+67>: mov %eax,(%esp)
0x080484a3 <+70>: call 0x8048320 <strcpy@plt>
0x080484a8 <+75>: lea 0x10(%esp),%eax
0x080484ac <+79>: mov %eax,0x4(%esp)
0x080484b0 <+83>: movl $0x8048574,(%esp)
0x080484b7 <+90>: call 0x8048310 <printf@plt>
0x080484bc <+95>: mov $0x0,%eax
0x080484c1 <+100>: leave
0x080484c2 <+101>: ret
So I guess it's the and $0xfffffff0,%esp
command that's causing the extra space, but why is that instruction necessary?