Challenge 1 – FLARE-ON 2015

-[ Introduction ]

Hello all, it has been a while since I’ve posted something so I thought I’d get around to writing up what I did on this years Flare-On challenge! Let’s start with the first one!

-[ The Challenge Binary ]

What is this file with the overly long name?

> % file i_am_happy_you_are_to_playing_the_flareon_challenge.exe
i_am_happy_you_are_to_playing_the_flareon_challenge.exe: PE32 executable (console) Intel 80386, for MS Windows

Right, M$ things. Opening it up in IDA will show us that only one function is declared, called start, and the first challenge is really this simple. Everything we might need is there!
Apart from windows causing you all the confusion because of how windows is (e.g. ReadFile is also used to read standard input…), this challenge has unobfuscated strings and a pretty straightforward control flow, so let’s do it!

-[ The Solution ]

Figure 1 is a screenshot of the start functions, with some annotations of my own to make it clearer.

Figure 1: disassembly of the main function.
Figure 1: disassembly of the main function.

Starting with the first basic block, the call to ReadFile is our first stop. The first two arguments, hFile and lpBuffer, are really just pointers telling ReadFile where to read from and where to write the data that it read. In this case it’s reading from standard input and saving to a location in memory. We can also see that memory variable being referenced later on, so let’s hang on to that!

Exactly after the ReadFile call the register ECX gets XORd with itself, a machine-efficient way to zero-out a register, and then what looks like a loop follows. Could it be that ECX is a loop counter? I think so because after the loop, this basic block follows:

.text:0040105D                 inc     ecx
.text:0040105E                 cmp     ecx, 18h
.text:00401061                 jl      short checking_loop

We can also spot the strings “You are success” and “You are failure”, and the paths leading to those two also carry some information with them. In particular, the string “You are success” is reachable only after successful termination of the loop (after 24 iterations, to be precise) while the failure string can be reached at any point within the loop where the comparison fails. As such, getting that comparison right will get us to Challenge 2!

We can see that the checking loop is fairly simple; it will take a byte of our input, XOR it with 0x7D and then compare it to a byte from the location 0x402140 + ECX (another indication that ECX is a counter, as it is used to index into an char array):

.text:0040104D checking_loop:                          ; CODE XREF: start+61j
.text:0040104D                 mov     al, our_string[ecx]
.text:00401053                 xor     al, 7Dh         ; transform string to compare with secret
.text:00401055                 cmp     al, byte_402140[ecx] ; byte_402140 must be where the secret is stored!
.text:0040105B                 jnz     short do_not_want_to_be_here

Looking at what is stored in location 0x402140 in our binary, we can extract the following array:

.data:00402140 byte_402140     db 1Fh                  ; DATA XREF: start+55r
.data:00402141                 db    8
.data:00402142                 db  13h
.data:00402143                 db  13h
.data:00402144                 db    4
.data:00402145                 db  22h ; "
.data:00402146                 db  0Eh
.data:00402147                 db  11h
.data:00402148                 db  4Dh ; M
.data:00402149                 db  0Dh
.data:0040214A                 db  18h
.data:0040214B                 db  3Dh ; =
.data:0040214C                 db  1Bh
.data:0040214D                 db  11h
.data:0040214E                 db  1Ch
.data:0040214F                 db  0Fh
.data:00402150                 db  18h
.data:00402151                 db  50h ; P
.data:00402152                 db  12h
.data:00402153                 db  13h
.data:00402154                 db  53h ; S
.data:00402155                 db  1Eh
.data:00402156                 db  12h
.data:00402157                 db  10h

Staying true to our very own lazy selves, though, we shall a program do all the hard work of XORing for us! The following prints out the flag:

#include <stdio.h>
//gcc -Os -o sol.o -std=c99 sol.c
char covert[] = { 
    0x1F, 0x08, 0x13, 0x13,
    0x04, 0x22, 0x0E, 0x11,
    0x4D, 0x0D, 0x18, 0x3D,
    0x1B, 0x11, 0x1C, 0x0F,
    0x18, 0x50, 0x12, 0x13,
    0x53, 0x1E, 0x12, 0x10};

int main(void){
    for (int i = 0 ; i < 24; i++){
            covert[i] ^= 0x7D;
    printf ("Result is : %s\n", covert);
    return 0;

-[ Conclusion ]

This was a nice easy start, and we got the email address to get onto challenge number 2! Email to get the next one!

Challenge 1 – FLARE-ON 2015

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s