Deep dive into JS/Vjw0rm
I recently came across an interesting javascript file and decided to do a quick write-up on it. Enjoy!
First I ran the file command on the downloaded .js file to determine what type of file we have.
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.
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.
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/