I'm new to buffer overflow exploitation. I've written a simple C program which will ask user to input a string (as a password) and match that string with "1235". If matched then it will print "Access Approved", otherwise it'll print "Access Denied". Now I'm trying to overflow the string buffer which will overwrite the caller function's return address with the address for the initiation of the printing of "Access Approved". Bellow is the source code and the disassembled code of the main function (I'm using gdb to see the memory layout):
#include <stdio.h>
#include <string.h>
void main()
{
char ch[10];
scanf("%s", ch);
if(strcmp("1235", ch))
printf("\nAccess Denied\n");
else
printf("\nAccess Approved\n");
}
0x0000000000001169 <+0>: push rbp
0x000000000000116a <+1>: mov rbp,rsp
0x000000000000116d <+4>: sub rsp,0x20
0x0000000000001171 <+8>: mov rax,QWORD PTR fs:0x28
0x000000000000117a <+17>: mov QWORD PTR [rbp-0x8],rax
0x000000000000117e <+21>: xor eax,eax
0x0000000000001180 <+23>: lea rax,[rbp-0x12]
0x0000000000001184 <+27>: mov rsi,rax
0x0000000000001187 <+30>: lea rdi,[rip+0xe76] # 0x2004
0x000000000000118e <+37>: mov eax,0x0
0x0000000000001193 <+42>: call 0x1060 <__isoc99_scanf@plt>
0x0000000000001198 <+47>: lea rax,[rbp-0x12]
0x000000000000119c <+51>: mov rsi,rax
0x000000000000119f <+54>: lea rdi,[rip+0xe61] # 0x2007
0x00000000000011a6 <+61>: call 0x1050 <strcmp@plt>
0x00000000000011ab <+66>: test eax,eax
0x00000000000011ad <+68>: je 0x11bd <main+84>
0x00000000000011af <+70>: lea rdi,[rip+0xe56] # 0x200c
0x00000000000011b6 <+77>: call 0x1030 <puts@plt>
0x00000000000011bb <+82>: jmp 0x11c9 <main+96>
0x00000000000011bd <+84>: lea rdi,[rip+0xe57] # 0x201b
0x00000000000011c4 <+91>: call 0x1030 <puts@plt>
0x00000000000011c9 <+96>: nop
0x00000000000011ca <+97>: mov rax,QWORD PTR [rbp-0x8]
0x00000000000011ce <+101>: sub rax,QWORD PTR fs:0x28
0x00000000000011d7 <+110>: je 0x11de <main+117>
0x00000000000011d9 <+112>: call 0x1040 <__stack_chk_fail@plt>
0x00000000000011de <+117>: leave
0x00000000000011df <+118>: ret
I've figured out the memory layout of the "ch" buffer (10 byte), "QWORD PTR fs:0x28" (8 bytes), privious base pointer (8 bytes) and the return address (8 bytes) (so total of 34 bytes) and below is the gdb output with the string argument "1235":
(gdb) x/34xb $rbp-0x12
0x7fffffffe42e: 0x31 0x32 0x33 0x35 0x00 0xff 0xff 0x7f
0x7fffffffe436: 0x00 0x00 0x00 0x5d 0x2d 0xd2 0x26 0x1e
0x7fffffffe43e: 0x4d 0x0e 0xe0 0x51 0x55 0x55 0x55 0x55
0x7fffffffe446: 0x00 0x00 0x52 0xa1 0xdf 0xf7 0xff 0x7f
0x7fffffffe44e: 0x00 0x00
(gdb)
Also I've figured out the return address for the printing of the message which is 0x5555555551bd (at runtime):
0x5555555551bd <main+84>: lea rdi,[rip+0xe57] # 0x55555555601b
0x5555555551c4 <main+91>: call 0x555555555030 <puts@plt>
Now the problem is if i pass a string consisting 26 'A's and the return the address, scanf interprets everything as a character even if I pass '\x' before the address's digits. And I can't figure out how I can tell scanf that the address part is not a string. Also what is the meaning of fs:0x28?