FLARE-ON Challenge – Part 3

Introduction

Hello and welcome to Part 3 of the FLARE-ON challenges (here are parts 1 and 2 in case you need to catch up!) This challenge started with the following message:

Nice job, you’re really knocking these out! Here’s the next binary. The password to the zip archive is “malware” again.
Keep up the good work, and good luck!
-FLARE

By the way get used to this; the password will be ‘malware’ for the future zips. There’s nothing in this welcoming message that hints to what we should do for this level (like in the previous one for example), so off we go!

The Challenge

After we unzip the archive we get a file called such_evil and it is 7168 bytes long. The file doesn’t have a file extension, but running file on it reveals it’s a M$ PE32 file, or in common parlance a .exe file! So what does such_evil.exe do?

Figure 1: What we first see when we run the executable.
Figure 1: What we first see when we run the executable.

And then it exits. Given M$’s history of bizarre error codes (I’m looking at you , ERROR_SUCCESS) it wouldn’t be surprising if ‘BrokenByte’ was an error code, but it’s not. So what other information can we get? Googling ‘Fatal Application Exit’ returns its MSDN page, which is not terribly helpful. It just says that an application should use  FatalAppExit as its last resort as it may not correctly close file handles or any other open resources used by the application (and also contains a very amusing comment by a confused user!), but the page gives no hints as to what arguments this method accepts. Writing a simple FatalAppExit Hello-World program in VS will inform us that this method accepts two arguments: the first argument is an UINT and the second one an LPCTSTR, or the message to be displayed to the user (gotta love M$ types). After all this I found an actually useful MSDN page on FatalAppExit.

An error occurred and the program crashed, and we should find out what error occurred! Inspecting the environment variable %errorlevel% shows that the exit status of our program was 0. As you might have guessed, error code 0 is ERROR_SUCCESS. So…was there an error or not?

Peering Under the Hood, or IDA

Opening the binary up with IDA we can see that it has only four functions defined. My cunning plan is to find where that string, BrokenByte, is being used and work backwards from there. Genius, I know. Since it is not an M$  error message, it’s unlikely to be in any of the imported DLLs and therefore *has* to be in our application. Right?

Figure 2: Strings used by the application at compile time.
Figure 2: Strings used by the application at compile time.

So my cunning plan failed, as per Figure 2. What if we track down the call to FatalAppExit?

Figure 3: Application declared imports.

Another plan goes in the bin. Looks like we’ll have to do some actual thinking for this one. So, let’s have a look at the functions in the application.

There are four functions in this application:  sub_401000, sub_40258C, sub_402590 and sub_4025D1. While most of them are dull as ditch water, with the exception of sub_401000 which is very promising. Figure 4 illustrates the end of this huge function:

 

Figure 4: Sample from the end of function sub_401000.
Figure 4: Sample from the end of function sub_401000.

Although sub_401000 is too large to post, it’s a big repetition of the sample shown in Figure 4, it moves bytes to the stack. Also observe the call eax instruction towards the end of the block,  I bet that something interesting is happening after that call (yes, I am very weary of control flow obfuscation like that).

Running this binary in immunity and putting a breakpoint over call eax we see that eax’s value is 0x18FD47, a stack address! Let the single-stepping begin! Figure 5 shows what we first come across when we follow the call:

Figure 5: Stack after following the call eax call.
Figure 5: Stack after following the call eax call.

Huh, valid code. I say valid because if you view the stack segment as code, in a normal program, most of the times the result might appear as broken, very obscure or generally incoherent instructions. We can see that the first bit of assembly is a loop that writes to the stack, so if we place a breakpoint on 0x18FD63 and then inspect the stack:

Figure 6: Stack after the initial XOR loop.
Figure 6: Stack after the initial XOR loop.

Aha. So somebody is being “funny” and messing with the stack. It’s amazing how instructions can form a valid sentence, really makes Von Neumann shine! Observe the memory address 0x17FD68 in the CPU and Stack windows and you’ll see that the first XOR loop revealed this message on the stack: “and so it begins“. Continuing our journey one step at a time and inspecting the stack, we get to a second message, shown in Figure 7:

Figure 7: Stack after second set of transformations, reveals a new message.
Figure 7: Stack after second set of transformations, reveals a new message.

nopasaurus“. I wonder what that is about, guess I should keep an eye out for a noticeable NOP-sled or something. Stepping forward, we reach another loop in our code. Stepping over it reveals a new message, “get ready to get nop’ed so damn hard in the pain”, and if we continue in this fashion we encounter yet another message, “omg is it almost over?!?”.

At this point it’s worth taking a step back and think about what we’re dealing with. The messages so far suggest that we should keep an eye out for some NOP instructions. Furthermore, it’s worth noting how the code behaves so far. Previous segments use the stack to modify the code that is going to get executed next and to reveal clues. The general format in which this is happening could be abstracted as:

....instructions....

mov ESI, target message address
more loop init here
jmp in loop
XOR target bytes, some stack address
increment loop counters
JMP looptop
JMP next instructions

... more instructions ...

Tracing this pattern has, so far, consistently revealed a message on the stack after the XOR loop. Following the code and watching out for loops, we finally get to Figure 8:

Figure 9: Our email address and a new message!
Figure 8: Our email address and a new message!

After following this multi-step procedure we’re finally there! The address we’re after is such.5h311010101@flare-on.com, as shown in the memory window. Also, if we keep on stepping for a bit longer, we see a new message crop up in the memory that reads “aaaaaand i’m spent“, as seen in the stack and register windows in Figure 8. Although absent from Figure 8, there were some NOPs preceding the code that revealed the email address and I was looking out for those!

Taking it one step further

If you remember my original ingenious theories you would be curious to know where “BrokenByte” is and where FatalAppExit is called. If we take some more steps we will eventually arrive at a point in the code where BrokenByte is being decrypted on the stack in much the same way as our previous strings. FatalAppExit is being called by the the application enumerating kernel32.dll’s functions in memory, finding out FatalAppExit’s address and loading it into EDI and then doing CALL EDI.

Fin

We stepped up to this challenge as well. Although it wasn’t complicated, it did require some vigilance and patience. You had to spot that CALL EAX at the end of sub_401000 and further look into it, but thankfully the first clue that you’re going in the right direction was given very early on and so we didn’t really have to step up our game! The fourth challenge is next 🙂

P.S. Sorry for the puns, there were there and I had to do it.

Advertisements
FLARE-ON Challenge – Part 3

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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