我已经安装了名为DVL的linux发行版(该死的易受攻击的linux),我正在使用缓冲区溢出攻击。 我写了两个几乎完全相同的程序,这些程序容易受到bof:
//bof_n.c
#include <stdio.h>
void bof() {
printf("BOF");
}
void foo(char* argv) {
char buf[10];
strcpy(buf, argv);
prinf("foo");
}
int main(int argc, char* argv[]) {
if (argc >= 1) {
foo(argv[1]);
}
return 0;
}
和
//bof.c
#include <stdio.h>
void bof() {
printf("BOF!\n");//this is the only change
}
void foo(char* argv) {
char buf[10];
strcpy(buf, argv);
prinf("foo");
}
int main(int argc, char* argv[]) {
if (argc >= 1) {
foo(argv[1]);
}
return 0;
}
之后我编译了它们,并在两种情况下都获得了bof()函数地址(例如,objdump -d bof.o | grep bof)。我们将这样一个地址ADDR命名为4字节。
我还发现,如果我在buf变量中写入32个字节,则EIP寄存器被完全覆盖(我无法复制gdb的输出,因为它在虚拟机上)。
现在,如果我这样做:
./bof `perl -e 'print "\x90"x28 . "ADDR"'`
我明白了:
fooBOF!
Segmentation fault
相反,如果我尝试使用相同的方法但使用bof_n,我只会收到“Segmentation fault”消息。 因此,我试图增加ADDR值重复的次数,我发现如果它重复至少350次,我得到想要的结果。但是我没有准确地输出上面的内容,而是依次得到一长串的“BOF”消息。我试图只获得一个“BOF”消息,但显然我不能这样做(我得到或零,或者很长的列表)。 为什么会这样?有什么想法吗?
我正在使用DVL和gcc 3.4.6
答案 0 :(得分:1)
你的目标是什么?
您应该使用调试器,尝试GDB Debugger或gdb
。有了它,您可以看到系统中当前正在进行的内存/寄存器/堆栈和反汇编。
我猜在第一个函数中,字符串长度只有3个字符,优化为\x42\x4f\x46\x00
,因此反汇编可能略有不同。
C源几乎无关紧要,你需要反汇编或fuzz两个二进制文件才能找到NOP
个雪橇的合适大小。
答案 1 :(得分:0)
我找到了解决方案。问题是关于消息的打印而不是缓冲区溢出漏洞本身。 事实上,在bof_n示例中也正确地覆盖了寄存器eip,并且在bof()函数中正确地重定向了程序流。问题是,显然,在分段错误之前stdout没有刷新,因此没有显示任何消息。
相反,使用fprintf(stderr, "BOF");
,我终于得到了“BOF”消息。