有没有可能破解这个c程序中的密码?
Is it possible to crack the password in this c program?
是否可以在不输入字符串 Password
的情况下打印 Password cracked
。是否有任何内存泄漏或意外行为可以设置标志,即使输入的输入不是 Password
.
#include<stdio.h>
#include<string.h>
int main()
{
int flag = 0;
char passwd[10];
char password[10];
memset(passwd,0,sizeof(passwd));
fgets(password, sizeof password, stdin);
strcpy(passwd, password);
if(0 == strcmp("Password", passwd)) {
flag = 1;
}
if(flag) {
printf("\n Password cracked \n");
}
else {
printf("\n Incorrect passwd \n");
}
return 0;
}
问:如果输入包含1到9个字符,puts()函数可以正常工作。如果输入 10 个字符,则不会打印任何内容。
A: 那是因为你覆盖了你的数组。缓冲区溢出。 Undefined behavior.
从不 使用“gets()”。 始终 使用 fgets() 代替。正是出于这个原因:
http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1049157810&id=1043284351
整个事情将取决于缓冲区溢出,从而取决于未定义的行为。
OP 已更新 post 将 gets()
替换为 fgets()
。现在代码使用 fgets()
不正确,因此它会表现出未定义的行为。
即使 fgets(password)
替换为 fgets(password, sizeof password, stdin)
仍然存在无法检查 fgets()
/
结果的问题
如果用户输入"Password"
,输出肯定是"\n Incorrect passwd \n"
,因为passwd
肯定保留了'\n'
。
OP 第二次进行了重要编辑 - 最好开始一个新问题。 @J.Selva,不要再改题了
在此版本中,下面的代码不检查 fgets()
的 return 值(这是一个漏洞利用漏洞),但使用 password
。这就产生了一个可以用来破解的问题。假设之前的 运行 代码出现了正确的密码。现在有了这个 运行,恶意用户会导致一个 IO 错误 fgets()
returns NULL
。 passwd
的内容是不确定的, 可能 是前一个 fgets()
调用的值。 memset()
在这里没有帮助,因为它清除了 passwd
而不是 fgets()
用来分配 password
.
的内部缓冲区
memset(passwd,0,sizeof(passwd));
fgets(password, sizeof password, stdin);
strcpy(passwd, password);
正确的代码将使用
// memset not needed
// memset(passwd,0,sizeof(passwd));
if (fgets(password, sizeof password, stdin) == NULL) {
Handle_EOForInputError();
return -1;
}
strcpy(passwd, password);
是否可以在不输入字符串 Password
的情况下打印 Password cracked
。是否有任何内存泄漏或意外行为可以设置标志,即使输入的输入不是 Password
.
#include<stdio.h>
#include<string.h>
int main()
{
int flag = 0;
char passwd[10];
char password[10];
memset(passwd,0,sizeof(passwd));
fgets(password, sizeof password, stdin);
strcpy(passwd, password);
if(0 == strcmp("Password", passwd)) {
flag = 1;
}
if(flag) {
printf("\n Password cracked \n");
}
else {
printf("\n Incorrect passwd \n");
}
return 0;
}
问:如果输入包含1到9个字符,puts()函数可以正常工作。如果输入 10 个字符,则不会打印任何内容。
A: 那是因为你覆盖了你的数组。缓冲区溢出。 Undefined behavior.
从不 使用“gets()”。 始终 使用 fgets() 代替。正是出于这个原因:
http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1049157810&id=1043284351
整个事情将取决于缓冲区溢出,从而取决于未定义的行为。
OP 已更新 post 将 gets()
替换为 fgets()
。现在代码使用 fgets()
不正确,因此它会表现出未定义的行为。
即使 fgets(password)
替换为 fgets(password, sizeof password, stdin)
仍然存在无法检查 fgets()
/
如果用户输入"Password"
,输出肯定是"\n Incorrect passwd \n"
,因为passwd
肯定保留了'\n'
。
OP 第二次进行了重要编辑 - 最好开始一个新问题。 @J.Selva,不要再改题了
在此版本中,下面的代码不检查 fgets()
的 return 值(这是一个漏洞利用漏洞),但使用 password
。这就产生了一个可以用来破解的问题。假设之前的 运行 代码出现了正确的密码。现在有了这个 运行,恶意用户会导致一个 IO 错误 fgets()
returns NULL
。 passwd
的内容是不确定的, 可能 是前一个 fgets()
调用的值。 memset()
在这里没有帮助,因为它清除了 passwd
而不是 fgets()
用来分配 password
.
memset(passwd,0,sizeof(passwd));
fgets(password, sizeof password, stdin);
strcpy(passwd, password);
正确的代码将使用
// memset not needed
// memset(passwd,0,sizeof(passwd));
if (fgets(password, sizeof password, stdin) == NULL) {
Handle_EOForInputError();
return -1;
}
strcpy(passwd, password);