0

我已经安装了名为 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,我只会收到“分段错误”消息。因此我尝试增加重复 ADDR 值的次数,我发现如果重复至少 350 次,我会得到想要的结果。但是,我并没有准确地得到上面的输出,而是一个接一个地得到一长串“BOF”消息。我试图只获得一个“BOF”消息,但显然我做不到(我得到或为零,或一长串)。为什么会这样?任何想法?

我将 DVL 与 gcc 3.4.6 一起使用

4

2 回答 2

1

你的目标是什么?

你真的应该为此使用调试器,试试GDB 调试器gdb. 有了它,您可以看到系统中当前正在发生的事情的内存/寄存器/堆栈和反汇编。

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

C 源代码几乎无关紧要,您需要反汇编或模糊两个二进制文件以找到适合两个NOP雪橇的大小。

于 2013-08-29T04:49:48.847 回答
0

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

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

于 2013-08-29T10:35:49.977 回答