[英]Can't find the vulnerability in this C program
学习考试,发现以下我无法破解的问题。 第一个问题是找到代码中的漏洞,第二个问题是举例说明攻击者如何利用漏洞。 所以它是可利用的,并且必须与我假设的“fscanf”语句之一有关,但我不知道漏洞是什么,因为它们都比缓冲区大小少读 1 个字节,以便为null 终结器。
#define USR_LEN 16
#define PWD_LEN 16
#define EMAIL_LEN 32
// Fetches password for given username and stores it into 'destination'
// Passwords are never longer than 15 characters.
// Returns 0 on success and 1 on error.
int get_pwd_from_user_db(const char* username, char* destination);
// Sends a password-reset link to given email, provided that the email is
// registered with the given username. Returns 0 on success and 1 on error.
int request_email(const char* username, const char* email);
// Performs credentials check. Returns 0 on successful login and 1 on
// failed login or error.
int login()
{
char username[USR_LEN];
char given_password[PWD_LEN];
char email[USR_LEN];
char stored_password[PWD_LEN];
int choice;
printf("User name: ");
// Read string from standard input. Given format specifier "%Ns" fscanf will
// read at most N characters into destination buffer ('username' here), or
// until whitespace (e.g. newline) is encountered. A null terminator is
// always appended after the last read character in the destination buffer.
fscanf(stdin, "%15s", username);
if(get_pwd_from_user_db(username, stored_password) != 0) {
printf("Error accessing user database\n");
return 1;
}
// Loop until explicitly terminated with return statement
while(1) {
printf("Choose action:\n");
printf(" 1: Proceed to type password\n");
printf(" 2: Cancel login\n");
printf(" 3: Request password reset email\n");
// Read one integer from standard input into 'choice'
fscanf(stdin, "%d", &choice);
if(choice == 1) {
printf("Password: ");
fscanf(stdin, "%15s", given_password);
// strcmp returns 0 if strings are equal
if(strcmp(given_password, stored_password) == 0) {
printf("Login successful!\n");
return 0;
} else {
printf("Incorrect password!\n");
return 1;
}
} else if(choice == 2) {
return 1;
} else if(choice == 3) {
printf("Email address: ");
fscanf(stdin, "%31s", email);
if(request_email(username, email) != 0) {
printf("Error sending email\n");
return 1;
} else {
printf("A password reset link has been sent!\n");
}
} else {
printf("Invalid choice, please try again.\n");
}
}
}
email
用char email[USR_LEN];
USR_LEN
为 16,但使用fscanf(stdin, "%31s", email);
.
此外,未测试fscanf
的结果。 用户可以使用Control-D (在 Unix 上)导致没有输入,使缓冲区未初始化,然后strcmp
可以溢出缓冲区。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.