Home Flareon9 Challenges 1-4 solutions and methodology
Post
Cancel

Flareon9 Challenges 1-4 solutions and methodology

Flaredle

For the first challenge, we are greeted with the following message:

You probably won’t win. Maybe you’re like us and spent the year playing Wordle. We made our own version that is too hard to beat without cheating.

We are also given a zip file with the following contents…

Flaredle Zip Contents

And a link to the hosted version of the challenge: http://flare-on.com/flaredle/. It looks like this:

Flaredle index.html

It’s a clone of Wordle! The first major difference being that the word seems to be 21 characters long. Odds are that we need to simply guess the correct word(s) to win the challenge. Upon entering some text and pressing enter, the message Word not in list is displayed.

Flaredle Test

So there is a list of words, just like in the actual Wordle game. Looking at the source files we were given, there is a file titled words.js. It contains an array WORDS of 21 letter long words.

Words.js

Looking at the code in script.js, there are several note worthy functions including one named checkGuess. In this function, we can find the variable name for the target word we need to guess. Here we can also see that the flag is simply the correct guessed word + @flare-on.com.

Guess code

By following the variable rightGuessString, we can see how it is created. rightGuessString is simply assigned a word from the WORDS array at index CORRECT_GUESS. The value of CORRECT_GUESS is 57.

Guess code

Since arrays in Javascript begin at 0, we simply need to look at what word is assigned on line 58 in the WORDS array in words.js.

Guess code

Success! Now we have the flag and can enter it on the website just to be sure.

Guess code

PixelPoker

I said you wouldn’t win that last one. I lied. The last challenge was basically a captcha. Now the real work begins. Shall we play another game?

Again, we are given a zip file for the next challenge.

PixelPoker Files

Contents of readme.txt:

1
2
3
4
5
Welcome to PixelPoker ^_^, the pixel game that's sweeping the nation!

Your goal is simple: find the correct pixel and click it

Good luck!

Interesting! The goal is to select a correct pixel. Lets run PixelPoker.exe and see how this works.

PixelPoker

Moving the mouse around changes the Window title text showing the current pixel the mouse is pointing to. Beside that, is a counter for each time the mouse is clicked.

PixelPoker Window title

After clicking 10 times, the following message appears and then the application exits.

Womp womp

Let’s open this application up in IDA and see what we can find a way to see the correct pixel or bypass the checks and make it think we clicked the correct one. Firstly, we need to find a function that is called when a click happens in an application. One way to do this is by looking for the “Womp Womp” text when 10 clicks have happened. The “womp womp” message appears after the final click, so this a good place to start.

Strings

And there is the string! By double clicking it, we can see the string in the resource data.

String Ref

Beside the string, we can see the function it is used in: sub_4012C0. Double clicking it takes us to where the string is used in the function.

Womp messagebox

Now we can see the call to MessageBoxA that displays the text Womp Womp. So lets go up in the flow a bit.

10 Click check

Here we see a cmp instruction that compares eax to 10. The value of dword_413298 was placed into eax so this is the click counter variable! Let’s follow the other branch to see what happens if there isn’t 10 clicks yet.

X Y Check

Hm. Here we see two immediate checks. These are the checks for x and y. If we follow the flow for if a check is not met, both go back to the portion of code for retitling the window. However, if both checks are met, the code proceeds to another function: sub_4015D0. This could relate to the flag. Let’s set breakpoints on both cmp instructions and debug the application.

After running the application, the breakpoints have not been hit yet - good sign. So we can click the app and indeed the first breakpoint is hit. Let’s jump forward once to the jnz instruction.

Debugging

IDA highlights the path at jumps that is about to be taken and we can see it’s the wrong path we want - as expected. So let’s set the zero flag register on the right (ZF) to 0x1 instead of 0x0. IDA then highlights the other branch will be taken! Then continue or step the application.

Debugging

Let’s do the same thing again for the jump. And success!

Success

And thus we have tricked the app into thinking we found the correct pixel! And we are gifted the flag.

Magic8Ball

You got a question? Ask the 8 ball!

Once again, we are given a zip file containing the challenge files.

8Ball Files

This app appears to be a crude representation of a magic 8 ball. We can type text for a question, use the arrow keys to “shake” the 8 ball, and press enter to get a result.

8Ball Files

Let’s toss the executable in IDA and see what we can find.

8Ball Dissasembly

We start out with WinMain() consisting of a single function call and a return. Let’s go into this function.

