in

Can’t find the vulnerability in this C program


Studying for an exam and found the following problem that I can’t crack. The first question is to find the bug in the code, the second is to give an example of how an attacker can exploit the bug. So it is exploitable, and has to have something to do with one of the ‘fscanf’ statements then I assume but I don’t know what the vulnerability is since they all read 1 less byte than the buffer size is to give room for the null terminator.

#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 databasen");
        return 1;
    }
    // Loop until explicitly terminated with return statement
    while(1) {
        printf("Choose action:n");
        printf(" 1: Proceed to type passwordn");
        printf(" 2: Cancel loginn");
        printf(" 3: Request password reset emailn");
        // 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 emailn");
                return 1;
            } else {
                printf("A password reset link has been sent!n");
            }
        } else {
            printf("Invalid choice, please try again.n");
        }
    }
}



Source: https://stackoverflow.com/questions/70719698/cant-find-the-vulnerability-in-this-c-program

Just learning to build mobile apps with flutter

a standalone, self-hosted, newsletter and mailing list manager