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.
The game prompts us to create a "New Flare Bear". Let's create one and give it a name.
At the bottom, we have three buttons - Feed, Play & Clean. Keeping the bear inactive makes it unhappy and it starts to cry.
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.
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.
Corresponding to the three actions - feed, play and clean we have three methods.
Each of the methods in turn call other methods to change some internal state variables. The
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 uses Android PreferenceManager to store the state values as a key-value pair.
In each of the
clean methods there was a
saveActivity call with character
c passed as argument respectively. Lets look at its code.
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.
isEcstatic return true it calls
danceWithFlag. This is what we want. Let's have a look at both of the 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.
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
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,
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.
Executing the required actions, make the bear happy and it gives us the flag.
Finally, its worth mentioning what if we patch
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.