首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >复制堆栈缓冲区溢出漏洞时出错

复制堆栈缓冲区溢出漏洞时出错
EN

Stack Overflow用户
提问于 2015-05-21 07:16:03
回答 1查看 211关注 0票数 2

我在复制OWASP 这里提供的堆栈缓冲区溢出示例时遇到了问题。

以下是我的尝试:

代码语言:javascript
复制
$ cat test.c
  #include <stdio.h>
  #include <string.h>

  void doit(void)
  {
          char buf[8];

          gets(buf);
          printf("%s\n", buf);
  }

  int main(void)
  {
          printf("So... The End...\n");
          doit();
          printf("or... maybe not?\n");

          return 0;
  }



$ gcc test.c -o test -fno-stack-protection -ggdb

$ objdump -d test # omitted irrelevant parts i think
000000000040054c <doit>:
  40054c:       55                      push   %rbp
  40054d:       48 89 e5                mov    %rsp,%rbp
  400550:       48 83 ec 10             sub    $0x10,%rsp
  400554:       48 8d 45 f0             lea    -0x10(%rbp),%rax
  400558:       48 89 c7                mov    %rax,%rdi
  40055b:       e8 d0 fe ff ff          callq  400430 <gets@plt>
  400560:       48 8d 45 f0             lea    -0x10(%rbp),%rax
  400564:       48 89 c7                mov    %rax,%rdi
  400567:       e8 a4 fe ff ff          callq  400410 <puts@plt>
  40056c:       c9                      leaveq
  40056d:       c3                      retq

000000000040056e <main>:
  40056e:       55                      push   %rbp
  40056f:       48 89 e5                mov    %rsp,%rbp
  400572:       bf 4c 06 40 00          mov    $0x40064c,%edi
  400577:       e8 94 fe ff ff          callq  400410 <puts@plt>
  40057c:       e8 cb ff ff ff          callq  40054c <doit>
  400581:       bf 5d 06 40 00          mov    $0x40065d,%edi
  400586:       e8 85 fe ff ff          callq  400410 <puts@plt>
  40058b:       b8 00 00 00 00          mov    $0x0,%eax
  400590:       5d                      pop    %rbp
  400591:       c3                      retq # this is where i took my overflow value from
  400592:       90                      nop
  400593:       90                      nop
  400594:       90                      nop
  400595:       90                      nop
  400596:       90                      nop
  400597:       90                      nop
  400598:       90                      nop
  400599:       90                      nop
  40059a:       90                      nop
  40059b:       90                      nop
  40059c:       90                      nop
  40059d:       90                      nop
  40059e:       90                      nop
  40059f:       90                      nop

$ perl -e 'print "A"x12 ."\x91\x05\x40"' | ./test
So... The End...
AAAAAAAAAAAA▒@
or... maybe not? # this shouldn't be outputted

为什么这不管用?我假设我要插入的内存地址是retq from <main>

我的目标是找出如何在程序的其他地方调用函数的堆栈缓冲区溢出。任何帮助都是非常感谢的。:)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-21 08:02:48

我正在使用Windows和MSVC,但是你应该知道这个想法。

考虑以下代码:

代码语言:javascript
复制
#include <stdio.h>

void someFunc()
{
    puts("wow, we should never get here :|");
}

// MSVC inlines this otherwise
void __declspec(noinline) doit(void)
{
    char buf[8];

    gets(buf);
    printf("%s\n", buf);
}

int main(void)
{
    printf("So... The End...\n");
    doit();
    printf("or... maybe not?\n");

    return 0;
}

(注意:我必须用/OPT:NOREF编译它,以强制MSVC不要删除“未使用的”代码,并强制/GS-关闭堆栈检查)

现在,让我们在我最喜欢的反汇编程序中打开它:

我们希望利用gets漏洞,因此执行会跳转到someFunc。我们可以看到它的地址是001D1000,所以如果我们能够通过缓冲区写入足够多的字节来覆盖返回地址,那么我们就很好了。让我们看看调用gets时的堆栈:

正如我们所看到的,我们的堆栈分配缓冲区(buf)有8个字节,一些东西有4个字节(实际上是PUSH编辑的EBP)和返回地址。因此,我们需要编写12字节的任何内容,然后编写4字节的返回地址(001D1000),以“劫持”执行流。让我们这样做--我们将使用十六进制编辑器准备一个包含我们需要的字节的输入文件:

实际上,当我们使用这个输入运行程序时,我们会得到以下结果:

在打印该行之后,由于堆栈上有一些垃圾,它将崩溃,从而导致访问冲突。但是,没有什么可以阻止您仔细分析代码,并在输入中准备这样的字节,使程序看起来正常工作(我们可以用ExitProcess地址覆盖下一个字节,以便someFunc跳到那里)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30366966

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档