I completed several of the recently ended Flare-On challenges put on by FireEye. Flare-On is their annual reverse engineering CTF which takes place over six weeks and awards those who complete every challenge bragging rights and some unique swag. This year the CTF was comprised of twelve individual challenges increasing in difficulty and spanning several different disciplines. My interest in the challenge primarily stemmed from a desire to see how far I could get with my current skillset. Unfortunately, I fell short of my goal but I learned a lot and that’s all anyone can ask for.
The first challenge centered around a .NET executable which when run reveals itself to be a simplistic game where the only goal is to enter the “password” to defeat the challenger. Obviously we have no way to know the passwords so the only logical option is to reverse the binary to see if we can determine what the passwords are and win the game. I previously had zero experience working with .NET binaries and luckily FireEye gives everyone a hint to try using dnSpy to decompile the code. Far be it for me to question FireEye so that’s exactly what I did…
Once I familiarized myself with the dnSpy interface getting to the first “password” to solve the challenge was fairly easy. I identified the FireButton_Click() function within the Stage1Form class which checks if the password entered is “RAINBOW” and succeeds if it is and fails otherwise. Once we enter “RAINBOW” we are presented with another challenger. On to Stage Two…
Stage Two is identical to Stage One: we need to figure out the “password” to defeat the challenger. I dropped down to the Stage2Form class in dnSpy and again chose the FireButton_Click function in hopes of another easy win but was met with slightly more complicated code. Instead of simply checking string in cleartext the FireButton_Click() function calls the isValidWeaponCode() function.
No problem, let’s look at that function…
Well this isn’t going to be quite as simple as Stage One. It looks like the string we are entering into the textbox is being passed to isValidWeaponCode() and becomes a character array. From here, a for loop iterates over our array and performs a bitwise XOR operation with the character ‘A’. The isValidWeaponCode() function will return true if the string we enter, when XOR’ed with ‘A’, is equal to the strange array of characters at the bottom of the function. But how do we get the actual password? Thankfully to get the cleartext from an XOR’ed ciphertext all we need to do is use the known key, in our case ‘A’, against the ciphertext to get back to cleartext.
I decided to use CyberChef to help me with this task. First we needed to deal with the characters prepended with “\u”. Assuming that this escape sequence meant Unicode I had CyberChef unescape the “\u” and return the string in its raw form. Then, using the XOR functionality, I had that raw string XOR’ed with ‘A’. All of this netted the Stage Two password, “Bagel_Cannon”.
Success! Entering the second password wins the game and presents us with the flag “[email protected]”.