#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <stdint.h>
#include <unistd.h>
#include <time.h>
#include <random>
using namespace std;
void login1(char * input1, char * input2) {
struct {
char username[20];
int canary;
char password[20];
char good_username[20];
char good_password[20];
int goodcanary;
} v;
v.canary = rand()000 10000;
v.goodcanary = v.canary;
if(strlen(input1) > 20) {
printf("Username too long, existing.\n");
exit(-1);
}
//read correct username and password
FILE * fp = fopen("password.txt", "r");
fgets(v.good_username, 20, fp);
fgets(v.good_password, 20, fp);
fclose(fp);
//remove trailing newline
v.good_username[strlen(v.good_username)-1] = '\0';
v.good_password[strlen(v.good_password)-1] = '\0';
strcpy(v.username, input1);
strcpy(v.password, input2);
//terminate strings properly for strcmp
v.username[19] = '\0';
v.password[19] = '\0';
v.good_username[19] = '\0';
v.good_password[19] = '\0';
//check canary and login success
if (v.canary != v.goodcanary) {
printf("Stack overflow detected, exiting.\n");
exit(-1);
}
if (strcmp(v.username, v.good_username) == 0 && strcmp(v.password, v.good_password) == 0) printf("Login successful!\n");
else printf("Login denied.\n");}
I've tried various lengths of usernames and passwords with no luck. I assumed I had to overflow but it always gets detected. What input of username and password would get me "Login successful" even if it wasn't the correct username and password?
CodePudding user response:
In
struct {
char username[20];
int canary;
char password[20];// a 60 char password can overwrite the next two members
char good_username[20];
char good_password[20];
int goodcanary; // without touching this canary
}
The second canary is after the input password as well as the good user name and password. The length of the input password is not validated. This allows an attacker to provide an input2
of sufficient length to overwrite both the user name and password with strcpy(v.password, input2);
without damaging the canary.
input2
must contain any password you want, then starting at character 20 the username provided as input1
, and then starting at character 40 a repeat of the password you set.
It doesn't matter what you supply as input1
so long as it exactly matches what you put in the middle of input2
, including padding, and doesn't overflow and damage the canary.