Wednesday, September 14, 2011

Dropping Executables with Powershell

Scenario: You find yourself in a limited Windows user environment without the ability to transfer binary files over the network for one reason or another. So this rules out using a browser, ftp.exe, mspaint (yes, mspaint can be used to transfer binaries), etc. for file transfer. Suppose this workstation isn't even connected to the Internet. What existing options do you have to drop binaries on the target machine? There's the tried and true debug.exe method of assembling a text file with your payload. This method limits the size of your executable to 64K however since debug.exe is a 16-bit application. Also, Microsoft has since removed debug from recent versions of Windows. Also, Didier Stevens showed how easy it to embed executables in PDFs[1]. You can convert executables to VBscript and embed in Office documents as well. These apps won't necessarily be installed on every machine. Fortunately, Starting with Windows 7 and Server 2008, Powershell is installed by default.

Because Powershell implements the .NET framework, you have an incredible amount of power at your fingertips. I will demonstrate one use case whereby you can create an executable from a text file consisting of a hexadecimal representation of an executable. You can generate this text file using any compiled/scripting language you wish but since we're on the topic, I'll show you how to generate it in Powershell:

The first line reads in each byte of an executable and saves them to a byte array. The second line casts the bytes in the array as strings and writes them to a text file. The resultant text file will look something like this:

You can see that each byte is represented as a decimal (77,90 = "MZ").

Next, once you get the text file onto the target machine (a teensy/USB HID device would be an ideal use case), Powershell can be used to reconstruct the executable from the text file using the following lines:

The first line reads the hex dump into a string variable. The string is then split into a byte array using <space> as a delimiter. Finally, the byte array is written back to a file and thus, the original executable is recreated.

While writing this article, I stumbled upon Dave Kennedy and Josh Kelley's work with Powershell[2] where they stumbled upon this same method of generating executables. In fact several Metasploit payloads use a similar, albeit slicker method of accomplishing this using compression and base64 encoding. Please do check out the great work they've been doing with Powershell.

1) Open mspaint.2) Go to the File->Open dialog box and enter the url of the file you want to download (http://example.com/evil.exe)3) mspaint will give you an error saying it couldn't load the image but it gives you the location in temporary internet files where the file was saved to.

Obviously, yes. The point of the posting was to point out that you can use built-in Windows tools to generate an executable. There's a ton of different ways to get an exe on a machine. This is just one more technique to add to your tool chest.

Came across this post today. The process worked as indicated; however, the file size was almost triple. Received the error that the program was too large to run in memory. Looking into the issue the file increase occurred during the original conversion to text. Attempted again with netcat same local file system for troubleshooting/verification. Same result. We are unsure as to why the file size grew exponentially. Any suggestions?

1) '77 90 144 0' are the first four bytes of your payload, assuming you're dealing with a PE executable, of course.

2) '-encoding byte' is used when you read in the original exe

If you say it's almost three times the size of the original, than you're probably not reading in bytes, rather the individual characters from the array. If that's the case, then the following instruction is crucial:

[Byte[]] $temp = $hex -split ' '

This method described in this post is good but far from ideal. Ideally, you'd write a script to compress the binary, hash it, then base64 encode it. Then do the reverse on the the victim machine.