*"The inventor of kittykoinz had the great idea to implement a transaction fee, so she can get more moneyz. She stressed the developers to get this feature ASAP. Never stress the devs..."*

We are provided with a web version of this program to netcat to, and the source code as a jar file. After patching the jar file so that it will run, we are provided with the following options:

Let's try and get the flag:

Of course it wouldn't be that easy... What if we try sending some coins to charity?

Hmm, we sent 1 coin but the account balance has been decreased by 3, obviously the transaction tax has been implemented and set at 2 coins. Let's try decompiling the jar to see what secrets we can uncover. I used JD-GUI to achieve this. Inside we find four classes:

  • MainRunner.class
  • IO.class
  • Shop.class
  • Account.class

First let's take a look at Shop.class:

We can see that the transaction tax is indeed set at 2, and that we need 1337 kittykoinz to obtain the flag - Just 1 away from our account balance. The try/catch in sendToCharity also blocks us from giving the program bogus input..

Next let's take a look at MainRunner.class - It contains some methods for displaying text and the main method which doesn't look too interesting.

IO.class is also not too interesting...

Account.class contains the method payCoins which actually handles the paying of coins out of an Account as well as some generic getters/setters - Let's take a closer look at the payCoins method

It has a few sanity checks which will mostly stop us from trying to underflow the amount and instead give us the You cannot generate debts message. We can try a basic underflow by decreasing the account balance to 1 and then attempting to pay out the maximum 32-bit integer 2,147,483,647

But this fails because in order to underflow we must get the integer to -2,147,483,649, which is impossible given the minimum starting balance of 1 and the transaction tax of 2. It could work if we had a starting balance of 0, but this is already checked at the start of the method.

the if (amount < 0) { amount *= -1; } check also prevents us from providing a negative integer so that the subtraction is cancelled and converted to an addition that would allow us to add to our account balance.

But what happens if we try to multiply the smallest (most negative) 32-bit integer by -1? The smallest 32-bit integer is 2,147,483,647, but the smallest is -2,147,483,648. This would mean multiplying it by -1 would produce an overflow and return us to our original number... A quick check in jshell - it works!

Let's try entering this amount into the program

Success!

Now to just obtain the flag

Unfortunately the web version of this challenge crashed at some point and cannot be accessed, so flag unavailable :(