Script-Based Malware: A New Attacker Trend on Internet Explorer

By , , and

Category: Malware, Unit 42

Tags: , , ,

This conceptual image represents Remote Access Trojans, such as the one examined here as an example of script-based malware.

This post is also available in: 日本語 (Japanese)

Executive Summary

Over the past few months, we have detected sophisticated script-based malware through Internet Explorer (IE) browser exploits that infect Windows Operating System (OS) users. We decided to investigate those scripts to identify their key features to demonstrate that they are attractive for attackers and so could lead to a trend worth paying attention to.

Indeed, with scripting languages, attackers have flexible and accessible tools to easily create sophisticated malware with multiple features and obfuscations. To demonstrate this, we chose two examples of script-based malware used to infect Windows OS users. Those examples were found from two separate sources, but came from the same IE browser exploit of the CVE-2019-0752 vulnerability. The first is a JScript Remote Access Trojan (RAT) that ensures persistence on the target system and then uses encoded network connection to connect to the attacker. After that, the attacker can execute arbitrary commands on the target machine to have potentially full control of it. The second is an AutoIT downloader that uses network connection and script functions to download and execute malware, which could be used to infect targeted systems with malware such as ransomware, spyware and so on.

Finally, to give more details about scripting languages used for script-based malware, we explore possible explanations for the attackers’ choice to use scripts instead of regular executables as the payload in the browser exploit.

Organizations with up-to-date Windows hosts that follow security best practices for secure web browsing have a much lower risk of infection. Palo Alto Networks customers are protected from this threat via IPS signatures. URL Filtering and WildFire both identify related samples and infrastructure as malware.

CVE-2019-0752

CVE-2019-0752 is a Scripting Engine Memory Corruption Vulnerability that was patched in April 2019. It can lead to remote code execution (RCE) on a target machine. In the case we examined, the exploit of the vulnerability was used to execute PowerShell commands to download the two samples presented here. A detailed exploit writeup of the CVE-2019-0752 vulnerability can be found in this Zero Day Initiative Blog Post.

JScript RAT in Our Browser

We observed the c.js JScript RAT downloaded from the assurancetemporaireenligne[.]com domain on April 18. The PowerShell command used by the exploit of the CVE-2019-0752 vulnerability can be found in Figure 1. In this section, we will focus on the analysis of the c.js file. First, we will cover the static analysis of the file so we can have a good overview of the malicious script. Then we will use dynamic analysis to clearly expose the behavior of the script, especially the technique used by the malicious script to ensure persistence on the target machine and to connect to the remote server.

This command shows the set of PowerShell commands used by the exploit of the CVE-2019-0752 vulnerability to download and launch the JScript RAT sample.
Figure 1. Command used to download and launch the JScript RAT sample.

Static Analysis of the c.js File

The c.js script below is an obfuscated script that doesn’t give any hint of its behavior at first glance.

After deobfuscation, we can see in Figure 2 that two packed pieces of JScript code are stored in data1 and data2.

Deobfuscating the script, as shown here, shows that two packed pieces of JScript code, which will run the script-based malware being examined, are stored in data1 and data2.
Figure 2. Deobfuscated c.js script, part one.

Figure 3 shows that the code stored in data1 is put in the HKCU\Software\loaderName register key and the code stored in data2 is encoded using the EncodeScriptFile function and written into the loader.jse file. The path to the loader.jse script is then passed to the HKCU\Software\Microsoft\Windows\CurrentVersion\Run register key and never used again after that (we will give more details about this behavior in the next section). There is also a host variable initialized with the hxxp://seemee[.]ddns[.]net/loader/loader2/www URL. The variable is never used in the script, but it can give a hint of a network activity during the execution. Finally, the loader.jse is run and c.js deletes itself.

This section of deobfuscated code from the script-based malware sample shows where the malicious code is stored.
Figure 3. Deobfuscated c.js script, part two.

Now that we have a good overview of the malicious script code, let's enter into the details of its behavior with dynamic analysis.

Technique to Ensure Persistence

First, the c.js script creates and sets a new value for the registry key HKCU\Software\Microsoft\Windows\CurrentVersion\Run. This value, named loaderName, is set with a path to a certain loader.jse file, as we can see in Figure 4 below.

This image shows how the script creates a new value for the registry key, which is set with a path to a certain loader.jse file.

This image shows how the script creates a new value for the registry key, which is set with a path to a certain loader.jse file.
Figure 4. API Hook on RegSetValueExA.

The Run key causes programs to run each time that a user logs on, and so the loader.jse script, which is not created yet, will run automatically each time the Windows OS boots. The next step of the persistence process of the c.js script is demonstrated in Figure 5, where the script creates the actual loader.jse file. Figure 5 also shows that the loader.jse script is created in the AppData folder. This folder is a hidden folder by default on Windows OS, so it is therefore harder for the target to detect the malicious file present in the system.

