i'm having problem to buffer overflow a simple c program that takes input from command line, this is the main.c code:
#include <stdio.h> #include <string.h> void func(char *name) { char buf[10]; strcpy(buf, name); } void chgflow(){ printf("changed flow!!\n"); } void main(int argc, char *argv[]) { func(argv[1]); printf("i should not be viewed if flow is changed\n"); chgflow(); }
this is the assembly version taken from objdump -d ./main :
<main>: 5a3: 8d 4c 24 04 lea 0x4(%esp),%ecx 5a7: 83 e4 f0 and $0xfffffff0,%esp 5aa: ff 71 fc pushl -0x4(%ecx) 5ad: 55 push %ebp 5ae: 89 e5 mov %esp,%ebp 5b0: 53 push %ebx 5b1: 51 push %ecx 5b2: e8 99 fe ff ff call 450 <__x86.get_pc_thunk.bx> 5b7: 81 c3 49 1a 00 00 add $0x1a49,%ebx 5bd: 89 c8 mov %ecx,%eax 5bf: 8b 40 04 mov 0x4(%eax),%eax 5c2: 83 c0 04 add $0x4,%eax 5c5: 8b 00 mov (%eax),%eax 5c7: 83 ec 0c sub $0xc,%esp 5ca: 50 push %eax 5cb: e8 7d ff ff ff call 54d <func> 5d0: 83 c4 10 add $0x10,%esp 5d3: 83 ec 0c sub $0xc,%esp 5d6: 8d 83 90 e6 ff ff lea -0x1970(%ebx),%eax 5dc: 50 push %eax 5dd: e8 fe fd ff ff call 3e0 <puts@plt> 5e2: 83 c4 10 add $0x10,%esp 5e5: e8 8e ff ff ff call 578 <chgflow> 5ea: 90 nop 5eb: 8d 65 f8 lea -0x8(%ebp),%esp 5ee: 59 pop %ecx 5ef: 5b pop %ebx 5f0: 5d pop %ebp 5f1: 8d 61 fc lea -0x4(%ecx),%esp 5f4: c3 ret <func>: 54d: 55 push %ebp 54e: 89 e5 mov %esp,%ebp 550: 53 push %ebx 551: 83 ec 14 sub $0x14,%esp 554: e8 9c 00 00 00 call 5f5 <__x86.get_pc_thunk.ax> 559: 05 a7 1a 00 00 add $0x1aa7,%eax 55e: 83 ec 08 sub $0x8,%esp 561: ff 75 08 pushl 0x8(%ebp) 564: 8d 55 ee lea -0x12(%ebp),%edx 567: 52 push %edx 568: 89 c3 mov %eax,%ebx 56a: e8 61 fe ff ff call 3d0 <strcpy@plt> 56f: 83 c4 10 add $0x10,%esp 572: 90 nop 573: 8b 5d fc mov -0x4(%ebp),%ebx 576: c9 leave 577: c3 ret <chgflow>: 578: 55 push %ebp 579: 89 e5 mov %esp,%ebp 57b: 53 push %ebx 57c: 83 ec 04 sub $0x4,%esp 57f: e8 71 00 00 00 call 5f5 <__x86.get_pc_thunk.ax> 584: 05 7c 1a 00 00 add $0x1a7c,%eax 589: 83 ec 0c sub $0xc,%esp 58c: 8d 90 80 e6 ff ff lea -0x1980(%eax),%edx 592: 52 push %edx 593: 89 c3 mov %eax,%ebx 595: e8 46 fe ff ff call 3e0 <puts@plt> 59a: 83 c4 10 add $0x10,%esp 59d: 90 nop 59e: 8b 5d fc mov -0x4(%ebp),%ebx 5a1: c9 leave 5a2: c3 ret
first of all i executed:
echo 0 > /proc/sys/kernel/randomize_va_space
then compiled main.c :
gcc -m32 -g main.c -o main -fno-stack-protector
when func
function terminates i want to overwrite the regular ret address, and pointing to chgflow
function, therefore bypassing the regular next instruction:
printf("i should not be viewed if flow is changed\n");
to debug the main.c and inspect which memory addresses are in place i executed:
gdb ./main go disas main disas chgflow
and this is what i found for disas main:
0x565555cb <+40>: call 0x5655554d <func> 0x565555d0 <+45>: add $0x10,%esp
and for chgflow:
Dump of assembler code for function chgflow: 0x56555578 <+0>: push %ebp
So i can understand that:
0x565555d0 <+45>: add $0x10,%esp
is the regular ret address (and next instruction) after func
terminates, and 0x56555578
is the first instruction of chgflow
function. Now i have to inspect assembly of func
to understand how many char A (let's say) i need for stuffing the stack; from this line:
564: 8d 55 ee lea -0x12(%ebp),%edx
i understand i need 18Byte + 4 Byte of A stuffing to get to Ret address. To confirm this i executed again:
gdb ./main break 7 run AAAAAAAAAAAAAAAAAAAAAA
("A" repeated 22 times)
(gdb) x/s $ebp-18 0xffffd2a6: 'A' <repeats 22 times> (gdb) x/s $ebp 0xffffd2b8: "AAAA" (gdb) x/x $ebp+4 0xffffd2bc: 0x00
my test finished here because i cannot understand why (gdb) x/x $ebp+4
that should be the Ret address, displays 0x00
as the result. I expected the ret address to not change from the regular one 0x565555d0
. But, hey! 0x00
should be the terminator isn't it? So i went on and performed another test with 21 "A" stuffing and the result is correct this time:
(gdb) x/x $ebp+4 0xffffd2bc: 0x565555d0
My last need is now to overwrite the return address with 0x56555578, that is the address of the first instruction of chgflow
function. I performed the previous test with this replaced:
run AAAAAAAAAAAAAAAAAAAAA\x78\x55\x55\x56
("A" repeats 21 times) but gdb gave to me:
Breakpoint 1, func (name=0x35357835 ) at main.c:7
and this is what i can see from memory:
(gdb) x/x $ebp+4 0xffffd2ac: 0x37 (gdb) x/s $ebp+4 0xffffd2ac: "78x55x55x56"
finally i was not able to jump to chgflow
Anyone can help me with this? i'd really appreciate. regards Marco