Thursday, August 25, 2016

FLARE On 2015 - Challenge 5


About:


This is the 5th challenge from FireEye's 2015 "FLARE On" challenge (http://flare-on.com/)


Solution:

Challenge 5 is different again from the ones before. 

This time we get an exe file called "sender" and a pcap file called "challenge.pcap", so it seems likely we'll need to reverse-engineer the exe to understand some piece of data hidden in the pcap.

Let's take a quick look at the pcap:


For better or worse, it looks like the only data transmitted went out via HTTP POST requests, where the only data sent was 4 bytes in each packet (here: UDYs).

The server responds with simple "1"s. 

So we have it, the full data transmitted in hex was:

55445973314437624e6d6445316f3367356d733156365272594356764f444a46314470784b5478414a3978755a573d3d

In binary this looks like:

UDYs1D7bNmdE1o3g5ms1V6RrYCVvODJF1DpxKTxAJ9xuZW==

Base64?? Un-base64'd it looks like:

P6,\xd4>\xdb6gD\xd6\x8d\xe0\xe6k5W\xa4k`%o82E\xd4:q)<@'\xdcne

Hmmm.... Alright let's break open the exe file with IDA:



Right off the bat, it looks like we're reading a key file "key.txt". So first guess, maybe this will send off the key.txt file after it's been encrypted/encoded and our task is to recover the original file?

Jumping ahead into the part of the code where the imported HTTP-related libraries are used, we get this:



Ok this is looking pretty good & simple. If we explore the calling tree a bit more, we come across what looks like a pretty straightforward XOR loop:



It seems to be using the "flarebearstare" string as a fixed key.

Once we notice that the base64 routine uses a custom, case-swapped alphabet ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/"), it looks like we may be getting pretty close to being done....


Writing out a python3 routine to take the data sent over the network interface, decode it using the special base64 alphabet, and then decrypt it with the constant key XOR, we get something like this:


from base64 import b64decode

KEY = 'flarebearstare'

def decrypt(str):
    result = ""
    for i, b in enumerate(str):
        result += chr(b - ord(KEY[i % len(KEY)]))
     
    return result

data = b64decode('UDYs1D7bNmdE1o3g5ms1V6RrYCVvODJF1DpxKTxAJ9xuZW=='.swapcase())

print(decrypt(data))


Running this code, we see the following printed out:

Sp1cy_7_layer_OSI_dip@flare-on.com

Woo hoo!

No comments:

Post a Comment