This shows that the loader.jse script is created in the AppData folder, a hidden folder by default on Windows OS.

This shows that the loader.jse script is created in the AppData folder, a hidden folder by default on Windows OS.
Figure 5. API Hook on CreateFileW.

After the creation of the loader.jse file, the c.js script uses the open handle of this file, as shown in Figure 6, to put some code in it, as shown in Figure 7.

After the creation of the loader.jse file, the c.js script uses the open handle of this file, as shown here, to put some code in it.

After the creation of the loader.jse file, the c.js script uses the open handle of this file, as shown here, to put some code in it.
Figure 6. Return of the CreateFileW function.

This image shows that the code written in the file is obfuscated. Being able to accomplish heavy obfuscation relatively easy is one reason attackers might choose to use script-based malware.

This image shows that the code written in the file is obfuscated. Being able to accomplish heavy obfuscation relatively easy is one reason attackers might choose to use script-based malware.
Figure 7. API Hook on WriteFile.

Figure 7 also shows that the code written in the file is obfuscated. Thanks to the magic bytes “#@~^” present at the beginning of the file, we can conclude that the loader.jse script has been encoded with Microsoft's script encoding. This is consistent with our static analysis. Then, the encoded file is run via the ShellExecute function (Figure 8) and the c.js file deletes itself.

This shows how the encoded file is run via the ShellExecute function before the c.js file deletes itself.

This shows how the encoded file is run via the ShellExecute function before the c.js file deletes itself.
Figure 8. API Hook on ShellExecuteExW.

To sum up, to ensure persistence on the targeted host, the c.js file tries to not leave traces behind. To do that, it uses the Windows registry key Run, and then it drops an encoded file, loader.jse, in a hidden folder before deleting itself.

Connection to the Remote Server

Before we can analyze the behavior of the loader.jse and the connection to the remote server, we have to go back to the c.js file execution. Indeed, as we saw during our static analysis, this file also creates a registry key named HKCU\Software\loaderName and sets a value data in this key with some packed JScript code. This action can also be seen in Figure 9.

This shows how the c.js file creates a registry key and sets a value in this key with some packed JScript code.

This shows how the c.js file creates a registry key and sets a value in this key with some packed JScript code.
Figure 9. API Hook on RegSetValueExA during c.js file execution.

This step in the c.js execution is very important because when the loader.jse is run, it opens the registry key HKCU\Software\loaderName (Figure 10) and runs the code contained in the data value.

This step shows how the loader.jse file opens the registry key and runs the code contained in the data value.
Figure 10. API Hook on RegOpenKeyExA during loader.jse file execution.

Now, when we take a look at the packed code in the registry key loaderName, we can notice the function(p,a,c,k,e,d) pattern in it (Figure 11). This pattern is an indicator that the Dean Edwards packer was used to obfuscate the code. This packer is outdated now but when it was common, it was widely used by benign scripts. Because of this, it was whitelisted by many kinds of detection technologies.

This shows how we can look at the packed code in the registry key and notice the pattern that indicates that the Dean Edwards packer was used to obfuscate the code.
Figure 11. loaderName registry key with the packed code.

After the code unpacking, Figure 12 shows that a GET request is made to the loader.php page of the hxxp://seemee[.]ddns [.]net domain. An argument r, which is a random number shared between the malicious script and the remote server, is used like a token to encode and decode the data sent and received through the network. Another function with the ability to decode strings is used here to decode the response of the GET request. The connection with the remote server is now set up, and so the malicious script will use the code received in the response to the GET request to connect to the cmd.php page, which is the panel where the attacker can choose commands to execute on the target machine.

This view of the unpacked code shows that a GET request is made to the loader.php page of the malicious domain, as well as other commands executed by the code.
Figure 12. Unpacked code executed by loader.jse.

The script contained in the request’s response is an infinite loop that makes requests to the cmd.php page to retrieve indications of the tasks to execute (Figure 13).

This script contained in the request's response is an infinite loop that makes requests to the cmd.php page to retrieve indications of the tasks to execute.
Figure 13: Launch of the tasks.

The attacker can perform multiple tasks on the target system: execute commands, download files, reboot the Windows OS, terminate the current task and shut down the Windows OS (Figure 14).

This shows commands that can be executed on the target machine, including Download, Exectue, Terminate, Reboot and Shutdown.
Figure 14. Commands that can be executed on the target machine.

AutoIT Downloader

Shortly after the discovery of the JScript RAT, on April 30, 2020, we observed the 2.exe file downloaded from the dark[.]crypterfile[.]com domain using the same vulnerability CVE-2019-0752 (Figure 15). This section will focus on the analysis of the compiled AutoIT script.

This command shows the set of PowerShell commands used by the exploit of the CVE-2019-0752 vulnerability to download and launch the compiled AutoIT sample.
Figure 15. Command used to download and launch the AutoIT downloader sample.

