Steps
The exercise uses a simple server application that allows buying the flag, but initially, we don't have enough funds to do so. The problem is how to get more funds by exploiting the server.
Fortunately, the author left the source code for reference. I am not that proficient in C, I've been using it a few years ago at the university, but I tried to hack this one nonetheless.
The only place where I am able to anything is when I get into Buy flags -> Definitely not the flag Flag
. Buying this one won't get me the flag needed to pass the exercise, it'll just adjust the funds (or: account_balance
) accordingly.
Source code analysis
There are some suspicious looking lines of code in the source:
int total_cost = 0;
total_cost = 900 * number_flags;
Both total_cost
and number_flags
are Integers, which means their the maximum value is 2147483647
(adding 1
will result in a signed int of -2147483648
).
The number_flags
is the only variable I can change.
Also:
account_balance = account_balance - total_cost;
The account_balance
is an Integer as well. It's decreased by the total_cost
. That'd mean if I'd be able to make total_cost
negative, the account_balance
would increase (base maths, negative + negative => positive).
Making total_cost
negative
So how can we make total_cost
negative?
Let's get back to the integer overflowing idea. I've opened an online C compiler and tried to mess with the values:
#include <stdio.h>
int main()
{
int x = 2147483647 + 1; // overflowed to -2147483648
int y = 900 * x;
printf("number_flags: %d\ntotal_cost: %d", x, y);
return 0;
}
// Output:
// number_flags: -2147483648
// total_cost: 0
That's no good. 900 * -2147483648
resulted in this:
warning: overflow in conversion from ‘long int’ to ‘int’ changes value from ‘-1932735283200’ to ‘0’ [-Woverflow]
Let's try another:
int x = 2147483647 + 10; // overflowed to -2147483639
int y = 900 * x;
// Output:
// number_flags: -2147483639
// total_cost: 8100
Yay, we've increased the total_cost
! But it's not enough to finish the task, as we need to make it negative.
The thing is that we'd need to find such a value for incrementing the maximum integer value of
2147483647
to make the900 * result
overflowing and becoming negative as well.
I've been appending zeros to the x
increment to the point when the total_cost
would become negative. I've settled with that:
#include <stdio.h>
int main ()
{
int x = 2147483647 + 100000000;
int y = 900 * -2047483649;
printf ("number_flags: %d \ntotal_cost: %d", x, y);
return 0;
}
// Output:
// number_flags: -2047483649
// total_cost: -194314116
Grabbing the flag
Ultimately I've opened the server once again, tried to buy 100000000
flag knockoffs and my account_balance
increased to 194314316
, which was enough to buy the final flag. Problem solved 💪
Disclaimer
As I said, at the time of writing this I am not that proficient in C, and the numeric systems are still a bit of the open waters to me. Probably I could find the easier way of increasing the account_balance
. But thanks to that meddling I was able to find the flag and that's most important to me 😉
Flag
picoCTF{m0n3y_bag5_65d67a74}