Flare-On 6 CTF WriteUp (Part 3)

Flare-On 6 CTF WriteUp (Part 3)

. 5 min read

This is the third part of the Flare-On 6 CTF WriteUp series.

3 - Flarebear

The challenge reads

We at Flare have created our own Tamagotchi pet, the flarebear. He is very fussy. Keep him alive and happy and he will give you the flag.

Different from previous, this is an Android challenge. We are provided with an APK - flarebear.apk. Let's install and run this in an Android Emulator. I prefer Genymotion but you can use any other emulator or even a real physical device.

Figure 1 - Flarebear running in Genymotion
Figure 1 - Flarebear running in Genymotion

The game prompts us to create a "New Flare Bear". Let's create one and give it a name.

Figure 2 - The bear is happy!
Figure 2 - The bear is happy!

At the bottom, we have three buttons - Feed, Play & Clean. Keeping the bear inactive makes it unhappy and it starts to cry.

Figure 3 - The bear is not happy!
Figure 3 - The bear is not happy!

Our objective is thus to keep the bear happy by feeding, playing and cleaning at regular intervals. However we have no idea the order in which we do this. To understand the core logic of the game we need to study its code. We can use JADX to decompile the APK to its Java source.

The FlareBearActivity class implements the game logic and resides in the com.fireeye.flarebear package. The presence of import kotlin.text.StringsKt; suggests that the game was most likely developed in Kotlin as opposed to Java.

Figure 4: The game was developed in Kotlin
Figure 4: The game was developed in Kotlin

Corresponding to the three actions - feed, play and clean we have three methods.

Figure 5: The methods handling feed, play and clean
Figure 5: The methods handling feed, play and clean

Each of the methods in turn call other methods to change some internal state variables. The changeMass, changeHappy and changeClean changes the mass, happiness and cleanliness by a given amount respectiviely.

  • Feeding increases mass and happiness by 10 and 2 units respectively while reducing cleanliness by 1 unit.
  • Playing decreases the mass and cleanliness by 2 and 1 unit respectively while increasing happiness by 4 units.
  • Cleaning increases cleanliness by 6 units while decreasing happiness by 1 unit. It doesn't change mass.

Internally, these methods make the changes and store the updated value using the setState method.

Figure 6: The changeXXX methods make the change to state variables
Figure 6: The changeXXX methods make the change to state variables

The setState method uses Android PreferenceManager to store the state values as a key-value pair.

Figure 7: Implementation of the setState method
Figure 7: Implementation of the setState method

In each of the feed, play and clean methods there was a saveActivity call with character f, p, and c passed as argument respectively. Lets look at its code.

Figure 8: The saveActivity method
Figure 8: The saveActivity method

All saveActivity does is to fetch a state variable named activity and append the character to it.

We have also seen a call to setMood from the clean method. The decompiled code looks interesting.

Figure 9: The setMood method
Figure 9: The setMood method

If both isHappy and isEcstatic return true it calls danceWithFlag. This is what we want. Let's have a look at both of the methods.

Figure 10: isEcstatic and isHappy methods
Figure 10: isEcstatic and isHappy methods

isEcstatic returns true only if the mass, happiness and cleanliness state variables are 72, 30 and 0 respectively.

isHappy returns true if result of getStat('f') / getStat('p') lies in the range 2.0 to 2.5. The getStat method counts the occurrences of the character in the state variable named activity. We have seen before that the saveActivity method appends a character to this state variable.

Figure 11: The getStat method
Figure 11: The getStat method

In other words, isHappy will return true if the number of times we feed divided by the number of times we play lies in the aforementioned range.

Armed with the above information, we can form some equations. Let us denote the number of times to feed, play and clean be f, p, and c respectively. Initially, mass, happiness and cleanliness are all zero.

Final Mass = 10f - 2p
Final Happiness = 2f + 4p - c
Final Cleanliness = -f -p +6c

Thus we have these system of equations,

Putting these system of equations in Wolfram Alpha, we get,

Figure 12: Solving the system of equations
Figure 12: Solving the system of equations

Thus, we need to clean 2 times, feed 8 times and play 4 times in order to make it happy and ecstatic which should gives us the flag. Let's try it out. There is no specific order in which we should feed, play and clean, but we should make sure that the number of times we execute each action equals the equation results.

Figure 13: We got the flag!
Figure 13: We got the flag!

Executing the required actions, make the bear happy and it gives us the flag.

Flag: th4t_was_be4rly_a_chall3nge@flare-on.com

Finally, its worth mentioning what if we patch isHappy and isEcstatic to return true instead of finding correct the number of times to execute each action. Will that gives us the flag too?

Unfortunately, this approach won't work. The number of times is used to derive a password which is used as a key to decrypt an encrypted resource using the AES crypto algorithm. Without the correct key we will not be able to decrypt the resource.

Figure 14: The password is derived from the state variables
Figure 14: The password is derived from the state variables
Figure 15: The decryption routine
Figure 15: The decryption routine