简单的缓冲区溢出

时间:2017-05-16 23:54:56

标签: c unix buffer buffer-overflow exploit

我有一个练习要求我制作一个seg.fault。 根据我的理解,我可以通过溢出缓冲区来做到这一点。 所以我需要做的就是提供一个大于特定大小的输入(Name)(覆盖返回地址)。 因此,如果buf,i和c保持52字节和ebp 4,则返回地址应该在56字节之后。因此,如果我给出大于56的输入,它应该产生一个seg.fault。我的想法是否正确?我试过这些数字,但它仍然运行并正确退出。(UNIX-32bit)

#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>

#define BUFSIZE 44

char grade = '3';
char Name[BUFSIZE];

void readString(char *s) {
   char buf[BUFSIZE];
   int i = 0;
   int c;

   while (1) {
      c = fgetc(stdin);
      if ((c == EOF) || (c == '\n'))
         break;
      buf[i++] = c;
   }
   buf[i] = 0;

   for (i = 0; i < BUFSIZE; i++)
      s[i] = buf[i];

   return;
}

int main(void) {
   mprotect((void*)((unsigned int)Name & 0xfffff000), 1,
            PROT_READ | PROT_WRITE | PROT_EXEC);

   printf("What is your name?\n");
   readString(Name);

   exit(0)
}

2 个答案:

答案 0 :(得分:1)

这段代码可以保护您免受段错误的侵害。

for (i = 0; i < BUFSIZE; i++)
      s[i] = buf[i];

你可能会跑掉buf数组的末尾但是在堆栈上。

为什么不呢?

*(int*)(0x00000000) = 0;

答案 1 :(得分:0)

在我看来,堆栈是单词对齐的,如果你的buf [BUFSIZE],它将与本地i和c变量有一个洞。这样的反汇编代码:

  4005d4:   55                      push   %rbp
  4005d5:   48 89 e5                mov    %rsp,%rbp
  4005d8:   48 83 ec 50             sub    $0x50,%rsp
  4005dc:   48 89 7d b8             mov    %rdi,-0x48(%rbp)
  4005e0:   c7 45 f8 00 00 00 00    movl   $0x0,-0x8(%rbp)

它的堆栈创建了90个字节,所以你想改变rbp必须输入很多。   所以如果你想改变像rbp这样的其他值,你必须输入超过64。 不幸的是,它可能没有用,因为当你经过i位置时,你的输入值会改变i值,所以buff [i ++]可能不是你想要的位置。所以改变rpb的最好方法是只是跳过在第一个中加入的堆栈。