Pages

Tuesday 23 September 2014

Deobfuscation tips: Nuclear EK landing page

DISCLAIMER: There isn't a single way to deal with obfuscated data/code. There are many automated and semi-automated tools available to help you with that. In this post though I'll be using none. The aim here is to walk through some code deobfuscation manually. This is not a comprehensive Nuclear EK landing page analysis. Only bits related to data/code obfuscation are covered.

NOTE: Exploit Kit sample used in this post was captured in September 2014. Taking the ever changing nature of EKs, the described below might not be applicable to the newer variants.

'Nuclear launch detected'

I'll be using Nuclear EK landing page sample here. Note a huge blob of numbers stored in 'G4Ah' variable and a string stored in 'qjv' variable. The string serves as a lookup key and the numbers blob is actually a sequence of 2 digit numbers that are used to find a character in 'lookup key' at the position = 2 digits value. The JavaScript on the landing page does quite a simple job - it splits the blob into 2 digits chunks, loops through each chunk value to find the corresponding character in the 'lookup key' and adds the found character to a string. This might sound a bit confusing, so let's translate it into a Python script to better understand it.

lookupKey = "LOOKUP_KEY_GOES_HERE"
encodedString = "NUMBERS_BLOB_GOES_HERE"
listOfValues = map(''.join, zip(*[iter(encodedString)]*2))
decodedString = ""

for index in range(len(listOfValues)):
    if int(listOfValues[index]) < 10:
        element = int(listOfValues[index])
    else:
        element = int(listOfValues[index]) - 2
    decodedElement = lookupKey[element]
    decodedString += decodedElement

print(decodedString)

You'll notice an 'if' condition in the 'lookup' loop - for any value greater than 10 subtract 2 from it and then perform the lookup. This is done to compensate for the escape '\' characters in the lookup key. I'm not entirely sure why '10', but assume the code logic that generates the key will not include characters that require escaping into the first 10 character positions of the key.

Before we can run the script we need to put the values into 'lookupKey' and 'encodedString'. Where the value for 'encodedString' is hard to miss in the landing page code, the value for 'lookupKey' might be challenging. From my personal experience with Nuclear EK landings, I found that the characters positions in the key are random, but its size is always 95 characters. The simplest, but not always reliable way to find the lookup key is to search for a variable assigned a long string value. If this method fails you'll have to follow the JavaScript code to find it.

Now, if we use the corresponding values from our landing page sample and run the script, we get the following output.

Another KISS approach to data obfuscation. Happy deobfuscation!


Thursday 18 September 2014

Deobfuscation tips: SweetOrange EK landing page

DISCLAIMER: There isn't a single way to deal with obfuscated data/code. There are many automated and semi-automated tools available to help you with that. In this post though I'll be using none. The aim here is to walk through some code deobfuscation manually.This is not a comprehensive SweetOrange EK landing page analysis. Only bits related to data/code obfuscation are covered.

NOTE: Exploit Kit sample used in this post was captured in September 2014. Taking the ever changing nature of EKs, the described below might not be applicable to the newer variants.

Sweet and Sour

I'll be using SweetOrange EK landing page sample here. Note a huge blob of text stored in one of the list items '<li>' followed by some JavaScript code. We'll skip the general code analysis/overview and focus on the tag. It has 'id' attribute with a rather unique value - 'UHOhpWHd'. Searching for this value in the webpage code leads to the following JS function:

function uQqRecfwwf(DDDDDDDDD) {
    TLKQDEnOiE = 0;
    var ARNTO = uQqRecfwwf;
    var DnB = 0;
    UhOnd = String(Math.asin);
    if (isNaN(UhOnd.match(/aSI/ig))) {
        var k = (UhOnd.match(/In/i));
        if (k != null) {
            iuhquweh = trenoSZ(uyHMzLQ);
            XdwrQ["spl" + "ice"](Math.acos(1), 2, "UHOhpWHd");
            XdwrQ["spl" + "ice"](1, Math.acos(1), iuhquweh);
            ardddds = DDDDDDDDD;
            DnB = cXEcJlM()[qqTbFg()];
        };
    };
    return DnB;
}

At this stage it's unclear what exactly happens to the blob's data rather then being stored in 'XdwrQ' array. Before we start chasing the rabbit down the rabbit's hole and submerge into other functions, let's find out what calls 'uQqRecfwwf' function.

aCaBOUakjB = uQqRecfwwf(BFG423SDFFSDF);

Ok, it's being called during a variable initialization. Are there any operations on this variable after the function call returns?

JvUhBCJkFV = aCaBOUakjB.substring(Math.acos(1) + 70).replace(/AdgSf344_42/, "");

The value returned is passed through '.replace' where any occurrence of 'AdgSf344_42' string is removed and then '.substring' cuts off first 70 characters and what's left is stored in another variable called - 'JvUhBCJkFV'. Note the string that's being removed - 'AdgSf344_42'. This string is repeatedly present all over the data blob, so it's safe enough to assume that these 'replace' and 'substring' operations are performed on the data stored in the blob. Now let's trace 'JvUhBCJkFV' variable.

JvUhBCJkFV = JvUhBCJkFV["CmYhLBWtlcUAuPllrQzwcR".charAt((Math.acos(1) + 1) * 21).toString().toLowerCase() + "QeTyvpnauVDwgPrSyUmddePl".substr((Math.acos(1) + 1) * 21, 3).toLowerCase() + "hSReqJbsEYDVGYtSdMaKvAce".toLowerCase().substr((Math.acos(1) + 1) * 21, 3)](/__hhg7_/, "<");
JvUhBCJkFV = JvUhBCJkFV["DFhBbAbrvTfutCnsmdcFnR".charAt((Math.acos(1) + 1) * 21).toString().toLowerCase() + "pxUBkDdBwEcWypAIICsrJePl".substr((Math.acos(1) + 1) * 21, 3).toLowerCase() + "mVrJDwMWDZuUhgpMZSmVEAce".toLowerCase().substr((Math.acos(1) + 1) * 21, 3)](/__Db8__/, ">");
JvUhBCJkFV = JvUhBCJkFV["QOmUjeNOFcQYONcLQZAtOR".charAt((Math.acos(1) + 1) * 21).toString().toLowerCase() + "bWXExXVfqvcqeIuyNfJaRePl".substr((Math.acos(1) + 1) * 21, 3).toLowerCase() + "iebFbNjCVybBwfEvorJqqAce".toLowerCase().substr((Math.acos(1) + 1) * 21, 3)](/_uio0__/, "&");
JvUhBCJkFV = JvUhBCJkFV["oZBZyFhKBOkJHNmWnmNCKR".charAt((Math.acos(1) + 1) * 21).toString().toLowerCase() + "PIPoCStPfHZIWGgmYzekFePl".substr((Math.acos(1) + 1) * 21, 3).toLowerCase() + "gfAOlzFwZvghrQYqhRPhnAce".toLowerCase().substr((Math.acos(1) + 1) * 21, 3)](/__cc0__/, "%");

This is a little bit hard to read, isn't it? This is another type of code obfuscation used in this sample. Thought it's not something I want to cover in this post, let's deobfuscate it for the sake of easiness. Simply taking the code enclosed into square brackets and evaluating it using a JS sandbox yields the code below.

JvUhBCJkFV = JvUhBCJkFV.replace(/__hhg7_/, "<");
JvUhBCJkFV = JvUhBCJkFV.replace(/__Db8__/, ">");
JvUhBCJkFV = JvUhBCJkFV.replace(/_uio0__/, "&");
JvUhBCJkFV = JvUhBCJkFV.replace(/__cc0__/, "%");

More replacements!! Ok, let's do all of the above replacements and see if we get some readable code. The following simple Python script will help us do it:
 
def readFile(filename):
    fo = open(filename, "rb")
    textFile = fo.read()
    fo.close()
    return textFile

encodedString = readFile('SW_landing.txt')
encodedString = encodedString[70:]
encodedString = encodedString.replace('AdgSf344_42', '')
encodedString = encodedString.replace('__hhg7_', '<')
encodedString = encodedString.replace('__Db8__', '>')
encodedString = encodedString.replace('_uio0__', '&')
encodedString = encodedString.replace('__cc0__', '%')

print(encodedString)

Before running it, we'll need to save the data blob into 'SW_landing.txt' file and place it in the same folder with the Python script. If you ever need to deobfuscate another SweetOrange EK landing page using this script, keep in mind that the replacement strings can change, though so far I've only seen '.substring' value and the first replacement string changing.

After running the script we get the output. With the exception to some base64 encoded strings, the code is pretty readable and can be analyzed further if required. Now let's sum things up a little bit.

So, from the data/code obfuscation perspective SweetOrange EK landing page contains a relatively big blob of obfuscated data and a JavaScript to deobfuscate it into yet another JavaScript. The deobfuscation is implemented through a series of simple replacement operations. KISS.


Happy deobfuscation!