0

可能重复:
C 中的堆栈溢出利用

我需要编写一个程序来利用以下程序的堆栈溢出漏洞。我从来没有做过这样的事情。我理解它在理论上是如何工作的堆栈和溢出。但是我对C中的实现一无所知。请帮助我。我只需要清楚地了解要采取哪些步骤来溢出堆栈并生成 shell 代码。

#include <stdio.h>
int myprint(char* argv1)
{
    printf("%s", argv1);
}
void foo(char* argv1, char* argv2) 
{
    int (*fptr)(char*) = myprint;
    char buf[12];
    strcpy(buf, argv1);
    fptr(argv2);
}
int main(int argc, char **argv) 
{
    if (argc < 3) 
    {
            printf("error\n");
            return;
    }

    foo(argv[1], argv[2]);
}

谢谢

4

1 回答 1

2

您能够利用此代码的关键在于以下两行:

char buf[12];
strcpy(buf, argv1);

您可以在此处看到您有一个称为buf大小12字节的缓冲区,它的空间有限。现在在下一行,您正在接受argv1并将其复制到buf其中,而没有检查 的大小argv1是否小于buf.

这意味着这个未经检查的版本strcpy允许您在结束后写入buf,然后可能覆盖此函数堆栈帧的返回地址。

在函数返回之前的堆栈帧末尾,您通常会在汇编器中找到与汇编器中类似的语句ret(在不同类型的汇编器中可能不同,我在这里假设 x86),它基本上跳回调用者,使用存储在堆栈中的地址(通常,取决于调用约定,存储在调用此函数之前)。

然后,您可以用指向您放置在将执行并打开 shell 的一些可用空间中的一些 shellcode 的东西覆盖该地址。

这是关于 X86 汇编器中的调用约定的部分,它解释了调用函数时会发生什么,以及序言和尾声是如何完成的。

于 2012-11-19T15:30:09.440 回答