Evading AV with JavaScript Obfuscation


Few days ago, Cybaze-Yoroi ZLAB researchers spotted a suspicious JavaScript file needing further attention: it leveraged several techniques in order to evade all AV detection and no one of the fifty-eight antivirus solution hosted on the notorious VirusTotal platform detected it. For this reason, we decided to dissect it and investigate what kind of tricks the malware used to achieve such result.

Figure 1: Javascript dropper AV detection at 2019-03-01

Technical analysis

The file is written in JavaScript language and it’s natively runnable by the Windows Script Host system component, its size is quite larger than common script files, about 1 MB of random looking text.

Hash (Sha256)99b0b24dcfb29291163b66c60355b6e1454c6a3d5dfbc2cd7b86b1ca548761eb

Table 1: Information about Javascript dropper.

The first look at this file reveal a first interesting characteristic: the usage of non ASCII charsets all along the body of the script.

Figure 2: Javascript dropper structure

These characters seem to be typed down without any apparent logic, but, a closer look reveals the first technique used by the malware writer. He declared all the variables using long strings combining a mixture of ASCII and UNICODE characters, even including some characters from the Cyrillic alphabet:


Figure 3: combination of ASCII and UNICODE characters

The difference among all the variables is visible only in the final part of those declarations after “_” char. So, we can say that the malware writers uses a common prefix for all the variables’ declarations. In the script previously shown in Figure 2, the final part of the variable is declared in the following way:

var = […]_0x5e24

Figure 4: different part in the defined variables

So the first step to de-obfuscate this code is to replace that prefix with other ones which allow the readability of the code. The result is:

var A_0x5e24=[‘fromCharCode’,’function\x20H2B([string]$s){$H=@();for\x20($i=0;$i\x20-lt\x20$s.Length;$i+=2){$H+=[Byte]::Parse($s.Substring($i,2),[System.Globalization.NumberStyles]::HexNumber);};return\x20$H;};$_b=(get-itemproperty\x20-path\x20\x27HKCU:\x5cSOFTWARE\x5cMicrosoft\x5cRun\x27\x20-name\x20\x27Microsoft\x27).Microsoft;

Figure 5: first deobfuscation level

Other obfuscation technique found during the analysis is the combination of ascii and hexadecimal character as visible in the script above. It is possible see different hexadecimal char encoding like:


Figure 6: hexadecimal character used in script of javascript

Replacing these hex represented chars with their ascii encoding end up this way:

0x27 → ‘
0x20 → empty space
0x5c → \

Figure 7: conversion from hexadecimal to ascii characters

After this de-obfuscation step, the script results in:

A_0x5e24=[‘fromCharCode’,’function H2B([string]$s){$H=@();for ($i=0;$i -lt $s.Length;$i+=2){$H+=[Byte]::Parse($s.Substring($i,2),[System.Globalization.NumberStyles]::HexNumber);};return $H;};$_b=(get-itemproperty -path ‘HKCU:\SOFTWARE\Microsoft\Run’ -name ‘Microsoft’).Microsoft;

Figure 8: second deobfuscation level

The backslash char before every hexadecimal char is necessary to combine hex with ascii encoding. Now we are able to see the clear code and initial part of executable hidden in the javascript dropper even if it not seems to be well defined. Inside of it, indeed, are present ‘$’ chars and these are not permitted in hexadecimal encoding.

Figure 9: First part of executable in javascript

The first line of the above code replaces all ‘$’ chars contained in _b variable with ‘5’ char. Performing this action manually, it is possible to obtain a well formed Portable Executable, representing the final payload detoned on victim machine after the infection.

Figure 10: Part of executable after replacing  $ with 5 character

The first four char, as we can see, are “4D5A”, magic numbers of the Executable files in Microsoft Windows environments. Once decoded, the payload is written down to the following registry key in order to allow its persistence on every reboot.


Figure 11: registry key used to grant persistence

The extracted executable is widely identified by most of the AV solutions enumerated into the VirusTotal platform.

Figure 12: payload inside of JavaScript dropper AV detection at 2019-02-28

The binary is a variant of a well known Remote Access Trojan abused by several cyber-criminals, a “RevengeRAT” configured to with the following command and control server:


Figure 13: Command and Control contacted by malware


The analysis of this malicious JS script brings a significant evidence about how threat actors are able to easily hide malware to the eyes of anti-virus technologies, even if belonging to widely known families such as RevengeRAT. A few manipulations of the dropper code are enough to ensure a zero detection rate.

Also, another aspects of this case need attention. Even after several days from its discovery, and its subsequent sample submission on the VirusTotal platform on 28th February 2019, only two AV solutions result to be able to correctly identify this file, a performance confirming modern threats could not be tackled with a single, automated tool.

Figure 14: JavaScript dropper AV detection at 2019-03-04

This blog post was authored by Davide Testa, Luigi Martire and Luca Mella of Cybaze-Yoroi Z-LAB