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, as shown below. 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 detected it dropping both RevengeRAT and WSHRAT.
First Stage – Launcher/Dropper
The objectives of the VBScript code are as follows:
- Create a new Shell.Application object
- Call the ShellExecute() function, which eventually generates a new file with the hardcoded filename of “A6p.vbs”
- Execute the newly-created script file “A6p.vbs”
- Pause the CMD command execution for 13 seconds (by calling the timeout.exe program)
- Delete the script file “A6p.vbs”
- Execute the downloaded script file “Microsoft.vbs”
- Close the current/active window
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.
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.
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.
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.
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 (HKCUMicrosoft SoftwareMicrosoft) 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”.
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.
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 “220.127.116.11” and “18.104.22.168”. 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:
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 “127.0.0.1” at the moment it connected.
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.
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.
- “10.0.2.15” 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(this, null, “Send”, new object
ect(Operators.ConcatenateObject(“Information” + Atomic.Key + this.ID + Atomic.Key, this.Encode(“_” + t
his.HWD())), Atomic.Key), this.IP()), Atomic.Key), this.Encode(Environment.MachineName + ” / “ + Enviro
nment.UserName)), Atomic.Key), this.CIVC()), Atomic.Key), this.Encode(Atomic.DI.OSFullName + ” “ + Ato
Command & Control
In the .Net code we found a thread function called this.data(), 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().
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.
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.
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.
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%MicrosoftWindowsStart MenuProgramsStartup”) folder.
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.
Read about the FortiGuard Security Rating Service, which provides security audits and best practices.