Flare on 2020 - Level 1
This challenge is a python that have compiled to windows program. The organizer also gives us a source code of this program. Let's dive into the code by static analysis. We have the following functions
+buy_click : function
+cat_clicked : function
+decode_flag : function <--
+game_screen : function
+main : function
+password_check : function <--
+password_fail_screen : function
+password_screen : function
+victory_screen : function
▼ variables
buying
current_autoclickers
current_coins
It looks like the program has several functions that may be of interest to us. In particular, the password_check
and decode_flag
functions stand out as potentially important.
To start, let's take a closer look at the password_check
function. This function is likely responsible for verifying the user's password, so it will be important to understand how it works and what it does. We can examine the code line by line to see what it does and how it operates.
Next, let's move on to the decode_flag
function. This function is probably responsible for decoding the flag that we need to find in order to solve the challenge. By analyzing the code in this function, we can learn more about how the flag is encoded and what we need to do to decode it.
The password_check
function
Since the program requires user to enter a password with a protect screen, the developer implements this feature by 2 functions:
password_screen
shows the input text.password_check
checks the password as follows
def password_check(input):
altered_key = "hiptu"
key = "".join([chr(ord(x) - 1) for x in altered_key])
return input == key
The solution is trivial, they key is "ghost" by running the code in python interpreter
print("".join([chr(ord(x) - 1) for x in "hiptu"]))
The decode_flag
function
I discovered that the victory_screen
function calls the decode_flag
function by using the "find references" feature from the Language Server Protocol (LSP). The game_screen
function calculates the token value using the following logic:
target_amount = (2 ** 36) + (2 ** 35)
if current_coins > (target_amount - 2 ** 20):
while current_coins >= (target_amount + 2 ** 20):
current_coins -= 2 ** 20
victory_screen(int(current_coins / 10 ** 8))
return
In order to display the victory screen and see the flag, the current_coins
variable must have a value greater than (target_amount - 2 ** 20)
. To achieve this, we can use the following code:
target_amount = (2 ** 36) + (2 ** 35) + 1 # +1 to jump inside the while loop.
current_coins = target_amount - 2 ** 20
while current_coins >= (target_amount + 2 ** 20):
current_coins -= 2 ** 20
token = int(current_coins / 10 ** 8)
With the token
value calculated, we can now call the decode_flag
function to decode the flag and print it to the screen:
print(decode_flag(token))
idle_with_kitty@flare-on.com