Flare-On is a CTF style reverse engineering challenge organized by the FLARE team at FireEye Labs annually. There are a series of 12 challenges with increasing difficulty. This year the challenges covered a variety of domains ranging from Windows to Linux and even the NES (Nintendo Entertainment System).
In this series of blog posts, we will try to go through the challenges one at a time. There may be multiple ways to solve a problem. The techniques presented here just reflects the views of the author.
1 - Memecat Battlestation [Shareware Demo Edition]
The challenge reads...
Welcome to the Sixth Flare-On Challenge!
This is a simple game. Reverse engineer it to figure out what "weapon codes" you need to enter to defeat each of the two enemies and the victory screen will reveal the flag. Enter the flag here on this site to score and move on to the next level.
This challenge is written in .NET. If you don't already have a favorite .NET reverse engineering tool I recommend dnSpy
** If you already solved the full version of this game at our booth at BlackHat or the subsequent release on twitter, congratulations, enter the flag from the victory screen now to bypass this level.
The challenge consists of a Windows executable - MemeCatBattlestation.exe. Running, we are greeted with the following window.
At the bottom half of the window, there's a text box which requests us to input a "Weapon Arming Code". Entering a random string says "Invalid Weapon Code". Our objective in Stage-1 is to get the correct arming code. That challenge description already mentions that this was written in .NET. So let's analyze the executable in dnSpy.
Once the binary is loaded in dnSpy, right-click on MemeCatBattlestation and chose "Go to Entrypoint" as shown in Figure 2. The Entrypoint is the code from where execution starts. This is like the
main function we have in a C or C++ program.
The entrypoint is located in the
Program class. The decompiled code looks like.
The application creates four forms -
VictoryForm as we can see in Figure 3. Initially, only
Stage1Form is shown. We proceed to
Stage2Form only after we provide the correct arming code. There's also a
Stage2Form. This suggests this challenge may consists of two stages both of which requires a weapon code to proceed. For now, let's have a look at
A .NET GUI application can have event handlers attached to the various controls. For example, there can be a button click handler attached to a button control which will be called whenever we click on that button. Going through the decompiled code we can find an event handler for the fire button.
As we can see, the code compares the input in the textbox to the string RAINBOW. If it matches it starts a victory animation timer. This must be the correct weapon arming code for passing Stage 1.
The second stage also requires us to input a weapon arming code. Without further ado, let's check the decompiled code of the form.
In stage 2, our input string in the textbox is passed to a method
isValidWeaponCode, which as it's name suggest, must check whether the code is valid or not.
Unlike the check in Stage 1, there's no direct string comparison here. Instead, it converts the string to a character array and Xor's each element in the array with the character
SequenceEqual method, compares two arrays for equality and returns
True if they match. In other words, after Xoring each element with
A, the resultant array must match with the given array.
Finding the original array is easy. We just need to Xor the given array with 'A' again.
>>> target = [u'\x03', ' ', '&', '$', '-', u'\x1e', u'\02', ' ', '/', '/', '.', '/'] >>> ''.join(map(lambda x:chr(ord(x)^ord('A')), target)) Bagel_Cannon
Typing, Bagel_Cannon as the arming code, we win the level and get the flag.