Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用堆栈缓冲区溢出(C)检索信息_C_Stack Overflow_Stack Smash - Fatal编程技术网

使用堆栈缓冲区溢出(C)检索信息

使用堆栈缓冲区溢出(C)检索信息,c,stack-overflow,stack-smash,C,Stack Overflow,Stack Smash,我在网上发现了一个有趣的练习,它指出特定的输入可以溢出缓冲区,这样“秘密”就会被打印到标准输出 我试着自己去想,但我做得不好 代码如下: #include <stdio.h> #include <stdlib.h> #include <string.h> void get_name(char *name, char *pr) { char local[20]; printf("%s:",pr); gets(local);// BUG

我在网上发现了一个有趣的练习,它指出特定的输入可以溢出缓冲区,这样“秘密”就会被打印到标准输出

我试着自己去想,但我做得不好

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void get_name(char *name, char *pr) {
    char local[20];
    printf("%s:",pr);
    gets(local);// BUG
    strncat(name,local,20);
}
int foo () {
    char name[28]="Hello..";
    char secret[12]="TOP SECRET";
    char buf[24];
    char n1[]="Enter your name";
    char n2[]="Enter Secret code"; 
    get_name(name,n1);
    memset(buf, 0, sizeof(buf));
    // Lets ONLY use strncpy for better control!!! 
    strncpy(buf, name, sizeof(buf));//BUG 
    printf("%s\n", buf); 
    memset(name,0,sizeof(name));
    get_name(name, n2);
    if (strncmp(secret,name,10)==0)
        printf("Welcome and %s\n",buf);
    else {printf("Wrong code, better try again..\n");}
    return 0;
}


int main(int argc, char **argv)
{
    foo();
    printf("Bye\n");
    return 0;
}
#包括
#包括
#包括
void get_name(char*name,char*pr){
char-local[20];
printf(“%s:”,pr);
获取(本地);//错误
strncat(名称,本地,20);
}
int foo(){
字符名称[28]=“你好..”;
char secret[12]=“绝密”;
char-buf[24];
char n1[]=“输入您的姓名”;
char n2[]=“输入密码”;
获取_名称(名称,n1);
memset(buf,0,sizeof(buf));
//让我们只使用strncpy进行更好的控制!!!
strncpy(buf,name,sizeof(buf));//错误
printf(“%s\n”,buf);
memset(name,0,sizeof(name));
获取_名称(名称,n2);
if(strncmp(secret,name,10)==0)
printf(“欢迎和%s\n”,buf);
否则{printf(“错误的代码,最好再试一次..\n”);}
返回0;
}
int main(int argc,字符**argv)
{
foo();
printf(“再见”);
返回0;
}

无法知道此类缓冲区溢出的结果会如何。您无法知道或假设它们将覆盖什么内存。它们很可能只会导致某种运行时崩溃。任何攻击都必须有一个非常具体的系统。这意味着没有人能够在不知道给定系统的细节的情况下回答你的问题

你的“随机上网者”的目标可能是用一些垃圾覆盖
Hello..
的空终止符,这样
的“绝密”
字符串就会随之打印出来。但是,您不能假设这两个字符串是相邻分配的。您可以尝试在
get
中键入28个字母长的输入,然后查看发生了什么。。。没有任何给定行为的保证。在我的电脑上,除了打印一些垃圾,它什么都不做。对我的二进制文件进行反向工程表明,这是因为数组确实不是相邻分配的


另外,你关于strncpy的评论是错误的,
strncpy
是危险的,应该避免,

这些评论不是我的,它们是与exercise@ro.Loon写练习的人似乎对C缺乏深入的了解。你似乎回答了与所问问题不同的问题。例如,在此代码中使用
strncpy
似乎是100%有意的,没有一点误导(出于代码和练习的目的)。@hyde关于strncpy的评论只是旁注。但是这个功能的使用总是被误导的,参见链接。这里正确的用法应该是使用memcpy,因为这段代码中似乎没有任何内容与20世纪70年代早期的固定宽度Unix字符串格式相关。我认为缺少编译行,通常他们会写这样的注释:
//gcc-o-m32 buffer\u overflow buffer\u overflow.c-fno stack protector
。您需要它(尤其是
-m32
-fno-stack-protector
)来实现这一挑战。