这些天我正在研究缓冲区溢出技术,我试图自己做一个简单的例子,以便更好地理解如何利用这样的漏洞。
我写了这个简单的 c 程序:
//bof.c
#include <stdio.h>
#include <string.h>
void
BOF() {
printf("BOF");
}
void
foo1(char* argv){
char buff[10];
strcpy(buff, argv);
printf("foo1");
}
int
main(int argc, char* argv[])
{
if ( argc < 1 ) {
return 0;
}
foo1(argv[1]);
return 0;
}
我的目标是利用 BOF 漏洞,以便跳转到未调用的函数 BOF(),从而打印消息。为了做到这一点,我有:
- 编译程序:gcc -ggdb -m64 -o bof.o -fno-stack-protector -mpreferred-stack-boundary=4 bof.c
- 发现 BOF() 地址:objdump -d bof.o | grep BOF(这给了我 0000000000400544)
- 在 gdb 中执行程序以查看寄存器中发生的情况
在 gdb 里面我做: r perl -e 'print "\x44\x05\x40\x00\x00\x00\x00\x00" x1500'
,但什么也没发生。程序正常结束。所以我在 strcpy 函数之后立即放了一个断点,以便查看寄存器,我收到的是:
rax 0x7ffffffeca20 140737488276000
rbx 0x0 0
rcx 0x7ffff7ab1f00 140737348574976
rdx 0x400544 4195652
rsi 0x7fffffffb8cd 140737488337101
rdi 0x7ffffffeca20 140737488276000
rbp 0x7ffffffeca30 0x7ffffffeca30
rsp 0x7ffffffeca10 0x7ffffffeca10
r8 0x400660 4195936
r9 0x7ffff7de9740 140737351948096
r10 0x7ffffffec7a0 140737488275360
r11 0x7ffff7b8fec0 140737349484224
r12 0x400460 4195424
r13 0x7ffffffecb30 140737488276272
r14 0x0 0
r15 0x0 0
rip 0x40057b 0x40057b <foo1+31>
eflags 0x206 [ PF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
为什么寄存器没有被覆盖?我尝试将 1500 参数更改为更大的值,但没有任何改变。我也尝试了很小的值(比如 50 或更少),但我得到了相同的结果。
我还尝试在堆栈中写入与地址不同的内容,以查看寄存器是否被覆盖。例如,使用 perl -e 'print "A" x1500',我只能修改 rbp 寄存器,而不能修改 rip。但是我通过阅读本网站上的一个帖子发现,在 gdb 上可能会发生这种情况,并尝试使用有效地址。所以我做了。
我做错了什么?BOF 在当今的内核中是否更可行?
在我忘记之前:我还删除了 gdb 限制元素以删除元素限制,使用:set print elements 0
最后,就像您可能想出查看寄存器一样,我有一台带有 ubuntu 12.04(内核版本 3.5.0-39-generic)的 64 位机器。
提前致谢。