VBScript has been regularly used to download or execute malware since a long time. Recently we came across one such malware written in VBScript that uses some innovative functionalities to assess the environment in which the malware was run. As VBScript is generally integrated into the OS by design, the use of a small combination of VB commands to perform bigger malicious tasks can be considered as “living off the land”.
This VBScript was found in the wild, delivering the QakBot malware also known as “Qbot”, an information stealer. This VB scripting technique is part of a campaign which reportedly started in March 2020 and delivers Ursnif, Dridex and the ZLoader banking malware.
This malware usually spreads via emails with zipped attachments containing the malicious VBScript. The peculiar thing about this VBScript is that, only after the successful validation of the environment for more than 8 rules, does it decrypt its malicious code. This is to restrict the malware from running under Sandboxes or automations used by AV companies.
Analysis
Initially, when executing this script, it shows an error message every time as shown in Figure 1.
However, the network analyzing tools that we used, says otherwise. We wanted to know the reason for this, so without any further thoughts we started analyzing the VBScript further.
We started by removing a lot of comments and junk data and were left only with arrays and function code. Getting into the details – the Main Function is usually found by a single function name and executed with the keyword “ExecuteGlobal()”. But here in Figure 2, we see that there are multiple functions involved which need to be deobfuscated to find out what really happens beneath it.
Highlighted in the Figure are the names of functions which will be executed one by one in order after deobfuscation.
The deobfuscation was done using “CScript.exe” in PowerShell after replacing every instance of “ExecuteGlobal()” with “Wscript.Echo”.
This output also had junk codes and comments, which were removed.
The final code as shown in Figure 3 had some mathematical operations in it, which was there to evade debugging.
Figure 4 shows the output after overwriting the same with its deobfuscated content.
Now the remaining code has only functions that drop and execute the malicious file in the system after doing some logical checks. Let’s get into the details of the checks done one by one and we have also included some comments (displayed in green) in the Figures for your reference.
Sub Function 1 – Quitting Function
Before going to the Main function, let’s discuss one of the important functions, the “Quitting Function” which is used in most of the places in the script.
This function has 3 inner functions,
A. Connecting to a URL to report its execution
B. Self Deletion
C. Displaying an Error box and quitting thereafter
Let’s get into the details one by one
A. Connecting to a URL to Report its Execution
The function shown in Figure 6 is used to connect to the mentioned URL, which has been shortened using the “iplogger” url shortener. It does not expect any response, which means that it’s just a beacon alerting the attacker of the script’s execution.
B. Self Deletion
As the name indicates, this function deletes its own script.
C. Fake Error Message Box
This prints the fake message box that we have seen in “Figure 1” to make the user believe that something went wrong during execution.
Upon running the “Quitting Function”, the script connects to the URL, deletes the script, and prints an error message box, and quits.
Sub Function 2 – Checking the Name of the Downloaded File
This function checks if the file in the download location contains a file with name “390419094.txt” and assigns the value to the variable “oiztG” which will be used in the functions. We will refer to this function as “Sub Function 2”.
Sub Function 3 – Creating Objects under the Temp Folder
This function creates a folder in Temp location to write the files to. Now let’s do a deeper analysis of the main functions that were shown in “Figure 2”.
Function 1 – Check Script Name and Logical Drive Size
- The function checks if its own name is “390419094” and for “Sub Function 2”, and exits the function, if true.
- Else it gets the size of the Logical Disk by using “Win32_LogicalDisk” class and checks if it is less than 60GB.
- If the size is less than 60 GB then, the “Quitting Function” is executed.
Function 2 – Checking the Size of Primary Memory
- This function again checks for the script name and “Sub Function 2”, and exits the function if true.
- It also gets the size of primary memory by using the “Win32_ComputerSystem” class and checks if it is less than 1030MB. If the memory is below 1030 MB then it executes “Quitting Function” and quits.
Function 3 – Check Running Processes
- This is one of the important functions where it gets the name of all the current running processes by using “Win32_Process” class, and compares it with the list of process names that it already has. This list contains most of the applications that are used by researchers for analysis and it quits the script if it detects one.
- It also counts all the current running processes and the total process count must not be below 28, indicating that the process is running in a sandbox environment, as usually sandboxes run only system applications during analysis.
Function 4 – Check If Already Infected
- This function checks if the system is infected previously. An earlier campaign had an artifact of “Microsoft.url” as a shortcut created under “temp” directory. However, this time they created a shortcut named “adobe.com” – Probably for Identifying the campaign.
- If “Microsoft shortcut file” is found under “temp” directory, then the Fake Message Box is executed and it deletes itself and quits as the system is already infected. Else, “abobe.com” shortcut is created under “temp” location and it proceeds further.
Function 5 – Decoding Malicious Binary
If all of the above checks are done then the script starts to decode the binary encoded with “ISO-8859-1” and the payload is dropped at the temp location by the name “Aviv.zip”.
Function 6 – Extraction and Deletion of the Zip file
- The zip file is then extracted in the same location. The decoded binary contains 4 files within it, where one is the malicious DLL, and another 3 files are just junk files to hamper the analysis.
- The zip file is then deleted from the location.
Function 7 – Execution of Malicious DLL
Here, for the last time it checks if the script name is “TESTING” and if not, then another packet is sent to the same URL without expecting any response and the malware is executed, by using “DLLRegisterServer” with “rundll32.exe”.
Additional Variant
After this initial variant, new variants of VBScript have been found in the wild, which is the upgraded version of the script with more functions which checks for targeted environment and uses more Anti-Sandboxing techniques before decrypting the malware. Let’s analyse the functions now.
Function 8 – Compare the Number of Files in Temp and Downloads Location
- In this variant, the script checks if it is named “138874814”.
- It then proceeds to check the number of objects in Temp location and Downloads location. If the file count is greater than “3”, it runs the “HxOPuqip” function which is same as “Quitting Function” and quits.
Function 9 – Excluding Geolocation
From this variant, we can see that they are moving more towards excluding countries based on GEOID, which they acquire from the registry path “HKEY_CURRENT_USER\Control Panel\International\Geo\Nation”.
GEOID | Country |
203 | Russia |
131 | North Korea |
134 | South Korea |
244 | United States |
113 | India |
If the above locations are detected, the program quits without executing the malware.
Function 10 – Checks Number of Cores
This function uses the “Win32_Processor” class to get the number of cores present, and quits if it’s below “3” (Usually sandboxes have 1 or 2 cores).
Function 11 – Checks BootUpTime
This function gets the LastBootUpTime of the system and splits it as “-” and “:” and stores in the “epitaph” variable. It calculates the difference with the current time and checks if the boot time is below “0” hours and “10” minutes, then the script exits without proceeding further.
Comparison with Earlier Versions
Earlier versions of the script had limited functions, but that included a test which checks if “Ram Adapter (Video Memory)” is below 1500 MB. It did not have an “Quitting function” but rather it used a “sleep” function.
The Ram Adapter function is removed in this variant but codes of sleep function still remains as junk and is also not used anywhere in the functions.
Conclusion
Simple VBScript is being used to detect the execution environment before running the malicious code. The attacker can change the hash of the code just by adding comments or junk values or using random function names, thereby evading hash based detection. Obfuscation helps a lot in making it difficult for analysis and moreover more than 8 criteria are taken into account before executing the malware, which eventually ends up evading detection at one place or another when executed in a sandbox environment, thereby succeeding in its goal.
We at K7 have detection for all these variants. To ensure a safe digital environment, we request all the users to use a robust security product such as K7 Total Security for scanning your system and ensure you keep that updated to stay safe from the latest threats.
Indicators of Compromise (IoCs)
Hash | File Name and Type | K7 Detection name |
60EE6817513927CF822453A95234DDAC | Mail attachment, VBScript | Trojan ( 0001140e1 ) |
031B11906A9B460CCE8922881663F2A5 | Mail attachment, VBScript | Trojan ( 0001140e1 ) |
C28FBCA3EA7632457767B9D31BB3B462 | Mail attachment, VBScript | Trojan ( 0001140e1 ) |
8BDB30D9F3C697D3F12AEA9DD3D83A60 | senate.m4a, dll | Trojan ( 005682b31 ) |
B0754BBC9E7A8907D94DABD286AA8E30 | thyme.eot, dll | Trojan ( 0056814f1 ) |
URLs Contacted
hxxps[:]//iplogger[.]org/1BBvy7
hxxps[:]//iplogger[.]org/1ys2w7