#include<stdio.h>#include<stdlib.h>#include<string.h>typedefenum {false,true} bool;staticconstchar secretPass[]="SuperSecureAndSuperSecretPassword!";intflag(){ system("/bin/cat flag.txt");fflush(NULL);}boolpassword_match(char*pass){// return true if password matchif (strncmp(pass, secretPass, strlen(secretPass))==0) {returntrue; }returnfalse;}voidauthentigate(){printf("WELCOME TO THE A U T H E N T I G A T E\n");printf("\n");bool auth_enabled =false;char pass[256];printf("Enter the correct password to be allowed through the gate: \n");fflush(NULL);scanf("%s",&pass[0]);if (!auth_enabled) {printf("Sorry, the AuthentiGate is closed, authentication is not currently enabled!\n");fflush(NULL);return; }if (password_match(&pass[0])) {printf("Congratulations! You have opened the AuthentiGate and here is your reward!\n");flag(); }else {printf("ERROR, INCORRECT PASSWORD!\n");fflush(NULL); }}intmain(){setbuf(stdin,NULL);setbuf(stdout,NULL);authentigate();return0;}
Big brain solution
The goal here is to furfill two if statments, the first one checks a bool value which is hardcoded to false, if it returns true we pass it, otherwise the program exits.
if (!auth_enabled) {printf("Sorry, the AuthentiGate is closed, authentication is not currently enabled!\n");fflush(NULL);return; }
The second if checks the password, and it needs to match "SuperSecureAndSuperSecretPassword!".
if (password_match(&pass[0])) {printf("Congratulations! You have opened the AuthentiGate and here is your reward!\n");flag(); }else {printf("ERROR, INCORRECT PASSWORD!\n");fflush(NULL); }}
The buffer where our password is stored is initialized right above the bool value and the input size is unrestricted, which means we can overflow the buffer and overwrite the bool value with true.
bool auth_enabled =false;char pass[256];
We can patch the source to print the pointers of both variables to calculate the offset. by simply adding the following lines after both variables are initialized:
After compiling and running the bin we can calculate the offset.
Great, the offset is 268 bytes, that means we can use a 268 sized junk to push a true value into auth_enabled. If we send the following input:
python -c 'print("A"*268+"\x01")'|./chall
We'll bypass the first if statment.
This means we hit the second if. Now we just got to input the correct password prepended to our padding to match the correct password. Don't forget to correct the padding size by subtracting the length of the password witch is 34 bytes.
What could make the challenge better would be adding a string compare instead of bool which would prevent one from solving without calculating the offset.