Technical Analysis

When we disassemble the Portable Executable (PE) file, we notice a clue that we are in the presence of a compiled AutoIT script. Indeed, in the code there is a check to see if we are running the PE file with a debugger (Figure 16). If it is the case, a message box pops up with the message,”This is a third party compiled AutoIT script” (Figure 17).

This shows the check in the code to see if we are running the PE file with a debugger. Of particular interest is the line in pink: "call ds:IsDeBuggerPresent"
Figure 16. Debugger check.
This shows the message box that pops up in response to the check: "This is a third-pary compiled AutoIT script."
Figure 17. Message that proves the presence of a compiled AutoIT script.

After the decompilation of the code (Figure 18) using an AutoIT script decompiler, we notice two parts in it. The first part manages the retrieval of the system information. This information is stored in the $asysinfo array. Then there is a check on the sixth element of this array, which corresponds to the number of logical processors. The check verifies whether the number of logical processors is greater than or equal to four, and it brings us to the second part of the script: the malicious files download. Using the InetGet and Run AutoIT functions, the malicious script downloads and executes multiple files on the target system. The last file downloaded is stored in the Current User Startup folder, so this file will be executed each time the user logs in to the Windows OS. This allows the attacker to ensure persistence on the targeted system.

This shows what is present after the decompliation of the code using an AutoIT script decompiler. The result contains two parts: one to manage the retrieval of the system information, and the other causes the download of the script-based malware.
Figure 18. Malicious AutoIT script.

Possible Reasons to Use Scripts

After the analysis of the two samples, we have a good overview of how attackers use scripts to carry out their malicious activities on a target system. In this section, we focus on the reasons that could lead an attacker to choose a script instead of a regular executable file.

First of all, scripting languages such as JScript, VBScript and even AutoIT were originally made to automate and simplify the execution of tasks in the Windows environment, and so these languages have multiple functions to ease the calls to Windows API. Due to the ease of use of these functions, it is pretty simple for an attacker to establish a network connection or to interact with the Windows environment – for example, to execute shell commands. Scripting languages are also often higher level than C or C++, and are easier to learn and more accessible for attackers. With just a few lines of code, attackers can build a working and flexible malicious program with lots of features like network connection, persistence on the targeted system, execution of commands, etc.

Furthermore, attackers can use lots of different techniques and tools to obfuscate their malicious scripts. This can involve very straightforward tools like Microsoft's script encoding, when the attacker is looking primarily for fast results, or it can take the form of very heavy obfuscations that will be challenging for analysts to deobfuscate. This again illustrates the flexibility of scripts.

Finally, malicious scripts allow attackers to create heavy obfuscation if they choose to, meaning that the malicious scripts can evade different kinds of detections and so bypass anti-malware technologies. Once the script-based malware is detected and tagged as malware by defenders, it is easier and faster for attackers to develop new variants to evade current detections if they are using scripting languages.

Conclusion

The samples presented are two examples of how attackers can use scripts to engage in malicious activities on Windows target machines. Those scripts do not reinvent the wheel, but they do offer flexibility and accessibility to attackers. As we saw in our analyses, these advantages allow the attackers to execute commands and so potentially have full control over target machines. For these reasons, attackers may have an incentive to choose this option.

Organizations with up-to-date Windows hosts that follow security best practices for secure web browsing have a much lower risk of infection. Palo Alto Networks customers are further protected from this threat. Indeed, customers are currently covered for the CVE-2019-0752 vulnerability by our IPS signature 55438. URL Filtering and WildFire also protect our customers from the kinds of attacks described here.

IOCs

JScript Sample

SHA256 hashes

c.js:

751D161ED4AFD822925C0373395F014578F166467D20A4B1ADFDB27FD0A83C36

loader.jse:

CCCF25DCD1FA16017B2ACCF4BC501BE583824423FC3A09779116AE07D833F2B2

HTTP URLs

hxxp://assurancetemporaireenligne[.]com/c[.]js

hxxp://seemee[.]ddns[.]net/loader/loader2/www/loader[.]php

hxxp://seemee[.]ddns[.]net/loader/loader2/www/cmd[.]php

AutoIT Downloader Sample

SHA256 hashes

2.exe:

BA60EFE2E939DA16E3D240732FDA286FBD3DB3A0F06CB12D7042C7FAC9B82B86

HTTP URLs

hxxp://dark[.]crypterfile[.]com/2[.]exe

hxxp://dark[.]crypterfile[.]com/1/desktop[.]exe

hxxp://dark[.]crypterfile[.]com/1/99[.]exe

hxxp://dark[.]crypterfile[.]com/1/Calc[.]vbs

hxxp://dark[.]crypterfile[.]com/1/calculator[.]exe

hxxp://dark[.]crypterfile[.]com/1/calc[.]exe