How We Decoded Some Nasty Multi-Level Encoded Malware

From time to time, we come up with interesting bits of malware that are just calling us to decode and learn more about them. This is one of those cases.

Recently, I crossed pathes with this little gem:

dissecting-malware-step-1

That snippet is encoded malicious content. The full payload is is much bigger, 12816 characters, to be exact. Seems benign, right? At least it looks interesting. So interesting that I decided to dissect it, piece by piece.

1st Level of Encoding

So, how do we decode it? As always, there are 2 ways. The easy way is to replace the Eval() function with an Echo. Doing so will just print out the decoded contents. That’s is too easy though and we wouldn’t learn anything. Lets get a closer look.

The first line is a standard for loop which actually contains the payload. Also, the stopping condition looks a little funny.

@ord($e[$o])

This function returns the ASCII code of the supplied char argument as an integer. Now, how is that a stopping condition? Well, when we access a char in the array that represents the payload that is non-existent (e.g. when we go out-of-bounds of the array), function return an error and that stops the for loop. So, with this condition, we will go through all of the payload.

Next couple of lines are interesting:

if ($o < 16) {
$h[$e[$o]] = $o;
} else ...

This basically creates an array that will contain the first 16 characters of the payload, which are used to serve as a kind of dictionary.

After this, we start decoding the payload:

...
else {
$d .= @chr(($h[$e[$o]] << 4) + ($h[$e[++$o]]));
}
...

We are decoding the payload bit by bit and are putting it into the $d variable. But how? Well, it looks like the payload is decoded by pairs of characters.

The first character of the payload after the 16 char dictionary represents the first 4 bits of the first decoded char. The second character is the last 4 bits of the same character. For example, the first 2 chars of the payload are “,,” which are decoded to a char ‘f’.

Using this technique, our decoded payload looks like this:

dissecting-malware-step-2
Same thing again… Another step of the same kind of encoding.

2nd Level of Encoding

After we decode the first part using the same technique as previously described, we end up with something interesting. Our $d variable is full of some sort of binary content. The script is setup to acquire a key from the user using either a cookie or parameter. After that we get this interesting bit:

3rd step level of encod… err, encryption :)

dissecting-malware-final-step
Here we get a new function called ‘decrypt’. I wonder what it does :)

After a bit of studying we realized that this is a XOR deciphering function. Cryptography all the way! The challenge is in order to decipher the malicious content, we needed a key. We could use frequency analysis and some other techniques to find the key but there must be an easier way. I’m not an expert at cryptography so it would take too much time.

A quick Google search of the part of function and tada!!! We found a post on HackerNews that tells us the password. After using the password, we get the really malicious content:

Malware Payload

Malware Payload 2

So what does it do? It enables you to download any file from the internet and save it on the server where this malicious script resides. Besides that, it can be also used to run linux commands on the server.

Notice that the command is saved in a cookie/parameter named just like our XOR cipher password.

Convenient, right?

Scan your website for free:
  • dec0der

    These malware writers are getting slick, but not slick enough :)