c中的缓冲区溢出以及在堆栈

时间:2017-03-31 21:33:00

标签: c buffer

首先,我正在使用这个编译标志: gcc -fno-stack-protector -z execstack -m 32

好的,请看下面的代码

int main(int argc, char *argv[]){
    char pass[8];
    char logged = 'n';
    strcpy( pass, argv[1] );
    if( logged == 'y' ){
        printf("Hello \n");
    } else {
        printf("Run hacker :(\n");
    }
    return 0;
}

和第二个代码

int main(int argc, char *argv[]){
    char logged = 'n';
    char pass[8];
    strcpy( pass, argv[1] );
    if( logged == 'y' ){
        printf("Hello \n");
    } else {
        printf("Run hacker :(\n");
    }
    return 0;
}

这些代码容易受到堆栈溢出攻击。 (通过'yyyyyyyyy'作为arg将通过测试)

但为什么?第二个代码中的局部变量的顺序与第一个代码中的不同。所以在堆栈上推送局部变量的队列也应该是另一个,但它不是吗?

1 个答案:

答案 0 :(得分:0)

首先,堆栈溢出漏洞与堆栈损坏不完全相同。

此代码正在编写一个在堆栈上(在您的框架中)分配的自动变量。编译器在堆栈上为传递字符串保留了8个字节。如果写入超过8个字节,则会破坏pass []数组旁边的堆栈上的其他内容。真的不重要;它将被破坏,这就是堆栈损坏的含义。

通过一些技巧,可以生成一个输入(argv [1])字符串(实际上是指令字节流),它将与main的返回指令对齐,从而可以强制执行代码。这就是漏洞。

您似乎明白堆栈中变量的顺序只决定了什么以及如何被破坏,如果您使用-fno-stack-protector关闭堆栈保护,您应该看到您的预期,加上减去编译器强加的确切堆栈布局。在保护的情况下,两种情况都应该倾倒堆栈粉碎回溯和诊断。

请注意,不同的linux distrubution将no-stack-protector默认设置为不同的值,但只要您在命令行上显式控制它就可以设置。 -z execstack选项是一种处理是否允许在堆栈上执行的机制;在这里它是无关紧要的,因为你的代码只是破坏了堆栈。