我在网上发现了一个有趣的练习,它指出特定的输入可以溢出缓冲区,这样'secret'将被打印到stdout。
我试着自己解决这个问题,但我做得不好。
代码如下:
#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("%sn", buf);
memset(name,0,sizeof(name));
get_name(name, n2);
if (strncmp(secret,name,10)==0)
printf("Welcome and %sn",buf);
else {printf("Wrong code, better try again..n");}
return 0;
}
int main(int argc, char **argv)
{
foo();
printf("Byen");
return 0;
}
没有办法知道这种缓冲区溢出的结果将会做什么。您无法知道或假设它们将覆盖哪些内存。它们很可能只会导致某种类型的运行时崩溃。任何攻击都必须有一个非常具体的系统。这意味着如果不知道给定系统的细节,没有人能够回答你的问题。
你的"随机互联网人"的目标是,很可能用一些垃圾覆盖Hello..
的null终止,以便"TOP SECRET"
字符串将与它一起打印。但是,不能假设这两个字符串是相邻分配的。你可以试着在gets
中输入28个字母,看看会发生什么……没有任何特定行为的保证。在我的电脑上,除了打印一些垃圾之外,它没有什么令人兴奋的功能。逆向工程我的二进制显示,这是因为数组确实不是邻接分配的。
另外,你对strncpy
的评论是错误的,strncpy
是危险的,应该避免,看这个