Deep dive into JS/Vjw0rm

shamooo
InfoSec Write-ups
Published in
7 min readMar 28, 2023

--

I recently came across an interesting javascript file and decided to do a quick write-up on it. Enjoy!

file command

First I ran the file command on the downloaded .js file to determine what type of file we have.

js file in sublime

Next, we open it up in sublime and dig into the analysis. For the analysis, I will try to go over the different variable definitions and functions and analyze them piece by piece.

j, g, y arrays

This code defines three arrays, j, g, and y, each containing a list of string values.

The j array contains the names of four Windows Script Host objects: "WScript.Shell", "Scripting.FileSystemObject", "Shell.Application", and "Microsoft.XMLHTTP". These objects are used for performing various tasks such as running programs, reading and writing files, and making HTTP requests.

The g array contains a list of registry keys and values that may be targeted by malware. The keys include "HKCU" (HKEY_CURRENT_USER), "HKLM" (HKEY_LOCAL_MACHINE), "HKCU\vjw0rm", "\Software\Microsoft\Windows\CurrentVersion\Run\", and "HKLM\SOFTWARE\Classes\". The value types include "REG_SZ", which indicates a string value, and "\defaulticon\", which is a subkey for file icons.

The y array contains four string values related to system information. The first value, "winmgmts:", is used to access the Windows Management Instrumentation (WMI) service, which provides information about hardware and software on a computer. The second value, "win32_logicaldisk", is a WMI class that represents a logical disk drive. The third value, "Win32_OperatingSystem", is another WMI class that provides information about the operating system. The fourth value, "AntiVirusProduct", is a WMI class that provides information about antivirus software installed on the system.

variable definitions & start of the do-while loop

This code initializes several variables and attempts to read a registry key using the Windows Script Host RegRead method. If the read fails, the code sets the value of the registry key based on the location of the current script file using RegWrite.

After this initialization, the code calls a function called Ns() and enters a loop. Inside the loop, the code calls a function called Pt() and splits the result using a separator string spl.

The script is able to execute several distinct commands, any of which it can receive from the C&C as a response to a POST request. The code above checks the value of P[0] to determine which action to take.

If P[0] is "Cl", the script is terminated with an exit code of 1 using WScript.Quit(1) — In short, this command kills the script

If P[0] is "Sc", a new file is created in the temp directory using fs.CreateTextFile() and is written with the value of P[1]. The file is then closed and executed using sh.run(s2)— Drops and executes the additional malicious script

If P[0] is "Ex", the code in P[1] is executed using eval() — Executes additional payload

If P[0] is "Rn", the script file is opened using fs.OpenTextFile() with read permissions, its contents are read using ReadAll(), and the contents are modified by replacing the first part of the value of VN with the value of P[1]. The file is then opened with write permissions using fs.OpenTextFile() and modified contents are written back to the file. Finally, the script is executed again using sh.run()

If P[0] is "Up", a new file is created in the temp directory using fs.CreateTextFile() and written with the value of P[1] after replacing all instances of "|U|" with "|V|". The file is then closed and executed using sh.run() -- Updates and executes a new version of the script.

If P[0] is equal to "Un", the code will perform a string replacement on the string stored in P[1] and then evaluate the resulting string as JavaScript code. — This command uninstalls the worm module by removing it from startup (Both registry and folder), removing the infection identifier (HKCU\vjw0rm), deleting the script file, and quitting

If P[0] is equal to "RF", the code will create a text file with the name specified in P[2] in the Windows temporary folder and write the contents of P[1] to it. It will then run the file using sh.run(). — Drops and executes the additional malicious script

The code then catches any errors that occur and sleeps for 7 seconds before repeating the loop.

As we can see the conditionals are enclosed in a do-while loop that will continue indefinitely. Within the loop, the code checks the value of P[0] to determine the type of command to execute.

The next part of the code defines two functions:

Ex(S): This function takes a string argument S representing an environment variable (e.g. "temp"). It uses the sh object to call the ExpandEnvironmentStrings method, which replaces any environment variable references in the string with their corresponding values. The function returns the resulting string.

Pt(C,A): This function takes two arguments: a string C representing a command, and a string A representing additional data to be sent with the command. The function uses the Cr function to create a new XMLHttpRequest object X, sets the open method to send a POST request to a specific URL (in this case, "http://ourvjworm.duckdns[.]org:7974/" plus the value of C), sets a custom request header using the SetRequestHeader method, sends the A data along with the request using the send method, and finally returns the response text from the server.

The nf function checks if the file vbc.exe exists in the Microsoft.NET\Framework\v2.0.50727 directory under the Windows directory using the fs.fileexists method. If the file exists, it sets NT to "YES", otherwise, it sets NT to "NO". It then creates a string s by concatenating various system information, including VN (which was previously defined as the name of the virus), the computer name, username, two system parameters (Ob(2) and Ob(4)), the value of NT, and U (which was previously defined as a unique identifier). It then returns the string s

The Cr function creates a new ActiveXObject using the j[N] value, where j is an array that was defined earlier.

Ob(N) is using the Windows Management Instrumentation (WMI) to retrieve various pieces of information from the local computer.

If N is equal to 2, the function retrieves the caption of the first instance of the Win32_OperatingSystem class.

If N is equal to 4, the function checks if the display name of the antivirus product is not empty, and if not, retrieves the display name of the first instance of the AntiVirusProduct class. If display name is empty, it retrieves the display name of the first instance of the AntiVirusProduct class from a different WMI namespace.

If N is equal to 6, the function retrieves the volume serial number of the first instance of the Win32_logicaldisk class.

The function appears to be returning a single value in each case, based on the information retrieved from WMI.

The Ns function copies a file to the Windows temporary folder, adds a registry entry to make the file run at startup, and creates a scheduled task named Skype to run the file every 30 minutes. It also tries to copy the same file to the startup folder of the current user. The purpose of this function is to maintain persistence and execute some malicious behavior on the victim's machine.

After uploading the javascript file to Virustotal we can see that it is detected by 33/52 vendors.

Summary

The Vjw0rm worm is a JavaScript file with malicious intent that replicates itself on removable storage devices within its reach. During its operation, the worm continuously communicates with its C&C server every 7 seconds to relay details of the compromised system and to receive further directives from its operator(s). To maintain persistence it also copies a file to the Windows temporary folder, adds a registry entry to make the file run at startup, and creates a scheduled task named Skype to run the file every 30 minutes. Once it receives instructions, the worm can implement them on the infected machine.

Happy Hacking!

IOCs

b226987db14d44762e9ebefcda95e144

d86eac68820c39703e52142d3bf450525a9f8d6c

6de643d185952a9903ab06d382c4373e516329536734d90be309004afaa5ea50

http://ourvjworm.duckdns[.]org/Vre

Sources & additional info:

https://bazaar.abuse.ch/download/6de643d185952a9903ab06d382c4373e516329536734d90be309004afaa5ea50/

https://www.f-secure.com/v-descs/worm_js_vjw0rm.shtml

--

--