繁体   English   中英

在这个 C 程序中找不到漏洞

[英]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");
        }
    }
}

emailchar email[USR_LEN]; USR_LEN为 16,但使用fscanf(stdin, "%31s", email); .

此外,未测试fscanf的结果。 用户可以使用Control-D (在 Unix 上)导致没有输入,使缓冲区未初始化,然后strcmp可以溢出缓冲区。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM