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.
It's fair to say that the exploit kit world is spinning around Adobe Flash files lately. ActionScript scripting language that drives SWF files execution is quite versatile and when combined with other SWF features, like, binary data containers or images embedding creates a strong application environment capable of executing relatively complex tasks. Some exploit kit authors already using SWF files to be all-in-one 'solution'. For example, Neutrino EK(aka Job314, aka Alter EK) uses Adobe Flash Player files to store exploits code, execution control logic(environment checks, exploit code selection, etc.), decryption keys for its various components and the configuration file. SWF file obfuscation applications further enhance data hiding capabilities and also drastically impede reverse engineering efforts making SWF files even more attractive to malware authors. The SWF files analysis below demonstrates how ActionScript combined with base64 encoding, RC4 encryption and image files can be used to hide the data.
What is magic?
The Neutrino EK sample analysed in this section was captured in Dec 2014. Its relatively simple landing page contains a request for an SWF file and what appears to be a base64 encoded GIF file.
Neutrino EK Dec 2014 sample - base64 encoded GIF stored on the landing page
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:
Neutrino EK Dec 2014 sample - AS3 function to decode data stored in 'mqdscriyolhypdbstnmv' landing page element
The function appears to do the following:
- splits the pulled content at 'base64,' expression creating 2 data chunks
- unescapes and base64 decodes the 'second' chunk
- runs the resulting data through RC4 decryption routine
Neutrino EK Dec 2014 sample - the configuration file RC4 decryption key
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.
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:
- loads data from a binary data container
- reads first 3 bytes and converts them into an Integer with radix 16
- continues reading the data until bytes count reaches the Integer value
- runs the read data through RC4 decryption routine
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
- TDS points the browser to an SWF file hosted on RackSpace CDN
- browser starts showing the advertisement content that looks absolutely legit
- 6 minutes later SWF generates a request to download CryptoWall malware
FlashPack malvertising Feb 2015 sample - SWF with 'bonus scenes'
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
- 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.
Exactly my feeling after analyzing this sample
Ok, now let's do the same thing in Python and see what happens.
FlashPack malvertising Feb 2015 sample - part of decoded PNG file content
'The operation was a complete success!' (c) Dr. Nick Riviera(The Simpsons)
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.
That's all for now, folks!
@kafeine - invaluable intelligence sharing
@TimoHirvonen - tremendous help with reverse engineering SWF files
Sulo - https://github.com/F-Secure/Sulo
JPEXS Free Flash Decompiler - https://www.free-decompiler.com/flash/
Kahu Security Converter Tool - http://www.kahusecurity.com/tools/
JetBrains PyCharm - https://www.jetbrains.com/pycharm/
Notepad++ - http://notepad-plus-plus.org/