Using NodeJS To Deobfuscate Malicious JavaScript


A group of analysts in the office are spending some time reverse engineering an Angler sample found at The website shows a screen capture of the malicious javascript that was injected into a page served by a compromised website. I had recently started using Node JS to try to setup some test suites for some client scripts and started wondering if this might be useful for deobfuscating malicious JavaScript.

Before describing the steps I took to deobfuscate the malicious script, a word of warning. When you run a Node JS application, you’re no longer running an application in a web browser environment. It is just like any other command line application. Since there are Node modules that can be used to access files on your computer and perform network communications, you may accidentally damage your own files or attack other computers by running the script. So, I always use a virtual machine on a host only network when analyzing the malicious code. Since we’re only interested in deobfuscating the malicious script, there is no need to try to observe what the script will actually do once it has been deobfuscated.

Virtual Environment

I have Node JS installed on an Ubuntu virtual machine. I also have the python js-beautify package installed. The js-beautify script will parse a javascript file that is combined into a single line, and create a line-by-line, indented representation of the script. The only way to set a breakpoint in the Node JS debugger is by line number, so if you want to step through the code line by line, parsing the obfuscated single line script into a multiline script will be very helpful.


The first step is to extract the javascript from between the script tags. A screenshot of the original, obfuscated code is shown in the figure below. The code that was extracted is highlighted. The code was copied into a file called minified.js.

Original obfuscated javascript, including tags

Original obfuscated javascript, including tags

Next, the command shown below was used to parse the single line into a multiline script:

js-beautify minified.js > obfuscated.js

The contents of obfuscated.js are shown below.

Malicious javascript parsed into multiline script

Malicious javascript parsed into multiline script

Next, there is a nested function call on line 8 of the script. Since a nested function call is equivalent to multiple function calls on a single line, you may have problems single-stepping through this line in a debugger. The easiest way to unnest the calls is to assign the return value of the inner eval() function to a variable. The variable can then be passed to the second eval() function.

But, what are the two eval() function calls doing? The inner eval() function call is probably deobfuscating the weird looking long string stored in the variable fnefybka on line 3 of the script. Once the inner eval() deobfuscates this string, the outer eval() is going to execute the deobfuscated string as if it were a piece of javascript.

So, to prevent the malicious code from being executed, I replaced the outer eval() function call with a call to console.log(). The edited script is shown below:

Unnesting the calls to eval()

Unnesting the calls to eval()

At this point, I ran the command shown below to output the contents of the deobfuscated string variable to a file:

nodejs obfuscated.js > deobfuscated.js

Deobfuscated string variable

Deobfuscated string variable

The contents of deobfuscated.js are also on a single line, so its a little hard to tell what’s going on. Once again, we can use the js-beautify command to fix this:

js-beautify deobfuscated.js > pretty.js

Deobfuscated multiline script

Deobfuscated multiline script

The screenshot above shows a multiline script that is now much easier to decipher. We can see an iframe with a URL that contains the word “helloresearcher” being inserted into the document towards the end of the script. The “helloresearcher” string is shown in a pcap at the Malware Analysis Traffic link in the introduction to this post.

Debugging With Node JS

In the section above, we used Node JS to execute the obfuscated java script after we made some edits to the script. However, if you would like to step through the script one line at a time, you can use the Node JS debugger to do so. The debugger can also be used to examine the values stored in different variables in the script as you are stepping through the script. To use the debugger, add the line debugger; at the point where you would like to pause execution in the script:

debugger statement added to pause script execution

debugger statement added to pause script execution

Next, type the following command to debug the script:

nodejs debug obfuscated.js

At this point you should see a debug> prompt, as well as a few lines from the script. Type c to continue executing the script, and execution should pause at the debugger statement.

Node JS paused at debugger statement

Node JS paused at debugger statement

Suppose I’m interested in the value of the zeeeafkz variable at this point in the script. We can use the debugger to display the value. The Node JS debugger is a little odd in that you can step through the script one line at a time by entering commands at the debug prompt. But, you need to open another shell within the debugger to view variables. To open the second shell, type repl. Once we’re in the repl shell, we can use the console.log() function to display the contents of the variable as shown below.   

Displaying a variable's value in the Node JS debugger

Displaying a variable’s value in the Node JS debugger

The for loop has somehow transformed the lengthy string stored in the variable fnefybka into a string that is now a list of integers. The remainder of the script finishes transforming this data into a string that can be fed to eval().

To exit the repl shell, type Ctrl + C, and you will be returned to the debugger shell. This should return you to the debug prompt, where you can start stepping through the script. Documentation for the Node debugger is available here.



Tagged with: , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *