Pages

Sunday, 22 March 2015

Data Obfuscation: Now you see me... Now you don't...

Introduction

This blog post shows how malware authors use Adobe Flash files to hide their creations' 'sensitive' data. I'll be using 2 recent Neutrino EK and 1 FlashPack malvertising samples to demonstrate it. In the case of Neutrino EK our goal will be extraction and decryption of its configuration file and in the malvertising case we'll be after the initial payload URL + exploit shellcode.

Let's start with the GIF file and try to manually reconstruct it. After unescaping and base64 decoding it, we ended up with a chunk of binary data that's anything, but a GIF file. So, it has to mean something else. Note that the <img> tag has 'id' parameter - 'mqdscriyolhypdbstnmv'. There is no reference to it on the landing page, so quite possible it's being used by the SWF file. After some reverse engineering 'kung-fu' and ActionScript review we come across the function below:

So, we have already completed 'unescape' and 'base64 decode' operations, all we're missing now is the RC4 decryption pass for which we need to know the key. The routine above tells us to look for it in 'getRtConfigKey()' function. Let's take a look there.

Alright, we got the key. Now let's find out what happens if we decrypt our data chunk with it.

Neutrino EK Dec 2014 sample - decrypted configuration file

There we go. The configuration file.

Just to make it a bit clearer why there are many initial payload URLs, let's take a look at the SWF file structure

Neutrino EK Dec 2014 sample - decrypted SWF structure

Take a look at the content of the 'exploit' folder in the screenshot above and note the 5 ActionScript filenames. Each of those scripts contains a routine that decrypts and launches an exploit code for some vulnerability. Now take a look at the tag names for each URL in the configuration file. Besides the first two, the rest of the names match the names of the ActionScripts. So, it appears that each exploit code has a unique URL associated with it to download the initial payload.

Focused deception.

The Neutrino EK sample analysed in this section was captured in Mar 2015. The landing page of this sample no longer has an <img> element with encoded data. In fact, it has nothing except the code requesting an SWF file.

Neutrino EK Mar 2015 sample - landing page

Into ActionScript code we descend again... until we reach a function that 'coincidentally' has the same name as in Dec 2014 sample - 'decodeRtConfig()'

Neutrino EK Mar 2015 sample - the configuration file decoding routine

As expected, there is no code interacting with any data outside of the SWF file, but instead there is a routine that performs some data manipulations with a binary data stored in one of the SWF binary data containers. Let's see what it does:

So, simply put, there is a chunk of data that we need to read just a part of and run it through RC4 decryption routine. Now we need to find out how much data we need to read and what the decryption key is. The key is not a problem at all since it can be found in the ActionScript code.

Neutrino EK Mar 2015 sample - the configuration file decryption key

For the Integer value of bytes to read we'll have to do some maths magic which will convert the first 3 bytes (0x36 0x32 0x65) into *drums roll*... 1582. Right, now we know how much data to read and the key to decrypt it.

Neutrino EK Mar 2015 sample - decrypted configuration file

And that's how we deal with this type of data hiding technique.

But deception meant to entertain.

At the beginning of February 2015 a FlashPack malvertising campaign was making rounds dropping CryptoWall malware.The scheme was rather interesting:

browser opens a webpage that requests some advertisement content from an ad TDS

In a nutshell, there are 2 embedded SWF files each occupying a binary data container. One of them contains some legitimate advertisement content and the other one an exploit code for CVE-2014-0569. Let's examine the later one closer.

FlashPack malvertising Feb 2015 sample - initialization routine

After some environment checks, the execution comes to an interesting chain of events(last 2 lines of code in the screenshot above).

function 'images' is called with one argument passed to it

the returned value from 'images' is passed to 'decodeurl' function

the returned value from 'decodeurl' is passed to 'hex2bin' function

the returned value from 'hex2bin' is split at '&' character

Judging by the function names, we can assume that by passing some data stored in 'var_29' to 'images' function we will end up with 2 pieces of data on 'hex2bin' return - one presumably some URL and the other one unknown yet. So, let's find out what 'var_29' is.

'var_29' is assigned 'class_7' object. So, what is this object...

Ok, 'class_7' appears to be a 'BitmapAsset', but which one...

Alright, 'var_29' is actually an image file stored in SWF file. Now, let's find out what happens to it when it's passed to 'images' function.

FlashPack malvertising Feb 2015 sample - 'images' function

The function is performing the following:

extracts image's bitmap data

identifies the number of pixel rows

reads pixel values one by one from each identified row

converts pixels value to a character and adds to a string

Simple enough operation, but let's find out what happens with the resulting string in the 'decodeurl' function.

FlashPack malvertising Feb 2015 sample - 'decodeurl' function

This function is performing the following:

loops through the string received from 'images' function character by character

find position of each character in a predefined string - '_loc3_'

takes a character in the same position, but from a different string - '_loc2_'

adds this character to a new string - '_loc4_'

The result of 'decodeurl' function is expected to be a string of 'hex' values. So, let's see what happens during the final transformation of what used to be an image file before.

FlashPack malvertising Feb 2015 sample - 'hex2bin' function

'hex2bin' function is indeed expecting a string of 'hex' values that it will loop through reading two characters at the time, convert each pair to a character and add that character to a string.

Our assumption was that at the end of the chained function calls we will have a string that can be broken in 2 at '&' character resulting in a URL and something else. Indeed we've got a URL and this something else turned out to be a part of the exploit shellcode.