FortiGuard Labs Threat Analysis Affected Platforms: Windows

Impacted Users: Any Windows users

Threat Severity: High – allows the attacker to gain remote access. Recently, FortiGuard Labs, leveraging the FortiEDR endpoint protection platform, detected and blocked a new and highly obfuscated malicious malware in a large OT environment. This newly discovered JavaScript-based Remote Access Trojan (RAT) and cryptocurrency stealer, which we have dubbed “ViperSoftX” (due to a hardcoded string used by its creator), became notably active towards the end of 2019, and remains so as of the time of this writing. In this blog post we will analyze the tactics, techniques, and procedures (TTPs) used by this new discovered threat along with details on the campaign we uncovered that uses this new malware.

Obfuscation ViperSoftX unravels 8 layers of code obfuscation before executing its actual payload. There are 3 different types of obfuscation techniques being employed: AES Decryption: This is only used in the first layer. The author copy-pasted chunks of code that implements the AES algorithm from the widely used CryptoJS library. Every sample has a different hardcoded AES key. Converting Char Arrays: This method executes only once as well, usually at the third layer, and has the simple functionality of evaluating a hardcoded array of characters. UTF8 Decoding: This method is the most recurring deobfuscation layer. It contains code snippets most likely copied from the online Web Toolkit to perform UTF-8 decoding. Another effective method used to thwart the analysis of this malware is appending a non-ascii character at the end of the script, which results in encoding exceptions in most of the existing debuggers and basic deobfuscation methods. Persistency ViperSoftX starts by placing a copy of itself under %APPDATA%. The author attempts to disguise the malicious script by using seemingly legitimate names such as vpn_port.dll, reg.converter.sys, install.sig, and install.db. To establish persistency, the malware drops another script file under %APPDATA% and creates a shortcut in the startup directory to invoke it. The dropped script is a VBScript file, which in turn, executes ViperSoftX:

Set WshShell = WScript.CreateObject(“””WScript.Shell”””) Obj = WshShell.Run(“””wscript.exe /E:jscript “””[PATH TO THE JS FILE]””” Set WshShell = Nothing Figure 1: Dropped VBScript

RAT Functionality After establishing persistency, ViperSoftX queries the C&C server to fetch a command for execution. It does so in an infinite loop, and following each command execution it sleeps for 3 seconds. The requests are sent in plain-text via HTTP PUT request to hxxp://seko[.]vipers[.]pw:8880/connect.

Figure 2: Typical HTTP Request

ViperSoftX uses HTTP headers to pass the machine information to the C&C server. The X-Header field (a non-standard header) is set to the hardcoded version and the User-Agent header is set to the machine information that includes:

The hardcoded version + “_” + includes the serial number of the machine, which is obtained using WMI’s win32_logicaldisk class and then extracting the VolumeSerialNumber.

class and then extracting the The ComputerName – an environment variable.

– an environment variable. The UserName – an environment variable.

– an environment variable. The operating system version from the Caption property of WMI’s win32_operatingsystem class.

property of WMI’s class. The CPU architecture from the AddressWidth property of WMI’s win32_processor class instance of ‘cpu0’.

property of WMI’s class instance of ‘cpu0’. Installed Anti-Virus information obtained by querying WMI’s instances of the AntiVirusProduct class in the SecurityCenter and SecurityCenter2 namespaces.

class in the and namespaces. A boolean flag indicating whether Microsoft.NET\\Framework\\v2.0.50727\\vbc.exe exists on the machine. The hardcoded version string format is as follows: Vress = “viperSoftx_x.x.x.x” There are no differences between files with different versions. Since the version is being sent to the server, we assume it might act as tag for different operations or campaigns being carried out. The response received from the server is a string that is split into an array, which represents the command to be executed. Currently, the following commands implemented by ViperSoftX are:

Name Description Parameters Ex Executes JS code using eval(). 1. JavaScript code Cmd Runs a command through cmd.exe. 1. Command line DwnlExe Runs a PowerShell script that downloads an additional file to a specified location under %TEMP%, sleeps for 20 seconds, and then executes the downloaded payload. 1. URL to download the file from 2. Path to save the file to DwnlOnly Downloads a file to predefined folders. Optionally, despite the name of the command, it executea the downloaded payload, like DwnlExe. 1. URL from which to download the file 2. Name to save the file as. It is appended to the predefined folder path 3. Predefined destination folder: Startup, Temp, or Desktop 4. Boolean flag that indicates whether to also execute the file SelfRemove Executes PowerShell one liners to delete the script from %APPDATA%, the VBScript and shortcut in the startup directory. UpdateS Removes all persistence for the current version and executes the new downloaded JS file. 1. URL to download the file from 2. Path to save the file to

The output of the commands executed on the victim machines are not being returned to the server. It’s interesting to note that the Ex command indicates that the malware author aimed to continue operating with additional JavaScript-based payloads. This indicates that the developer feels more comfortable using JavaScript as his “go-to” programming language. During our research, we also noticed that the X-Powered-By header in the response was “Express”. This serves as another indication of the author’s affection for JavaScript since it suggests the server was built using the widely popular Express framework for NodeJS. Replacing Crypto Wallets One of the goals of ViperSoftX is to steal cryptocurrency. Thus, after every command execution, ViperSoftX checks the content of the clipboard using the following code:

WScript.CreateObject(“htmlfile”).parentWindow.clipboardData.getData(“text”)

It then checks to see if the content matches either of two regex patterns that aim to match either a Bitcoin or an Ethereum address. In case of a match, and if the addresses are different from the addresses hardcoded in ViperSoftX, it sets the clipboard data to its own addresses. Changing the clipboard data is done based on the OS version. On Windows 10 it uses PowerShell’s scp. Otherwise, it runs cmd as follows:

Cmd.exe /c echo|set /p=[address to set]|clip

After examining ViperSoftX’s Bitcoin and Ethereum addresses hardcoded in the malware, we can conclude the following: There’s a matching BCH address that had only 1 transaction on 2020-01-17. This address holds a total sum of 1.00962178 BCH, which is worth 379.51 USD.

There’s a matching BTC address that has had 125 transactions, the most recent of which occurred on 2020-01-17, while the earliest occurred on 2019-06-20. The total balance of the wallet is 3.37562306 BTC, which translates to 31,085.29 USD.

transactions, the most recent of which occurred on 2020-01-17, while the earliest occurred on 2019-06-20. The total balance of the wallet is 3.37562306 BTC, which translates to 31,085.29 USD. The matching Ethereum address holds a total sum of 7. 436753340964695808 Ether, which is worth 1,394.18 USD. The current total sum of all of the above mentioned wallets stands at 32,858.98 USD. While this is not a significant amount, this is only one campaign of this newly discovered threat which has only operated for a short while, and may only be the start of bigger, more successful campaigns. Also, as this threat has RAT capabilities, we don’t know if this was the only goal of the threat actor. For example, the threat actor might also be selling stolen data.

The following Ethereum activity graphs also indicate the campaign’s activity phases and reflect the steady growth of activity of ViperSoftX since late 2019, along with a stable increase of revenue since the first time it was detected in the wild:

Figure 3: Ethereum Balance Graph showing growth over time