In order to improve my binary exploitation skills, and deepen my understanding in low level environments I tried solving challenges in pwnable.kr, The third challenge- called bof
has the following C code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
char overflowme[32];
printf("overflow me : ");
gets(overflowme); // smash me!
if(key == 0xcafebabe){
system("/bin/sh");
}
else{
printf("Nah..\n");
}
}
int main(int argc, char* argv[]){
func(0xdeadbeef);
return 0;
}
Disassembling the func:
0x5655562c <+0>: push ebp
0x5655562d <+1>: mov ebp,esp
**0x5655562f <+3>: sub esp,0x48**
0x56555632 <+6>: mov eax,gs:0x14
0x56555638 <+12>: mov DWORD PTR [ebp-0xc],eax
0x5655563b <+15>: xor eax,eax
0x5655563d <+17>: mov DWORD PTR [esp],0x5655578c
0x56555644 <+24>: call 0xf7e28b70 <puts>
0x56555649 <+29>: lea eax,[ebp-0x2c]
0x5655564c <+32>: mov DWORD PTR [esp],eax
0x5655564f <+35>: call 0xf7e280c0 <gets>
0x56555654 <+40>: cmp DWORD PTR [ebp+0x8],0xcafebabe
0x5655565b <+47>: jne 0x5655566b <func+63>
0x5655565d <+49>: mov DWORD PTR [esp],0x5655579b
0x56555664 <+56>: call 0xf7dfc8b0 <system>
0x56555669 <+61>: jmp 0x56555677 <func+75>
0x5655566b <+63>: mov DWORD PTR [esp],0x565557a3
0x56555672 <+70>: call 0xf7e28b70 <puts>
0x56555677 <+75>: mov eax,DWORD PTR [ebp-0xc]
0x5655567a <+78>: xor eax,DWORD PTR gs:0x14
0x56555681 <+85>: je 0x56555688 <func+92>
0x56555683 <+87>: call 0xf7ece820 <__stack_chk_fail>
0x56555688 <+92>: leave
0x56555689 <+93>: ret
I know how to solve it, but when I disassembled the binary I found out that esp
creates a stack frame(Highlighted the command where it happens) 0x48 bytes long. And I don't understand why - I thought it'd allocate 32 bytes since the only variable it allocates the stack for is overflowme
.
Can anybody explain why the stack allocates this many extra bytes?
I have another question,I printed 32 bytes of 'A' into the program and I inspected the stack at the gets
function line(after the execution). This is the result:
0xffffcd20: 0xffffcd3c 0xffffce24 0xf7fa0000 0xf7f9ea60
0xffffcd30: 0x00000000 0xf7fa0000 0xf7ffc840 0x41414141
0xffffcd40: 0x41414141 0x41414141 0x41414141 0x41414141
0xffffcd50: 0x41414141 0x41414141 0x41414141 0x93e65400
0xffffcd60: 0x56556ff4 0xf7fa0000 0xffffcd88 0x5655569f
0xffffcd70: 0xdeadbeef 0x00000000 0x565556b9 0x00000000
0xffffcd80: 0xf7fa0000 0xf7fa0000 0x00000000 0xf7dd5fb9
0xffffcd90: 0x00000001 0xffffce24 0xffffce2c 0xffffcdb4
0xffffcda0: 0x00000001 0x00000000 0xf7fa0000 0x00000000
0xffffcdb0: 0xf7ffd000 0x00000000 0xf7fa0000 0xf7fa0000
The question is: What are the bytes between the 0x5655569f
(which is the return address) value, and the end of the 'A's? Are there just random junk?
EDIT: Forgot to add, the binary is a 32 bit binary, dynamically linked, with debugging symbols.
User contributions licensed under CC BY-SA 3.0