8Ball Dissasembly

Here we see some calls to get the command line args, heap setup, and some SDL setup. Following the flow we see a call to another function sub_4027A0. Let’s see what this function does.

8Ball Dissasembly

Here we can already see this function set’s the window title text to Magic 8 Ball.

Following the flow and looking at different functions, we come to sub_402090. This function contains calls to SDL_CreateWindow, SDL_CreateRenderer and other stuff used for creating the application gui items. Near the end of this function, before some images and fonts are loaded, there is some data stored at edi+5Ch. By selecting the data and pressing R, we can see that as a string.

8Ball Dissasembly

It spells out gimme flag pls?! Entering this into the text box and pressing enter does not reveal the flag though, so there must be more. Let’s go back to the previous function and keep looking at the other function calls. Continuing on, we eventually reach function sub_4024E0. Looking a bit at this function, we can see something a bit odd.

8Ball Dissasembly

Why is it pushing U, D, and L before each call to sub_401780? This continues on and adds another character R. Hm. U, D, L, R? That corresponds with the directions we can shake the 8 Ball! Looking at all of the characters, we see they end up as LLURULDUL. Let’s see what happens when we enter the text gimme flag pls? and do those specific movements with the 8 Ball.

8Ball Solved

Success!

Darn_mice

Again we are given a zip file.

Darn Mice Files

This time we get a single executable.

Darn Mice

Running it, we see no output. Adding a -h flag and prints a strange message, and exits(?). This happens with anything added as arguments. The mouse loading wheel appears for a second when the program exits, almost like it is crashing. Strange. Let’s run this in x64dbg and see if it’s exiting or crashing.

Darn Mice Crash

Well, it is crashing. xchg ecx,eax followed by many add byte ptr ds:[eax],al? That’s also odd. Let’s also open this in IDA. _main is simple enough, it checks to make sure there is a program argument and then calls sub_401000.

Darn Mice Dissasembly

Hm. Here we see a large number of bytes being stored in an array. Then we can see a string is pushed to the stack then sub_401240 is called to print the string.

Darn Mice Dissasembly

Here we see a loop begin at the top checking if a variable is 35 (23h). If it is, it prints No, nevermind. Otherwise, shown on the bottom left, it prints You leave the room, and a mouse EATS one, writes some bites to a buffer, jumps to it? and then prints Nibble... Hm. My first thought was that this is the data in the array and we need to modify that, since it is 35 bytes long. But the first byte in the array is 0x50. The instruction it’s crashing on is instruction 0x91. Let’s step through in the debugger again.

Darn Mice Dissasembly

Ah! On this instruction we see how we get 0x91 to jump to! Look at the instruction - add ecx, eax and look at the values of the registers on the right. 41 + 50 = 91! 41 (A) is the first byte in the argument we are passing! Using this we can modify what the instruction is that we are jumping to. Looking at the rest of the flow, it doesn’t appear that we need to do anything other than return. Looking at some reference the ret instruction is 0xC3. So lets use some python to calculate what our command line arg needs to be in order for each addition to equal the return instruction.

1
2
3
4
5
6
7
8
9
10
11
12
b = [0x50, 0x5E, 0x5E, 0xA3, 0x4F, 0x5B,
     0x51, 0x5E, 0x5E, 0x97, 0xA3, 0x80,
     0x90, 0xA3, 0x80, 0x90, 0xA3, 0x80,
     0x90, 0xA3, 0x80, 0x90, 0xA3, 0x80,
     0x90, 0xA3, 0x80, 0x90, 0xA3, 0x80,
     0x90, 0xA2, 0xA3, 0x6B, 0x7F]

solve = []
for i in b:
    solve.append(chr(0xc3 - i))

print(''.join(solve))

Running this, we see the argument needed is see three, C3 C3 C3 C3 C3 C3 C3! XD! Let’s run the code with that argument and see if it worked.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
C:\Users\Starw\Desktop\Flareon9\darn_mice>darn_mice.exe "see three, C3 C3 C3 C3 C3 C3 C3! XD"
On your plate, you see four olives.
You leave the room, and a mouse EATS one!
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
Nibble...
When you return, you only: see three, C3 C3 C3 C3 C3 C3 C3! XD
i_w0uld_l1k3_to_RETurn_this_joke@flare-on.com

C:\Users\Starw\Desktop\Flareon9\darn_mice>

Success! We have the flag!

This post is licensed under CC BY 4.0 by the author.