Created
June 27, 2016 20:08
-
-
Save mclosson/a3e59f747e6d57d1078ac4a8836d09b3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Welcome freedom fighter. The liberation front has gained access to the | |
* source code for a wire transfer program used by FIRST NATIONAL CYBER, a | |
* bank used by the alliance for oppression and we need you to find a | |
* vulnerability in this program and stea... er liberate the funds from an | |
* operative named prince_john. | |
* | |
* The bank programmers have attempted to put in a number of defensive checks | |
* to prevent abuse of the bank wire network, and we cannot modify the | |
* program source code without risking detection but we suspect that deadlines | |
* and corporate training programs have left them without the motivation | |
* required to think through each possibility clearly. | |
* | |
* It is imperative that you find a way to drain the account completely | |
* otherwise they may be able to withdraw the remaining funds and go | |
* underground before we can finish tracking them in the physical world. | |
* | |
* Good luck and as always, should you be detected your actions will be | |
* blamed on the Chinese Government. | |
* | |
* ~~~0xDEADFEED~~~ | |
* | |
* To build and run the wire transfer program: | |
* | |
* $ cc -o wire_transfer wire_transfer.c | |
* $ ./wire_transfer | |
* | |
*/ | |
#include <stdbool.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#define MAXLEN 255 | |
typedef struct Account { | |
int balance; | |
char owner[MAXLEN]; | |
} Account; | |
Account *init_account(const char *name, int balance); | |
bool read_transfer_amount(unsigned int *amount); | |
bool wiretransfer(Account *source, Account *dest, int amount); | |
void display_balance(Account *account); | |
void exit_if(bool condition, const char *message); | |
void validate_heist(Account *target); | |
int main(int argc, const char *argv[]) | |
{ | |
unsigned int transfer_amount; | |
char input[MAXLEN]; | |
char *dash; | |
printf("----- WELCOME TO FIRST CYBER BANK -----\n"); | |
printf("username: robin_hood\n"); | |
printf("password: *****************\n"); | |
printf("Logged In Successfully!\n"); | |
printf("account> wiretransfer prince_john\n"); | |
printf("----- BEGIN WIRE TRANSFER SETUP -----\n"); | |
Account *yours = init_account("robin_hood", 10000); | |
exit_if(yours == NULL, "Problem allocating memory"); | |
Account *theirs = init_account("prince_john", 500000); | |
exit_if(theirs == NULL, "Problem allocating memory"); | |
display_balance(yours); | |
display_balance(theirs); | |
while (true) { | |
printf("Amount to transfer from your account to theirs: "); | |
if (read_transfer_amount(&transfer_amount)) { | |
break; | |
} | |
printf("Invalid transfer amount!\n"); | |
} | |
printf("----- ATTEMPTING WIRE TRANSFER -----\n"); | |
printf("Wire transfer status: "); | |
printf("%s\n", wiretransfer(yours, theirs, transfer_amount) ? "SUCCESS" : "FAILURE"); | |
display_balance(yours); | |
display_balance(theirs); | |
validate_heist(theirs); | |
free(yours); | |
free(theirs); | |
return 0; | |
} | |
Account *init_account(const char *name, int balance) | |
{ | |
Account *account = malloc(sizeof(Account)); | |
if (account != NULL) { | |
strncpy(account->owner, name, sizeof(account->owner) - 1); | |
account->balance = balance; | |
} | |
return account; | |
} | |
bool read_transfer_amount(unsigned int *amount) | |
{ | |
char input[MAXLEN]; | |
char *dash; | |
fgets(input, sizeof(input), stdin); | |
while ((dash = strnstr(input, "-", sizeof(input))) != NULL) { | |
*dash = '0'; | |
} | |
*amount = strtoul(input, NULL, 10); | |
return amount > 0; | |
} | |
bool wiretransfer(Account *source, Account *dest, int amount) | |
{ | |
if (source == NULL || dest == NULL) return false; | |
if (source->balance - amount < 0) return false; | |
if (dest->balance + amount < 0) return false; | |
source->balance -= amount; | |
dest->balance += amount; | |
return true; | |
} | |
void display_balance(Account *account) | |
{ | |
if (account == NULL) return; | |
printf("%s has $%d in their account.\n", account->owner, account->balance); | |
} | |
void exit_if(bool condition, const char *message) | |
{ | |
if (condition) { | |
perror(message); | |
exit(EXIT_FAILURE); | |
} | |
} | |
void validate_heist(Account *target) | |
{ | |
if (target->balance == 0) { | |
printf("Target funds liberated: You win ;)\n"); | |
} else { | |
printf("Target still has operating funds, try again.\n"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment