Deobfuscating a JavaScript exploit

Recently, one of our partners sent us an interesting piece of obfuscated JavaScript code that was used to run ads on their network. As it turned out, the code was malicious in nature, and in the present article I would like to analyze it and show how obfuscated JavaScript code can reverse engineered.

The following screenshot shows the code that we received:

In the above screenshot, there are two URLs that are readily identifiable (masked for this public release to preserve confidentiality of the affected party). The one used in the land variable is a tracker used to monitors a brand’s performance. The other one is embedded in the final part of code. This final part gave an impression to be garbage, for the exception of some artifacts (like the URL and JavaScript code).

As can be observed, the encoded text on line 58 is stored as a string and is passed as a parameter to what appears to be the decoding function defined on line 3. The decoded output is executed with the eval() call on line 2.

The eval() call will evaluate whatever is returned by the function that is defined inside the call. The function returns the decoded string on line 57. This is where we can intercept the execution flow and have a look at what is to be evaluated after the decoding function. We simply replace the return call with console.log(), save and run the script. Now we will see the decoded code printed out to console. Checking the console, I got the following output:

More obfuscated code! Analyzing we can see that _$_f4ea is an array of string values that appear to be JavaScript. The rest of the code selectively picks values from _$_f4ea and merges them into a coherent set of instructions. This time it’s not possible to get the decoded code by simply running the decoder function and printing out the result. Reversing this part will require manual substitution of values from the array. By using a JavaScript interpreter, it’s possible to semi-automate the process to get values from the _$_f4ea array, and then merge them together manually.

The final result looks, like this:

Now we can see a clear picture of what is really going on. Lets quickly review it line by line.

The first two lines define the iframe variable and the inCode that will later be injected into the URL that was previously identified. Lines 4-10 set iframe parameters and append it to the HTML document. Here we can see that inCode is injected into the css parameter in the URL passed to f.src. Upon further investigation it became evident that this website is suffering from an HTML injection vulnerability that allows malicious actors to inject arbitrary code, and more importantly have HTTP requests appear as if coming from the website itself. This is the core of the exploit. The vulnerable website is hosted in Spain. The attackers were routing all their ad traffic though this vulnerable website, thereby converting all their traffic to Spanish traffic, and finally sending it to the ad tracker that we previously identified.

It appears that the purpose of this exploit was to illegitimately augment Spanish traffic volume and get higher payouts by country. This of course led to the campaign being banned on our partner’s network.

Recommended Posts